lfsdash/gauge.c

238 lines
6.5 KiB
C

#include <GL/glfw.h>
#include <FTGL/ftgl.h>
#include <math.h>
#include <stdio.h>
#include "gauge.h"
#include "text.h"
void init_gauges(void)
{
}
void DrawArc(float inner, float outer, float start_angle, float arc_angle, int num_segments)
{
num_segments = 72;
float theta = arc_angle / (float)(num_segments - 1);//theta is now calculated from the arc angle instead, the - 1 bit comes from the fact that the arc is open
float tangetial_factor = tanf(theta);
float radial_factor = cosf(theta);
float xi = inner * sinf(start_angle); //we now start at the start angle
float yi = inner * cosf(start_angle);
float xo = outer * sinf(start_angle); //we now start at the start angle
float yo = outer * cosf(start_angle);
glBegin(GL_TRIANGLE_STRIP);//since the arc is not a closed curve, this is a strip now
int ii;
for(ii = 0; ii < num_segments; ii++)
{
glVertex3f(xi, yi, 0);
glVertex3f(xo, yo, 0);
float txi = -yi;
float tyi = xi;
xi += txi * tangetial_factor;
yi += tyi * tangetial_factor;
xi *= radial_factor;
yi *= radial_factor;
float txo = -yo;
float tyo = xo;
xo += txo * tangetial_factor;
yo += tyo * tangetial_factor;
xo *= radial_factor;
yo *= radial_factor;
}
glEnd();
}
/*
float theta = 2 * 3.1415926 / (float)num_segments;
float c = cosf(theta);//precalculate the sine and cosine
float s = sinf(theta);
float t;
float x = r;//we start at angle = 0
float y = 0;
glBegin(GL_LINE_LOOP);
int ii;
for(ii = 0; ii < num_segments; ii++)
{
glVertex3f(x + cx, y + cy, 0);//output vertex
//apply the rotation matrix
t = x;
x = c * x - s * y;
y = s * t + c * y;
}
glEnd();
}*/
void drawDial(const struct gauge *gauge, float value, int style)
{
float range = gauge->rangemax - gauge->rangemin;
float angle = gauge->anglemax - gauge->anglemin;
float cura = (value - gauge->rangemin) / range * angle + gauge->anglemin;
switch (style)
{
case GT_NONE:
break;
case GT_BAR:
glColor4f(gauge->dial.r, gauge->dial.g, gauge->dial.b, gauge->dial.a);
DrawArc(gauge->majorstart, gauge->majorend, cura, cura - gauge->anglemin, 10);
break;
case GT_LINE2:
glColor4f(gauge->dial.r, gauge->dial.g, gauge->dial.b, gauge->dial.a);
glBegin(GL_LINES);
glVertex3f(0, 0, 0);
glVertex3f(sin(cura), cos(cura), 0);
glEnd();
break;
case GT_LINE:
glColor4f(1.0, 0.0, 0.0, 1.0);
glBegin(GL_LINES);
glVertex3f(sin(cura) * 0.8, cos(cura) * 0.8, 0);
glVertex3f(sin(cura), cos(cura), 0);
glEnd();
break;
default:
case GT_NEEDLE:
glColor4f(gauge->dial.r, gauge->dial.g, gauge->dial.b, gauge->dial.a);
glRotatef(cura * -180.0 / M_PI, 0.0, 0.0, 1.0);
glBegin(GL_TRIANGLE_STRIP);
//glVertex3f(-0.01, -0.04, 0.0);
//glVertex3f(0.01, -0.04, 0.0);
//glVertex3f(-0.02, 0, 0.0);
//glVertex3f(0.02, 0.0, 0.0);
//glVertex3f(-0.005, 1.0, 0.0);
//glVertex3f(0.005, 1.0, 0.0);
glVertex3f(-0.02, 0.2, 0.0);
glVertex3f(0.02, 0.2, 0.0);
glVertex3f(-0.005, 1.0, 0.0);
glVertex3f(0.005, 1.0, 0.0);
//glVertex3f(0.0, 1.0, 0.0);
glEnd();
break;
}
}
void draw_gauge(const struct gauge *gauge, float value, float red, FTGLfont *font, int gaugetype)
{
float range = gauge->rangemax - gauge->rangemin;
float angle = gauge->anglemax - gauge->anglemin;
float major;// = angle / (range / gauge->majorstep + 0.0);
float minor;// = angle / (range / gauge->minorstep + 0.0);
float cura;
float x1, y1, x2, y2;
int ii;
float majorstep = gauge->majorstep;
float minorstep = gauge->minorstep;
while (1) {
major = angle / (range / majorstep + 0.0);
minor = angle / (range / minorstep + 0.0);
if (fabsf(major) < 12 * M_PI / 180.0) {
majorstep *= 2;
minorstep = majorstep / 2;
} else {
break;
}
}
if (value < gauge->rangemin) value = gauge->rangemin;
if (value > gauge->rangemax * 2) value = gauge->rangemax * 2;
glPushMatrix();
glScalef(gauge->radius, gauge->radius, 1.0);
if (red > 0) {
glLineWidth(1.0);
glColor4f(0.8, 0.0, 0.0, 1.0);
cura = (red - gauge->rangemin) / range * angle + gauge->anglemin;
/*
float x1 = sin(cura) * gauge->majorstart;
float y1 = cos(cura) * gauge->majorstart;
float x2 = sin(cura) * gauge->majorend;
float y2 = cos(cura) * gauge->majorend;
glBegin(GL_LINES);
glVertex3f(x1, y1, 0);
glVertex3f(x2, y2, 0);
glEnd();*/
// printf("%f -> %f\n", cura, gauge->anglemax);
DrawArc(gauge->majorstart, gauge->majorend, gauge->anglemax, gauge->anglemax - cura, 10);
}
glLineWidth(gauge->minorwidth);
glColor4f(gauge->minor.r, gauge->minor.g, gauge->minor.b, gauge->minor.a);
// for (cura = gauge->anglemin; cura < gauge->anglemax; cura += minor)
for (ii = 0; ii <= range / minorstep; ii++)
{
if (red > 0 && ii * minorstep >= red) {
glColor4f(1.0, 1.0, 1.0, 1.0);
}
float cura = gauge->anglemin + ii * minor;
x1 = sin(cura) * gauge->minorstart;
y1 = cos(cura) * gauge->minorstart;
x2 = sin(cura) * gauge->minorend;
y2 = cos(cura) * gauge->minorend;
glBegin(GL_LINES);
glVertex3f(x1, y1, 0);
glVertex3f(x2, y2, 0);
glEnd();
}
glLineWidth(gauge->majorwidth);
glColor4f(gauge->major.r, gauge->major.g, gauge->major.b, gauge->major.a);
// for (cura = gauge->anglemin; cura < gauge->anglemax; cura += major)
for (ii = 0; ii <= range / majorstep; ii++)
{
if (red > 0 && ii * majorstep > red) {
glColor4f(1.0, 1.0, 1.0, 1.0);
}
float cura = gauge->anglemin + ii * major;
x1 = sin(cura) * gauge->majorstart;
y1 = cos(cura) * gauge->majorstart;
x2 = sin(cura) * gauge->majorend;
y2 = cos(cura) * gauge->majorend;
glBegin(GL_LINES);
glVertex3f(x1, y1, 0);
glVertex3f(x2, y2, 0);
glEnd();
char text[10];
if (gauge->majorstep > 100) {
snprintf(text, sizeof text, "%d", (int)(ii * majorstep / 1000 + gauge->rangemin));
} else {
if (range == 1) {
snprintf(text, sizeof text, ii == 0 ? "E" : ii == 1 ? "½" : "F");
} else {
snprintf(text, sizeof text, "%d", (int)(ii * majorstep + gauge->rangemin));
}
}
float scale = (gauge->majorend - gauge->majorstart) * 1.5;
float offs = gauge->majorstart - scale;
drawText(text, font, sin(cura) * offs, cos(cura) * offs, scale, scale, TA_CENTRE, TA_CENTRE);
}
drawDial(gauge, value, gaugetype);
glPopMatrix();
}