diff options
Diffstat (limited to 'progs/glsl/texaaline.c')
-rw-r--r-- | progs/glsl/texaaline.c | 369 |
1 files changed, 369 insertions, 0 deletions
diff --git a/progs/glsl/texaaline.c b/progs/glsl/texaaline.c new file mode 100644 index 0000000000..7a5ac405bb --- /dev/null +++ b/progs/glsl/texaaline.c @@ -0,0 +1,369 @@ +/** + * AA lines with texture mapped quads + * + * Brian Paul + * 9 Feb 2008 + */ + + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glew.h> +#include <GL/glut.h> + + +static GLint WinWidth = 300, WinHeight = 300; +static GLint win = 0; +static GLfloat Width = 8.; + +/* + * Quad strip for line from v0 to v1: + * + 1 3 5 7 + +---+---------------------+---+ + | | + | *v0 v1* | + | | + +---+---------------------+---+ + 0 2 4 6 + */ +static void +QuadLine(const GLfloat *v0, const GLfloat *v1, GLfloat width) +{ + GLfloat dx = v1[0] - v0[0]; + GLfloat dy = v1[1] - v0[1]; + GLfloat len = sqrt(dx*dx + dy*dy); + float dx0, dx1, dx2, dx3, dx4, dx5, dx6, dx7; + float dy0, dy1, dy2, dy3, dy4, dy5, dy6, dy7; + + dx /= len; + dy /= len; + + width *= 0.5; /* half width */ + dx = dx * (width + 0.0); + dy = dy * (width + 0.0); + + dx0 = -dx+dy; dy0 = -dy-dx; + dx1 = -dx-dy; dy1 = -dy+dx; + + dx2 = 0+dy; dy2 = -dx+0; + dx3 = 0-dy; dy3 = +dx+0; + + dx4 = 0+dy; dy4 = -dx+0; + dx5 = 0-dy; dy5 = +dx+0; + + dx6 = dx+dy; dy6 = dy-dx; + dx7 = dx-dy; dy7 = dy+dx; + + /* + printf("dx, dy = %g, %g\n", dx, dy); + printf(" dx0, dy0: %g, %g\n", dx0, dy0); + printf(" dx1, dy1: %g, %g\n", dx1, dy1); + printf(" dx2, dy2: %g, %g\n", dx2, dy2); + printf(" dx3, dy3: %g, %g\n", dx3, dy3); + */ + + glBegin(GL_QUAD_STRIP); + glTexCoord2f(0, 0); + glVertex2f(v0[0] + dx0, v0[1] + dy0); + glTexCoord2f(0, 1); + glVertex2f(v0[0] + dx1, v0[1] + dy1); + + glTexCoord2f(0.5, 0); + glVertex2f(v0[0] + dx2, v0[1] + dy2); + glTexCoord2f(0.5, 1); + glVertex2f(v0[0] + dx3, v0[1] + dy3); + + glTexCoord2f(0.5, 0); + glVertex2f(v1[0] + dx2, v1[1] + dy2); + glTexCoord2f(0.5, 1); + glVertex2f(v1[0] + dx3, v1[1] + dy3); + + glTexCoord2f(1, 0); + glVertex2f(v1[0] + dx6, v1[1] + dy6); + glTexCoord2f(1, 1); + glVertex2f(v1[0] + dx7, v1[1] + dy7); + glEnd(); +} + + +static float Cos(float a) +{ + return cos(a * M_PI / 180.); +} + +static float Sin(float a) +{ + return sin(a * M_PI / 180.); +} + +static void +Redisplay(void) +{ + float cx = 0.5 * WinWidth, cy = 0.5 * WinHeight; + float len = 0.5 * WinWidth - 20.0; + int i; + + glClear(GL_COLOR_BUFFER_BIT); + + glColor3f(1, 1, 1); + + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + + for (i = 0; i < 360; i+=5) { + float v0[2], v1[2]; + v0[0] = cx + 40 * Cos(i); + v0[1] = cy + 40 * Sin(i); + v1[0] = cx + len * Cos(i); + v1[1] = cy + len * Sin(i); + QuadLine(v0, v1, Width); + } + + { + float v0[2], v1[2], x; + for (x = 0; x < 1.0; x += 0.2) { + v0[0] = cx + x; + v0[1] = cy + x * 40 - 20; + v1[0] = cx + x + 5.0; + v1[1] = cy + x * 40 - 20; + QuadLine(v0, v1, Width); + } + } + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + WinWidth = width; + WinHeight = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, width, 0, height, -1, 1); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void +CleanUp(void) +{ + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case 'w': + Width -= 0.5; + break; + case 'W': + Width += 0.5; + break; + case 27: + CleanUp(); + exit(0); + break; + } +#if 0 + if (Width < 3) + Width = 3; +#endif + printf("Width = %g\n", Width); + glutPostRedisplay(); +} + + +static float +ramp4(GLint i, GLint size) +{ + float d; + if (i < 4 ) { + d = i / 4.0; + } + else if (i >= size - 5) { + d = 1.0 - (i - (size - 5)) / 4.0; + } + else { + d = 1.0; + } + return d; +} + +static float +ramp2(GLint i, GLint size) +{ + float d; + if (i < 2 ) { + d = i / 2.0; + } + else if (i >= size - 3) { + d = 1.0 - (i - (size - 3)) / 2.0; + } + else { + d = 1.0; + } + return d; +} + +static float +ramp1(GLint i, GLint size) +{ + float d; + if (i == 0 || i == size-1) { + d = 0.0; + } + else { + d = 1.0; + } + return d; +} + + +/** + * Make an alpha texture for antialiasing lines. + * Just a linear fall-off ramp for now. + * Should have a number of different textures for different line widths. + * Could try a bell-like-curve.... + */ +static void +MakeTexture(void) +{ +#define SZ 8 + GLfloat tex[SZ][SZ]; /* alpha tex */ + int i, j; + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { +#if 0 + float k = (SZ-1) / 2.0; + float dx = fabs(i - k) / k; + float dy = fabs(j - k) / k; + float d; + + dx = 1.0 - dx; + dy = 1.0 - dy; + d = dx * dy; + +#else + float d = ramp1(i, SZ) * ramp1(j, SZ); + printf("%d, %d: %g\n", i, j, d); +#endif + tex[i][j] = d; + } + } + + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, SZ, SZ, 0, GL_ALPHA, GL_FLOAT, tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +#undef SZ +} + + +static void +MakeMipmap(void) +{ +#define SZ 64 + GLfloat tex[SZ][SZ]; /* alpha tex */ + int level; + + glPixelStorei(GL_UNPACK_ROW_LENGTH, SZ); + for (level = 0; level < 7; level++) { + int sz = 1 << (6 - level); + int i, j; + for (i = 0; i < sz; i++) { + for (j = 0; j < sz; j++) { + if (level == 6) + tex[i][j] = 1.0; + else if (level == 5) + tex[i][j] = 0.5; + else + tex[i][j] = ramp1(i, sz) * ramp1(j, sz); + } + } + + glTexImage2D(GL_TEXTURE_2D, level, GL_ALPHA, + sz, sz, 0, GL_ALPHA, GL_FLOAT, tex); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4); + ////glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 5); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +#undef SZ +} + + +static void +Init(void) +{ + const char *version; + + (void) MakeTexture; + (void) ramp4; + (void) ramp2; + + version = (const char *) glGetString(GL_VERSION); + if (version[0] != '2' || version[1] != '.') { + printf("This program requires OpenGL 2.x, found %s\n", version); + exit(1); + } + + glClearColor(0.3f, 0.3f, 0.3f, 0.0f); + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +#if 0 + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#elif 0 + MakeTexture(); +#else + MakeMipmap(); +#endif +} + + +static void +ParseOptions(int argc, char *argv[]) +{ +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + win = glutCreateWindow(argv[0]); + glewInit(); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Redisplay); + ParseOptions(argc, argv); + Init(); + glutMainLoop(); + return 0; +} |