diff options
Diffstat (limited to 'progs/glsl')
-rw-r--r-- | progs/glsl/.gitignore | 12 | ||||
-rw-r--r-- | progs/glsl/CH06-brick.frag (renamed from progs/glsl/CH06-brick.frag.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/CH06-brick.vert (renamed from progs/glsl/CH06-brick.vert.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/CH11-bumpmap.frag (renamed from progs/glsl/CH11-bumpmap.frag.txt) | 2 | ||||
-rw-r--r-- | progs/glsl/CH11-bumpmap.vert (renamed from progs/glsl/CH11-bumpmap.vert.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/CH11-toyball.frag (renamed from progs/glsl/CH11-toyball.frag.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/CH11-toyball.vert (renamed from progs/glsl/CH11-toyball.vert.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/CH18-mandel.frag (renamed from progs/glsl/CH18-mandel.frag.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/CH18-mandel.vert (renamed from progs/glsl/CH18-mandel.vert.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/Makefile | 159 | ||||
-rw-r--r-- | progs/glsl/bitmap.c | 323 | ||||
-rw-r--r-- | progs/glsl/brick.c | 138 | ||||
-rw-r--r-- | progs/glsl/bump.c | 142 | ||||
-rw-r--r-- | progs/glsl/convolutions.c | 18 | ||||
-rw-r--r-- | progs/glsl/cubemap.frag (renamed from progs/glsl/cubemap.frag.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/deriv.c | 90 | ||||
-rw-r--r-- | progs/glsl/fragcoord.c | 185 | ||||
-rw-r--r-- | progs/glsl/identity.c | 208 | ||||
-rw-r--r-- | progs/glsl/mandelbrot.c | 152 | ||||
-rw-r--r-- | progs/glsl/multinoise.c | 281 | ||||
-rw-r--r-- | progs/glsl/multitex.c | 285 | ||||
-rw-r--r-- | progs/glsl/multitex.frag | 15 | ||||
-rw-r--r-- | progs/glsl/multitex.vert | 10 | ||||
-rw-r--r-- | progs/glsl/noise.c | 103 | ||||
-rw-r--r-- | progs/glsl/pointcoord.c | 205 | ||||
-rw-r--r-- | progs/glsl/points.c | 260 | ||||
-rw-r--r-- | progs/glsl/reflect.vert (renamed from progs/glsl/reflect.vert.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/shadowtex.frag (renamed from progs/glsl/shadowtex.frag.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/simple.vert (renamed from progs/glsl/simple.vert.txt) | 0 | ||||
-rw-r--r-- | progs/glsl/skinning.c | 280 | ||||
-rw-r--r-- | progs/glsl/skinning.frag | 6 | ||||
-rw-r--r-- | progs/glsl/skinning.vert | 24 | ||||
-rw-r--r-- | progs/glsl/texdemo1.c | 163 | ||||
-rw-r--r-- | progs/glsl/toyball.c | 165 | ||||
-rw-r--r-- | progs/glsl/trirast.c | 259 | ||||
-rw-r--r-- | progs/glsl/twoside.c | 294 | ||||
-rw-r--r-- | progs/glsl/vert-tex.c | 279 |
37 files changed, 3199 insertions, 859 deletions
diff --git a/progs/glsl/.gitignore b/progs/glsl/.gitignore index 81ecf5bdd5e..5d954519b24 100644 --- a/progs/glsl/.gitignore +++ b/progs/glsl/.gitignore @@ -1,11 +1,23 @@ +bitmap brick bump convolutions deriv extfuncs.h +fragcoord +identity mandelbrot +multinoise +multitex noise +pointcoord +points readtex.c readtex.h +shaderutil.c +shaderutil.h +skinning texdemo1 toyball +trirast +twoside diff --git a/progs/glsl/CH06-brick.frag.txt b/progs/glsl/CH06-brick.frag index 06ef04e3afb..06ef04e3afb 100644 --- a/progs/glsl/CH06-brick.frag.txt +++ b/progs/glsl/CH06-brick.frag diff --git a/progs/glsl/CH06-brick.vert.txt b/progs/glsl/CH06-brick.vert index e95e6f42f0b..e95e6f42f0b 100644 --- a/progs/glsl/CH06-brick.vert.txt +++ b/progs/glsl/CH06-brick.vert diff --git a/progs/glsl/CH11-bumpmap.frag.txt b/progs/glsl/CH11-bumpmap.frag index 063576f5a3c..e12c5d374cd 100644 --- a/progs/glsl/CH11-bumpmap.frag.txt +++ b/progs/glsl/CH11-bumpmap.frag @@ -24,7 +24,7 @@ void main() float d, f; d = p.x * p.x + p.y * p.y; - f = 1.0 / sqrt(d + 1.0); + f = inversesqrt(d + 1.0); if (d >= BumpSize) { p = vec2(0.0); f = 1.0; } diff --git a/progs/glsl/CH11-bumpmap.vert.txt b/progs/glsl/CH11-bumpmap.vert index d3d19f62ac3..d3d19f62ac3 100644 --- a/progs/glsl/CH11-bumpmap.vert.txt +++ b/progs/glsl/CH11-bumpmap.vert diff --git a/progs/glsl/CH11-toyball.frag.txt b/progs/glsl/CH11-toyball.frag index 90ec1c27fc1..90ec1c27fc1 100644 --- a/progs/glsl/CH11-toyball.frag.txt +++ b/progs/glsl/CH11-toyball.frag diff --git a/progs/glsl/CH11-toyball.vert.txt b/progs/glsl/CH11-toyball.vert index b7da3ac839e..b7da3ac839e 100644 --- a/progs/glsl/CH11-toyball.vert.txt +++ b/progs/glsl/CH11-toyball.vert diff --git a/progs/glsl/CH18-mandel.frag.txt b/progs/glsl/CH18-mandel.frag index a472d812526..a472d812526 100644 --- a/progs/glsl/CH18-mandel.frag.txt +++ b/progs/glsl/CH18-mandel.frag diff --git a/progs/glsl/CH18-mandel.vert.txt b/progs/glsl/CH18-mandel.vert index c4ca66405d3..c4ca66405d3 100644 --- a/progs/glsl/CH18-mandel.vert.txt +++ b/progs/glsl/CH18-mandel.vert diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile index 9c1d3f8126b..71ca0af9412 100644 --- a/progs/glsl/Makefile +++ b/progs/glsl/Makefile @@ -7,15 +7,28 @@ INCDIR = $(TOP)/include LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) +LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS) + PROGS = \ + bitmap \ brick \ bump \ + convolutions \ deriv \ + identity \ + fragcoord \ mandelbrot \ + multinoise \ + multitex \ noise \ - toyball \ + points \ + pointcoord \ + skinning \ texdemo1 \ - convolutions + toyball \ + twoside \ + trirast \ + vert-tex ##### RULES ##### @@ -26,7 +39,7 @@ PROGS = \ # make executable from .c file: .c: $(LIB_DEP) - $(APP_CC) -I$(INCDIR) $(CFLAGS) $< $(APP_LIB_DEPS) -o $@ + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) $< $(LIBS) -o $@ ##### TARGETS ##### @@ -40,6 +53,7 @@ default: $(PROGS) extfuncs.h: $(TOP)/progs/util/extfuncs.h cp $< . + readtex.c: $(TOP)/progs/util/readtex.c cp $< . @@ -49,28 +63,147 @@ readtex.h: $(TOP)/progs/util/readtex.h readtex.o: readtex.c readtex.h $(APP_CC) -c -I$(INCDIR) $(CFLAGS) readtex.c -brick.c: extfuncs.h -bump.c: extfuncs.h +shaderutil.c: $(TOP)/progs/util/shaderutil.c + cp $< . -mandelbrot.c: extfuncs.h +shaderutil.h: $(TOP)/progs/util/shaderutil.h + cp $< . -toyball.c: extfuncs.h +shaderutil.o: shaderutil.c shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) shaderutil.c -texdemo1: texdemo1.o readtex.o - $(APP_CC) -I$(INCDIR) $(CFLAGS) texdemo1.o readtex.o $(APP_LIB_DEPS) -o $@ -texdemo1.o: texdemo1.c readtex.h extfuncs.h - $(APP_CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c -convolutions: convolutions.o readtex.o - $(APP_CC) -I$(INCDIR) $(CFLAGS) convolutions.o readtex.o $(APP_LIB_DEPS) -o $@ +bitmap.o: bitmap.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) bitmap.c + +bitmap: bitmap.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) bitmap.o shaderutil.o $(LIBS) -o $@ + + +brick.o: brick.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) brick.c + +brick: brick.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) brick.o shaderutil.o $(LIBS) -o $@ + + +bump.o: bump.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) bump.c + +bump: bump.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) bump.o shaderutil.o $(LIBS) -o $@ + convolutions.o: convolutions.c readtex.h $(APP_CC) -c -I$(INCDIR) $(CFLAGS) convolutions.c +convolutions: convolutions.o readtex.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) convolutions.o readtex.o $(LIBS) -o $@ + + +deriv.o: deriv.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) deriv.c + +deriv: deriv.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) deriv.o shaderutil.o $(LIBS) -o $@ + + +identity.o: identity.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) identity.c + +identity: identity.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) identity.o shaderutil.o $(LIBS) -o $@ + + +fragcoord.o: fragcoord.c extfuncs.h shaderutil.h + $(CC) -c -I$(INCDIR) $(CFLAGS) fragcoord.c + +fragcoord: fragcoord.o shaderutil.o + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) fragcoord.o shaderutil.o $(LIBS) -o $@ + + +mandelbrot.o: mandelbrot.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) mandelbrot.c + +mandelbrot: mandelbrot.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) mandelbrot.o shaderutil.o $(LIBS) -o $@ + +multitex.o: multitex.c extfuncs.h readtex.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) multitex.c + +multitex: multitex.o readtex.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) multitex.o readtex.o shaderutil.o $(LIBS) -o $@ + + +noise.o: noise.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) noise.c + +noise: noise.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) noise.o shaderutil.o $(LIBS) -o $@ + + +points.o: points.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) points.c + +points: points.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) points.o shaderutil.o $(LIBS) -o $@ + + +pointcoord.o: pointcoord.c readtex.h extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) pointcoord.c + +pointcoord: pointcoord.o readtex.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) pointcoord.o readtex.o shaderutil.o $(LIBS) -o $@ + + +skinning.o: skinning.c readtex.h extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) skinning.c + +skinning: skinning.o readtex.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) skinning.o readtex.o shaderutil.o $(LIBS) -o $@ + + +texdemo1.o: texdemo1.c readtex.h extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c + +texdemo1: texdemo1.o readtex.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) texdemo1.o readtex.o shaderutil.o $(LIBS) -o $@ + + +toyball.o: toyball.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) toyball.c + +toyball: toyball.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) toyball.o shaderutil.o $(LIBS) -o $@ + + +twoside.o: twoside.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) twoside.c + +twoside: twoside.o shaderutil.o + $(APP_CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) twoside.o shaderutil.o $(LIBS) -o $@ + + +trirast.o: trirast.c extfuncs.h shaderutil.h + $(APP_CC) -c -I$(INCDIR) $(CFLAGS) trirast.c + +trirast: trirast.o shaderutil.o + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) trirast.o shaderutil.o $(LIBS) -o $@ + + +vert-tex.o: vert-tex.c extfuncs.h shaderutil.h + $(CC) -c -I$(INCDIR) $(CFLAGS) vert-tex.c + +vert-tex: vert-tex.o shaderutil.o + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) vert-tex.o shaderutil.o $(LIBS) -o $@ + + + clean: -rm -f $(PROGS) -rm -f *.o *~ -rm -f extfuncs.h + -rm -f shaderutil.* diff --git a/progs/glsl/bitmap.c b/progs/glsl/bitmap.c new file mode 100644 index 00000000000..d488ec6cb9f --- /dev/null +++ b/progs/glsl/bitmap.c @@ -0,0 +1,323 @@ +/** + * Implement glRasterPos + glBitmap with textures + shaders. + * Brian Paul + * 14 May 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static GLuint FragShader; +static GLuint VertShader; +static GLuint Program; + +static GLint Win = 0; +static GLint WinWidth = 500, WinHeight = 500; +static GLboolean Anim = GL_TRUE; +static GLboolean Bitmap = GL_FALSE; +static GLfloat Xrot = 20.0f, Yrot = 70.0f; +static GLint uTex, uScale; +static GLuint Textures[2]; + +#define TEX_WIDTH 16 +#define TEX_HEIGHT 8 + + +static void +BitmapText(const char *s) +{ + while (*s) { + glutBitmapCharacter(GLUT_BITMAP_8_BY_13, (int) *s); + s++; + } +} + + +static void +Redisplay(void) +{ + static const GLfloat px[3] = { 1.2, 0, 0}; + static const GLfloat nx[3] = {-1.2, 0, 0}; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(Xrot, 1.0f, 0.0f, 0.0f); + glRotatef(Yrot, 0.0f, 1.0f, 0.0f); + + glEnable(GL_LIGHTING); + + glPushMatrix(); + glScalef(0.5, 0.5, 0.5); + glutSolidDodecahedron(); + glPopMatrix(); + + glDisable(GL_LIGHTING); + + glColor3f(0, 1, 0); + glBegin(GL_LINES); + glVertex3f(-1, 0, 0); + glVertex3f( 1, 0, 0); + glEnd(); + + glColor3f(1, 1, 0); + + if (Bitmap) { + glRasterPos3fv(px); + BitmapText("+X"); + glRasterPos3fv(nx); + BitmapText("-X"); + } + else { + glUseProgram_func(Program); + + /* vertex positions (deltas) depend on texture size and window size */ + if (uScale != -1) { + glUniform2f_func(uScale, + 2.0 * TEX_WIDTH / WinWidth, + 2.0 * TEX_HEIGHT / WinHeight); + } + + /* draw +X */ + glBindTexture(GL_TEXTURE_2D, Textures[0]); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3fv(px); + glTexCoord2f(1, 0); glVertex3fv(px); + glTexCoord2f(1, 1); glVertex3fv(px); + glTexCoord2f(0, 1); glVertex3fv(px); + glEnd(); + + /* draw -X */ + glBindTexture(GL_TEXTURE_2D, Textures[1]); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3fv(nx); + glTexCoord2f(1, 0); glVertex3fv(nx); + glTexCoord2f(1, 1); glVertex3fv(nx); + glTexCoord2f(0, 1); glVertex3fv(nx); + glEnd(); + + glUseProgram_func(0); + } + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Idle(void) +{ + Yrot = glutGet(GLUT_ELAPSED_TIME) * 0.01; + glutPostRedisplay(); +} + + +static void +Reshape(int width, int height) +{ + WinWidth = width; + WinHeight = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -10.0f); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case ' ': + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'b': + Bitmap = !Bitmap; + if (Bitmap) + printf("Using glBitmap\n"); + else + printf("Using billboard texture\n"); + break; + case 27: + glDeleteShader_func(FragShader); + glDeleteShader_func(VertShader); + glDeleteProgram_func(Program); + glutDestroyWindow(Win); + exit(0); + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 0.125f; + switch(key) { + case GLUT_KEY_UP: + Xrot -= step; + break; + case GLUT_KEY_DOWN: + Xrot += step; + break; + case GLUT_KEY_LEFT: + Yrot -= step; + break; + case GLUT_KEY_RIGHT: + Yrot += step; + break; + } + /*printf("Xrot: %f Yrot: %f\n", Xrot, Yrot);*/ + glutPostRedisplay(); +} + + +static void +MakeTexImage(const char *p, GLuint texobj) +{ + GLubyte image[TEX_HEIGHT][TEX_WIDTH]; + GLuint i, j, k; + + for (i = 0; i < TEX_HEIGHT; i++) { + for (j = 0; j < TEX_WIDTH; j++) { + k = i * TEX_WIDTH + j; + if (p[k] == ' ') { + image[i][j] = 0; + } + else { + image[i][j] = 255; + } + } + } + + glBindTexture(GL_TEXTURE_2D, texobj); + glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, TEX_WIDTH, TEX_HEIGHT, 0, + GL_RED, GL_UNSIGNED_BYTE, image); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); +} + + +static void +MakeBitmapTextures(void) +{ + const char *px = + " X X " + " X X X " + " X X X " + " XXXXX X " + " X X X " + " X X X " + " X X " + " X X "; + const char *nx = + " X X " + " X X " + " X X " + " XXXXX X " + " X X " + " X X " + " X X " + " X X "; + glGenTextures(2, Textures); + MakeTexImage(px, Textures[0]); + MakeTexImage(nx, Textures[1]); +} + + +static void +Init(void) +{ + /* Fragment shader: modulate raster color by texture, discard fragments + * with alpha < 1.0 + */ + static const char *fragShaderText = + "uniform sampler2D tex2d; \n" + "void main() {\n" + " vec4 c = texture2D(tex2d, gl_TexCoord[0].xy); \n" + " if (c.w < 1.0) \n" + " discard; \n" + " gl_FragColor = c * gl_Color; \n" + "}\n"; + /* Vertex shader: compute new vertex position based on incoming vertex pos, + * texcoords and special scale factor. + */ + static const char *vertShaderText = + "uniform vec2 scale; \n" + "void main() {\n" + " vec4 p = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + " gl_Position.xy = p.xy + gl_MultiTexCoord0.xy * scale * p.w; \n" + " gl_Position.zw = p.zw; \n" + " gl_TexCoord[0] = gl_MultiTexCoord0; \n" + " gl_FrontColor = gl_Color; \n" + "}\n"; + + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText); + FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText); + Program = LinkShaders(VertShader, FragShader); + + glUseProgram_func(Program); + + uScale = glGetUniformLocation_func(Program, "scale"); + uTex = glGetUniformLocation_func(Program, "tex2d"); + if (uTex != -1) { + glUniform1i_func(uTex, 0); /* tex unit 0 */ + } + + glUseProgram_func(0); + + glClearColor(0.3f, 0.3f, 0.3f, 0.0f); + glEnable(GL_DEPTH_TEST); + glEnable(GL_NORMALIZE); + glEnable(GL_LIGHT0); + + MakeBitmapTextures(); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + if (Anim) + glutIdleFunc(Idle); + Init(); + glutMainLoop(); + return 0; +} + + diff --git a/progs/glsl/brick.c b/progs/glsl/brick.c index 522698b5d43..526ef0e2e36 100644 --- a/progs/glsl/brick.c +++ b/progs/glsl/brick.c @@ -13,33 +13,26 @@ #include <GL/glut.h> #include <GL/glext.h> #include "extfuncs.h" +#include "shaderutil.h" -static char *FragProgFile = "CH06-brick.frag.txt"; -static char *VertProgFile = "CH06-brick.vert.txt"; +static char *FragProgFile = "CH06-brick.frag"; +static char *VertProgFile = "CH06-brick.vert"; /* program/shader objects */ static GLuint fragShader; static GLuint vertShader; static GLuint program; - -struct uniform_info { - const char *name; - GLuint size; - GLint location; - GLfloat value[4]; -}; - static struct uniform_info Uniforms[] = { /* vert */ - { "LightPosition", 3, -1, { 0.1, 0.1, 9.0, 0} }, + { "LightPosition", 3, GL_FLOAT, { 0.1, 0.1, 9.0, 0}, -1 }, /* frag */ - { "BrickColor", 3, -1, { 0.8, 0.2, 0.2, 0 } }, - { "MortarColor", 3, -1, { 0.6, 0.6, 0.6, 0 } }, - { "BrickSize", 2, -1, { 1.0, 0.3, 0, 0 } }, - { "BrickPct", 2, -1, { 0.9, 0.8, 0, 0 } }, - { NULL, 0, 0, { 0, 0, 0, 0 } } + { "BrickColor", 3, GL_FLOAT, { 0.8, 0.2, 0.2, 0 }, -1 }, + { "MortarColor", 3, GL_FLOAT, { 0.6, 0.6, 0.6, 0 }, -1 }, + { "BrickSize", 2, GL_FLOAT, { 1.0, 0.3, 0, 0 }, -1 }, + { "BrickPct", 2, GL_FLOAT, { 0.9, 0.8, 0, 0 }, -1 }, + END_OF_UNIFORMS }; static GLint win = 0; @@ -146,121 +139,20 @@ SpecialKey(int key, int x, int y) static void -LoadAndCompileShader(GLuint shader, const char *text) -{ - GLint stat; - - glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); - - glCompileShader_func(shader); - - glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetShaderInfoLog_func(shader, 1000, &len, log); - fprintf(stderr, "brick: problem compiling shader: %s\n", log); - exit(1); - } - else { - printf("Shader compiled OK\n"); - } -} - - -/** - * Read a shader from a file. - */ -static void -ReadShader(GLuint shader, const char *filename) -{ - const int max = 100*1000; - int n; - char *buffer = (char*) malloc(max); - FILE *f = fopen(filename, "r"); - if (!f) { - fprintf(stderr, "brick: Unable to open shader file %s\n", filename); - exit(1); - } - - n = fread(buffer, 1, max, f); - printf("brick: read %d bytes from shader file %s\n", n, filename); - if (n > 0) { - buffer[n] = 0; - LoadAndCompileShader(shader, buffer); - } - - fclose(f); - free(buffer); -} - - -static void -CheckLink(GLuint prog) -{ - GLint stat; - glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetProgramInfoLog_func(prog, 1000, &len, log); - fprintf(stderr, "Linker error:\n%s\n", log); - } - else { - fprintf(stderr, "Link success!\n"); - } -} - - -static void Init(void) { - const char *version; - GLint i; - - version = (const char *) glGetString(GL_VERSION); - if (version[0] != '2' || version[1] != '.') { - printf("Warning: this program expects OpenGL 2.0\n"); - /*exit(1);*/ - } + if (!ShadersSupported()) + exit(1); GetExtensionFuncs(); - vertShader = glCreateShader_func(GL_VERTEX_SHADER); - ReadShader(vertShader, VertProgFile); - - fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); - ReadShader(fragShader, FragProgFile); + vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile); + fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile); + program = LinkShaders(vertShader, fragShader); - program = glCreateProgram_func(); - glAttachShader_func(program, fragShader); - glAttachShader_func(program, vertShader); - glLinkProgram_func(program); - CheckLink(program); glUseProgram_func(program); - for (i = 0; Uniforms[i].name; i++) { - Uniforms[i].location - = glGetUniformLocation_func(program, Uniforms[i].name); - printf("Uniform %s location: %d\n", Uniforms[i].name, - Uniforms[i].location); - switch (Uniforms[i].size) { - case 1: - glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 2: - glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 3: - glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 4: - glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - default: - abort(); - } - } + InitUniforms(program, Uniforms); assert(glGetError() == 0); diff --git a/progs/glsl/bump.c b/progs/glsl/bump.c index a6846acf7e4..b93ab44b5b9 100644 --- a/progs/glsl/bump.c +++ b/progs/glsl/bump.c @@ -13,10 +13,11 @@ #include <GL/glu.h> #include <GL/glext.h> #include "extfuncs.h" +#include "shaderutil.h" -static char *FragProgFile = "CH11-bumpmap.frag.txt"; -static char *VertProgFile = "CH11-bumpmap.vert.txt"; +static char *FragProgFile = "CH11-bumpmap.frag"; +static char *VertProgFile = "CH11-bumpmap.vert"; /* program/shader objects */ static GLuint fragShader; @@ -24,20 +25,13 @@ static GLuint vertShader; static GLuint program; -struct uniform_info { - const char *name; - GLuint size; - GLint location; - GLfloat value[4]; -}; - static struct uniform_info Uniforms[] = { - { "LightPosition", 3, -1, { 0.57737, 0.57735, 0.57735, 0.0 } }, - { "SurfaceColor", 3, -1, { 0.8, 0.8, 0.2, 0 } }, - { "BumpDensity", 1, -1, { 10.0, 0, 0, 0 } }, - { "BumpSize", 1, -1, { 0.125, 0, 0, 0 } }, - { "SpecularFactor", 1, -1, { 0.5, 0, 0, 0 } }, - { NULL, 0, 0, { 0, 0, 0, 0 } } + { "LightPosition", 3, GL_FLOAT, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 }, + { "SurfaceColor", 3, GL_FLOAT, { 0.8, 0.8, 0.2, 0 }, -1 }, + { "BumpDensity", 1, GL_FLOAT, { 10.0, 0, 0, 0 }, -1 }, + { "BumpSize", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 }, + { "SpecularFactor", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 }, + END_OF_UNIFORMS }; static GLint win = 0; @@ -147,9 +141,6 @@ Redisplay(void) glPopMatrix(); - glFinish(); - glFlush(); - CheckError(__LINE__); glutSwapBuffers(); @@ -232,100 +223,18 @@ SpecialKey(int key, int x, int y) } - -static void -LoadAndCompileShader(GLuint shader, const char *text) -{ - GLint stat; - - glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); - - glCompileShader_func(shader); - - glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetShaderInfoLog_func(shader, 1000, &len, log); - fprintf(stderr, "brick: problem compiling shader: %s\n", log); - exit(1); - } - else { - printf("Shader compiled OK\n"); - } -} - - -/** - * Read a shader from a file. - */ -static void -ReadShader(GLuint shader, const char *filename) -{ - const int max = 100*1000; - int n; - char *buffer = (char*) malloc(max); - FILE *f = fopen(filename, "r"); - if (!f) { - fprintf(stderr, "brick: Unable to open shader file %s\n", filename); - exit(1); - } - - n = fread(buffer, 1, max, f); - printf("brick: read %d bytes from shader file %s\n", n, filename); - if (n > 0) { - buffer[n] = 0; - LoadAndCompileShader(shader, buffer); - } - - fclose(f); - free(buffer); -} - - -static void -CheckLink(GLuint prog) -{ - GLint stat; - glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetProgramInfoLog_func(prog, 1000, &len, log); - fprintf(stderr, "Linker error:\n%s\n", log); - } - else { - fprintf(stderr, "Link success!\n"); - } -} - - static void Init(void) { - const char *version; - GLint i; - - version = (const char *) glGetString(GL_VERSION); - if (version[0] != '2' || version[1] != '.') { - printf("Warning: this program expects OpenGL 2.0\n"); - /*exit(1);*/ - } - printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + if (!ShadersSupported()) + exit(1); GetExtensionFuncs(); - vertShader = glCreateShader_func(GL_VERTEX_SHADER); - ReadShader(vertShader, VertProgFile); - - fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); - ReadShader(fragShader, FragProgFile); + vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile); + fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile); + program = LinkShaders(vertShader, fragShader); - program = glCreateProgram_func(); - glAttachShader_func(program, fragShader); - glAttachShader_func(program, vertShader); - glLinkProgram_func(program); - CheckLink(program); glUseProgram_func(program); assert(glIsProgram_func(program)); @@ -336,28 +245,7 @@ Init(void) CheckError(__LINE__); - for (i = 0; Uniforms[i].name; i++) { - Uniforms[i].location - = glGetUniformLocation_func(program, Uniforms[i].name); - printf("Uniform %s location: %d\n", Uniforms[i].name, - Uniforms[i].location); - switch (Uniforms[i].size) { - case 1: - glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 2: - glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 3: - glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 4: - glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - default: - abort(); - } - } + InitUniforms(program, Uniforms); CheckError(__LINE__); diff --git a/progs/glsl/convolutions.c b/progs/glsl/convolutions.c index 9b9ee532453..ac71c68235e 100644 --- a/progs/glsl/convolutions.c +++ b/progs/glsl/convolutions.c @@ -1,3 +1,10 @@ +/** + * Convolution with GLSL. + * Note: uses GL_ARB_shader_objects, GL_ARB_vertex_shader, GL_ARB_fragment_shader, + * not the OpenGL 2.0 shader API. + * Author: Zack Rusin + */ + #define GL_GLEXT_PROTOTYPES #include "readtex.h" @@ -227,9 +234,11 @@ static void createProgram(const char *vertProgFile, glUseProgram(program); + /* assert(glIsProgram(program)); assert(glIsShader(fragShader)); assert(glIsShader(vertShader)); + */ checkError(__LINE__); {/*texture*/ @@ -316,6 +325,13 @@ static void menuInit() static void init() { + if (!glutExtensionSupported("GL_ARB_shader_objects") || + !glutExtensionSupported("GL_ARB_vertex_shader") || + !glutExtensionSupported("GL_ARB_fragment_shader")) { + fprintf(stderr, "Sorry, this program requires GL_ARB_shader_objects, GL_ARB_vertex_shader, and GL_ARB_fragment_shader\n"); + exit(1); + } + fprintf(stderr, "GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); fprintf(stderr, "GL_VERSION = %s\n", (char *) glGetString(GL_VERSION)); fprintf(stderr, "GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR)); @@ -423,8 +439,6 @@ static void draw() glPopMatrix(); - glFlush(); - glutSwapBuffers(); } diff --git a/progs/glsl/cubemap.frag.txt b/progs/glsl/cubemap.frag index 9c27648aaf9..9c27648aaf9 100644 --- a/progs/glsl/cubemap.frag.txt +++ b/progs/glsl/cubemap.frag diff --git a/progs/glsl/deriv.c b/progs/glsl/deriv.c index 8b652bc1e46..e69f0b82c45 100644 --- a/progs/glsl/deriv.c +++ b/progs/glsl/deriv.c @@ -17,6 +17,7 @@ #include <GL/glut.h> #include <GL/glext.h> #include "extfuncs.h" +#include "shaderutil.h" static char *FragProgFile = NULL; @@ -159,68 +160,6 @@ MakeRect(void) } - -static void -LoadAndCompileShader(GLuint shader, const char *text) -{ - GLint stat; - - glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); - - glCompileShader_func(shader); - - glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetShaderInfoLog_func(shader, 1000, &len, log); - fprintf(stderr, "fslight: problem compiling shader:\n%s\n", log); - exit(1); - } -} - - -/** - * Read a shader from a file. - */ -static void -ReadShader(GLuint shader, const char *filename) -{ - const int max = 100*1000; - int n; - char *buffer = (char*) malloc(max); - FILE *f = fopen(filename, "r"); - if (!f) { - fprintf(stderr, "fslight: Unable to open shader file %s\n", filename); - exit(1); - } - - n = fread(buffer, 1, max, f); - printf("fslight: read %d bytes from shader file %s\n", n, filename); - if (n > 0) { - buffer[n] = 0; - LoadAndCompileShader(shader, buffer); - } - - fclose(f); - free(buffer); -} - - -static void -CheckLink(GLuint prog) -{ - GLint stat; - glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetProgramInfoLog_func(prog, 1000, &len, log); - fprintf(stderr, "Linker error:\n%s\n", log); - } -} - - static void Init(void) { @@ -234,33 +173,16 @@ Init(void) " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" " gl_TexCoord[0] = gl_MultiTexCoord0;\n" "}\n"; - const char *version; - version = (const char *) glGetString(GL_VERSION); - if (version[0] != '2' || version[1] != '.') { - printf("This program requires OpenGL 2.x, found %s\n", version); + if (!ShadersSupported()) exit(1); - } GetExtensionFuncs(); - fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); - if (FragProgFile) - ReadShader(fragShader, FragProgFile); - else - LoadAndCompileShader(fragShader, fragShaderText); - - vertShader = glCreateShader_func(GL_VERTEX_SHADER); - if (VertProgFile) - ReadShader(vertShader, VertProgFile); - else - LoadAndCompileShader(vertShader, vertShaderText); - - program = glCreateProgram_func(); - glAttachShader_func(program, fragShader); - glAttachShader_func(program, vertShader); - glLinkProgram_func(program); - CheckLink(program); + vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText); + fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText); + program = LinkShaders(vertShader, fragShader); + glUseProgram_func(program); /*assert(glGetError() == 0);*/ diff --git a/progs/glsl/fragcoord.c b/progs/glsl/fragcoord.c new file mode 100644 index 00000000000..0b7561f3e47 --- /dev/null +++ b/progs/glsl/fragcoord.c @@ -0,0 +1,185 @@ +/** + * Test GLSL gl_FragCoord fragment program attribute. + * Color the quad's fragments according to their window position. + * + * Brian Paul + * 20 Nov 2008 + */ + + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static GLint WinWidth = 200, WinHeight = 200; +static char *FragProgFile = NULL; +static char *VertProgFile = NULL; +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; +static GLint win = 0; +static GLboolean Anim = GL_TRUE; +static GLfloat PosX = 0.0, PosY = 0.0; + + +static void +Idle(void) +{ + float r = (WinWidth < WinHeight) ? WinWidth : WinHeight; + float a = glutGet(GLUT_ELAPSED_TIME) * 0.001; + r *= 0.25; + PosX = WinWidth / 2 + r * cos(a); + PosY = WinHeight / 2 + r * sin(a); + + glutPostRedisplay(); +} + + +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glPushMatrix(); + glTranslatef(PosX, PosY, 0.0); +#if 0 + glBegin(GL_POLYGON); + glVertex2f(-50, -50); + glVertex2f( 50, -50); + glVertex2f( 50, 50); + glVertex2f(-50, 50); + glEnd(); +#else + glutSolidSphere(50, 20, 10); +#endif + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, width, 0, height, -55, 55); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + WinWidth = width; + WinHeight = height; +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case ' ': + case 'a': + Anim = !Anim; + glutIdleFunc(Anim ? Idle : NULL); + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +Init(void) +{ + static const char *fragShaderText = + "void main() { \n" + " vec4 scale = vec4(.005, 0.005, 0.5, 1.0);\n" + " gl_FragColor = gl_FragCoord * scale; \n" + "}\n"; + static const char *vertShaderText = + "void main() {\n" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + "}\n"; + + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText); + fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText); + program = LinkShaders(vertShader, fragShader); + + glUseProgram_func(program); + + /*assert(glGetError() == 0);*/ + + glClearColor(0.3f, 0.3f, 0.3f, 0.0f); + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Redisplay); + ParseOptions(argc, argv); + Init(); + glutIdleFunc(Anim ? Idle : NULL); + glutMainLoop(); + return 0; +} diff --git a/progs/glsl/identity.c b/progs/glsl/identity.c new file mode 100644 index 00000000000..37579eb3469 --- /dev/null +++ b/progs/glsl/identity.c @@ -0,0 +1,208 @@ +/** + * Test very basic glsl functionality (identity vertex and fragment shaders). + * Brian Paul & Stephane Marchesin + */ + + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static char *FragProgFile = NULL; +static char *VertProgFile = NULL; +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; +static GLint win = 0; +static GLboolean anim = GL_FALSE; +static GLfloat xRot = 0.0f, yRot = 0.0f; +static int w,h; + + +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glBegin(GL_TRIANGLES); + glColor3f(.8,0,0); + glVertex3f(-0.9, -0.9, 0.0); + glColor3f(0,.9,0); + glVertex3f( 0.9, -0.9, 0.0); + glColor3f(0,0,.7); + glVertex3f( 0.0, 0.9, 0.0); + glEnd(); + + glutSwapBuffers(); +} + + +static void +Idle(void) +{ + yRot = glutGet(GLUT_ELAPSED_TIME) * 0.1; + glutPostRedisplay(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + w = width; + h = height; +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case ' ': + case 'a': + anim = !anim; + if (anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 3.0f; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + xRot -= step; + break; + case GLUT_KEY_DOWN: + xRot += step; + break; + case GLUT_KEY_LEFT: + yRot -= step; + break; + case GLUT_KEY_RIGHT: + yRot += step; + break; + } + glutPostRedisplay(); +} + + +static void +Init(void) +{ + static const char *fragShaderText = + "void main() {\n" + " gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n" + "}\n"; + static const char *vertShaderText = + "void main() {\n" + " gl_Position = gl_Vertex;\n" + "}\n"; + + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + if (FragProgFile) + fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile); + else + fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText); + + if (VertProgFile) + vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile); + else + vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText); + + program = LinkShaders(vertShader, fragShader); + + glUseProgram_func(program); + + /*assert(glGetError() == 0);*/ + + glClearColor(0.3f, 0.3f, 0.3f, 0.0f); + glEnable(GL_DEPTH_TEST); + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(200, 200); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + if (anim) + glutIdleFunc(Idle); + ParseOptions(argc, argv); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/glsl/mandelbrot.c b/progs/glsl/mandelbrot.c index 7a2bad6dde3..24e19926655 100644 --- a/progs/glsl/mandelbrot.c +++ b/progs/glsl/mandelbrot.c @@ -13,10 +13,11 @@ #include <GL/glut.h> #include <GL/glext.h> #include "extfuncs.h" +#include "shaderutil.h" -static char *FragProgFile = "CH18-mandel.frag.txt"; -static char *VertProgFile = "CH18-mandel.vert.txt"; +static char *FragProgFile = "CH18-mandel.frag"; +static char *VertProgFile = "CH18-mandel.vert"; /* program/shader objects */ static GLuint fragShader; @@ -24,28 +25,21 @@ static GLuint vertShader; static GLuint program; -struct uniform_info { - const char *name; - GLuint size; - GLint location; - GLfloat value[4]; -}; - static struct uniform_info Uniforms[] = { /* vert */ - { "LightPosition", 3, -1, { 0.1, 0.1, 9.0, 0} }, - { "SpecularContribution", 1, -1, { 0.5, 0, 0, 0 } }, - { "DiffuseContribution", 1, -1, { 0.5, 0, 0, 0 } }, - { "Shininess", 1, -1, { 20.0, 0, 0, 0 } }, + { "LightPosition", 3, GL_FLOAT, { 0.1, 0.1, 9.0, 0}, -1 }, + { "SpecularContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 }, + { "DiffuseContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 }, + { "Shininess", 1, GL_FLOAT, { 20.0, 0, 0, 0 }, -1 }, /* frag */ - { "MaxIterations", 1, -1, { 12, 0, 0, 0 } }, - { "Zoom", 1, -1, { 0.125, 0, 0, 0 } }, - { "Xcenter", 1, -1, { -1.5, 0, 0, 0 } }, - { "Ycenter", 1, -1, { .005, 0, 0, 0 } }, - { "InnerColor", 3, -1, { 1, 0, 0, 0 } }, - { "OuterColor1", 3, -1, { 0, 1, 0, 0 } }, - { "OuterColor2", 3, -1, { 0, 0, 1, 0 } }, - { NULL, 0, 0, { 0, 0, 0, 0 } } + { "MaxIterations", 1, GL_FLOAT, { 12, 0, 0, 0 }, -1 }, + { "Zoom", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 }, + { "Xcenter", 1, GL_FLOAT, { -1.5, 0, 0, 0 }, -1 }, + { "Ycenter", 1, GL_FLOAT, { .005, 0, 0, 0 }, -1 }, + { "InnerColor", 3, GL_FLOAT, { 1, 0, 0, 0 }, -1 }, + { "OuterColor1", 3, GL_FLOAT, { 0, 1, 0, 0 }, -1 }, + { "OuterColor2", 3, GL_FLOAT, { 0, 0, 1, 0 }, -1 }, + END_OF_UNIFORMS }; static GLint win = 0; @@ -80,8 +74,6 @@ Redisplay(void) glPopMatrix(); - glFinish(); - glFlush(); glutSwapBuffers(); } @@ -157,123 +149,21 @@ SpecialKey(int key, int x, int y) } - -static void -LoadAndCompileShader(GLuint shader, const char *text) -{ - GLint stat; - - glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); - - glCompileShader_func(shader); - - glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetShaderInfoLog_func(shader, 1000, &len, log); - fprintf(stderr, "brick: problem compiling shader: %s\n", log); - exit(1); - } - else { - printf("Shader compiled OK\n"); - } -} - - -/** - * Read a shader from a file. - */ -static void -ReadShader(GLuint shader, const char *filename) -{ - const int max = 100*1000; - int n; - char *buffer = (char*) malloc(max); - FILE *f = fopen(filename, "r"); - if (!f) { - fprintf(stderr, "brick: Unable to open shader file %s\n", filename); - exit(1); - } - - n = fread(buffer, 1, max, f); - printf("brick: read %d bytes from shader file %s\n", n, filename); - if (n > 0) { - buffer[n] = 0; - LoadAndCompileShader(shader, buffer); - } - - fclose(f); - free(buffer); -} - - -static void -CheckLink(GLuint prog) -{ - GLint stat; - glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetProgramInfoLog_func(prog, 1000, &len, log); - fprintf(stderr, "Linker error:\n%s\n", log); - } - else { - fprintf(stderr, "Link success!\n"); - } -} - - static void Init(void) { - const char *version; - GLint i; - - version = (const char *) glGetString(GL_VERSION); - if (version[0] != '2' || version[1] != '.') { - printf("Warning: this program expects OpenGL 2.0\n"); - /*exit(1);*/ - } + if (!ShadersSupported()) + exit(1); GetExtensionFuncs(); - vertShader = glCreateShader_func(GL_VERTEX_SHADER); - ReadShader(vertShader, VertProgFile); - - fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); - ReadShader(fragShader, FragProgFile); + vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile); + fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile); + program = LinkShaders(vertShader, fragShader); - program = glCreateProgram_func(); - glAttachShader_func(program, fragShader); - glAttachShader_func(program, vertShader); - glLinkProgram_func(program); - CheckLink(program); glUseProgram_func(program); - for (i = 0; Uniforms[i].name; i++) { - Uniforms[i].location - = glGetUniformLocation_func(program, Uniforms[i].name); - printf("Uniform %s location: %d\n", Uniforms[i].name, - Uniforms[i].location); - switch (Uniforms[i].size) { - case 1: - glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 2: - glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 3: - glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 4: - glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - default: - abort(); - } - } + InitUniforms(program, Uniforms); uZoom = glGetUniformLocation_func(program, "Zoom"); uXcenter = glGetUniformLocation_func(program, "Xcenter"); diff --git a/progs/glsl/multinoise.c b/progs/glsl/multinoise.c new file mode 100644 index 00000000000..2351863aff8 --- /dev/null +++ b/progs/glsl/multinoise.c @@ -0,0 +1,281 @@ +/** + * Another test for noise() functions (noise1 to noise4 tested independently). + * 13 Dec 2008 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" + +static const char *VertShaderText = + "void main() {\n" + " gl_TexCoord[0].xyz = gl_Vertex.xyz;\n" + " gl_TexCoord[0].w = gl_MultiTexCoord1.x;\n" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + "}\n"; + +static const char *FragShaderText[ 4 ] = { + "void main()\n" + "{\n" + " gl_FragColor.rgb = noise3( gl_TexCoord[ 0 ].w ) * 0.5 + 0.5;\n" + " gl_FragColor.a = 1;\n" + "}\n", + "void main()\n" + "{\n" + " gl_FragColor.rgb = noise3( gl_TexCoord[ 0 ].xw ) * 0.5 + 0.5;\n" + " gl_FragColor.a = 1;\n" + "}\n", + "void main()\n" + "{\n" + " gl_FragColor.rgb = noise3( gl_TexCoord[ 0 ].xyw ) * 0.5 + 0.5;\n" + " gl_FragColor.a = 1;\n" + "}\n", + "void main()\n" + "{\n" + " gl_FragColor.rgb = noise3( gl_TexCoord[ 0 ].xyzw ) * 0.5 + 0.5;\n" + " gl_FragColor.a = 1;\n" + "}\n" +}; + +struct uniform_info { + const char *name; + GLuint size; + GLint location; + GLfloat value[4]; +}; + +/* program/shader objects */ +static GLuint fragShader[ 4 ]; +static GLuint vertShader; +static GLuint program[ 4 ]; + +static GLint win = 0; +static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f; +static GLfloat Slice = 0.0; +static GLboolean Anim = GL_FALSE; + + +static void +Idle(void) +{ + Slice += 0.01; + glutPostRedisplay(); +} + + +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMultiTexCoord1f( GL_TEXTURE1, Slice ); + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glRotatef(zRot, 0.0f, 0.0f, 1.0f); + + glutSolidTeapot( 1.0 ); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ + GLint i; + + glDeleteShader_func(vertShader); + for( i = 0; i < 4; i++ ) { + glDeleteShader_func(fragShader[ i ]); + glDeleteProgram_func(program[ i ]); + } + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 0.01; + (void) x; + (void) y; + + switch(key) { + case 'a': + Anim = !Anim; + glutIdleFunc(Anim ? Idle : NULL); + case 's': + Slice -= step; + break; + case 'S': + Slice += step; + break; + case 'z': + zRot -= 1.0; + break; + case 'Z': + zRot += 1.0; + break; + case '1': + case '2': + case '3': + case '4': + glUseProgram_func(program[ key - '1' ]); + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 3.0f; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + xRot -= step; + break; + case GLUT_KEY_DOWN: + xRot += step; + break; + case GLUT_KEY_LEFT: + yRot -= step; + break; + case GLUT_KEY_RIGHT: + yRot += step; + break; + } + glutPostRedisplay(); +} + + + +static void +LoadAndCompileShader(GLuint shader, const char *text) +{ + GLint stat; + + glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); + + glCompileShader_func(shader); + + glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog_func(shader, 1000, &len, log); + fprintf(stderr, "noise: problem compiling shader: %s\n", log); + exit(1); + } + else { + printf("Shader compiled OK\n"); + } +} + + +static void +CheckLink(GLuint prog) +{ + GLint stat; + glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog_func(prog, 1000, &len, log); + fprintf(stderr, "Linker error:\n%s\n", log); + } + else { + fprintf(stderr, "Link success!\n"); + } +} + + +static void +Init(void) +{ + const char *version; + GLint i; + + version = (const char *) glGetString(GL_VERSION); + if (version[0] != '2' || version[1] != '.') { + printf("Warning: this program expects OpenGL 2.0\n"); + /*exit(1);*/ + } + + GetExtensionFuncs(); + + vertShader = glCreateShader_func(GL_VERTEX_SHADER); + LoadAndCompileShader(vertShader, VertShaderText); + + for( i = 0; i < 4; i++ ) { + fragShader[ i ] = glCreateShader_func(GL_FRAGMENT_SHADER); + LoadAndCompileShader(fragShader[ i ], FragShaderText[ i ]); + program[ i ] = glCreateProgram_func(); + glAttachShader_func(program[ i ], fragShader[ i ]); + glAttachShader_func(program[ i ], vertShader); + glLinkProgram_func(program[ i ]); + CheckLink(program[ i ]); + } + + glUseProgram_func(program[ 0 ]); + + assert(glGetError() == 0); + + glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + + glColor3f(1, 0, 0); + + glFrontFace( GL_CW ); + glEnable( GL_CULL_FACE ); + glEnable( GL_DEPTH_TEST ); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(400, 400); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + Init(); + glutMainLoop(); + return 0; +} + diff --git a/progs/glsl/multitex.c b/progs/glsl/multitex.c new file mode 100644 index 00000000000..096d40f64d7 --- /dev/null +++ b/progs/glsl/multitex.c @@ -0,0 +1,285 @@ +/** + * Test multi-texturing with GL shading language. + * + * Copyright (C) 2008 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + + +#include <assert.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "GL/glut.h" +#include "readtex.h" +#include "extfuncs.h" +#include "shaderutil.h" + +static const char *Demo = "multitex"; + +static const char *VertFile = "multitex.vert"; +static const char *FragFile = "multitex.frag"; + +static const char *TexFiles[2] = + { + "../images/tile.rgb", + "../images/tree2.rgba" + }; + + +static GLuint Program; + +static GLfloat Xrot = -90.0, Yrot = .0, Zrot = 0.0; +static GLfloat EyeDist = 10; +static GLboolean Anim = GL_TRUE; + + +/* value[0] = tex unit */ +static struct uniform_info Uniforms[] = { + { "tex1", 1, GL_INT, { 0, 0, 0, 0 }, -1 }, + { "tex2", 1, GL_INT, { 1, 0, 0, 0 }, -1 }, + END_OF_UNIFORMS +}; + + +static void +DrawPolygon(GLfloat size) +{ + glPushMatrix(); + glRotatef(90, 1, 0, 0); + glNormal3f(0, 0, 1); + glBegin(GL_POLYGON); + + glMultiTexCoord2f(GL_TEXTURE0, 0, 0); + glMultiTexCoord2f(GL_TEXTURE1, 0, 0); + glVertex2f(-size, -size); + + glMultiTexCoord2f(GL_TEXTURE0, 2, 0); + glMultiTexCoord2f(GL_TEXTURE1, 1, 0); + glVertex2f( size, -size); + + glMultiTexCoord2f(GL_TEXTURE0, 2, 2); + glMultiTexCoord2f(GL_TEXTURE1, 1, 1); + glVertex2f( size, size); + + glMultiTexCoord2f(GL_TEXTURE0, 0, 2); + glMultiTexCoord2f(GL_TEXTURE1, 0, 1); + glVertex2f(-size, size); + + glEnd(); + glPopMatrix(); +} + + +static void +draw(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); /* modelview matrix */ + glTranslatef(0.0, 0.0, -EyeDist); + glRotatef(Zrot, 0, 0, 1); + glRotatef(Yrot, 0, 1, 0); + glRotatef(Xrot, 1, 0, 0); + + DrawPolygon(3.0); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +idle(void) +{ + GLfloat t = 0.05 * glutGet(GLUT_ELAPSED_TIME); + Yrot = t; + glutPostRedisplay(); +} + + +static void +key(unsigned char k, int x, int y) +{ + (void) x; + (void) y; + switch (k) { + case ' ': + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(idle); + else + glutIdleFunc(NULL); + break; + case 'z': + EyeDist -= 0.5; + if (EyeDist < 3.0) + EyeDist = 3.0; + break; + case 'Z': + EyeDist += 0.5; + if (EyeDist > 90.0) + EyeDist = 90; + break; + case 27: + exit(0); + } + glutPostRedisplay(); +} + + +static void +specialkey(int key, int x, int y) +{ + GLfloat step = 2.0; + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + Xrot += step; + break; + case GLUT_KEY_DOWN: + Xrot -= step; + break; + case GLUT_KEY_LEFT: + Yrot -= step; + break; + case GLUT_KEY_RIGHT: + Yrot += step; + break; + } + glutPostRedisplay(); +} + + +/* new window size or exposure */ +static void +Reshape(int width, int height) +{ + GLfloat ar = (float) width / (float) height; + glViewport(0, 0, (GLint)width, (GLint)height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-2.0*ar, 2.0*ar, -2.0, 2.0, 4.0, 100.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + + +static void +InitTextures(void) +{ + GLenum filter = GL_LINEAR; + int i; + + for (i = 0; i < 2; i++) { + GLint imgWidth, imgHeight; + GLenum imgFormat; + GLubyte *image = NULL; + + image = LoadRGBImage(TexFiles[i], &imgWidth, &imgHeight, &imgFormat); + if (!image) { + printf("Couldn't read %s\n", TexFiles[i]); + exit(0); + } + + glActiveTexture(GL_TEXTURE0 + i); + glBindTexture(GL_TEXTURE_2D, 42 + i); + gluBuild2DMipmaps(GL_TEXTURE_2D, 4, imgWidth, imgHeight, + imgFormat, GL_UNSIGNED_BYTE, image); + free(image); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + } +} + + +static GLuint +CreateProgram(const char *vertProgFile, const char *fragProgFile, + struct uniform_info *uniforms) +{ + GLuint fragShader, vertShader, program; + + vertShader = CompileShaderFile(GL_VERTEX_SHADER, vertProgFile); + fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, fragProgFile); + assert(vertShader); + program = LinkShaders(vertShader, fragShader); + + glUseProgram_func(program); + + InitUniforms(program, uniforms); + + return program; +} + + +static void +InitPrograms(void) +{ + Program = CreateProgram(VertFile, FragFile, Uniforms); +} + + +static void +InitGL(void) +{ + const char *version = (const char *) glGetString(GL_VERSION); + + if (version[0] != '2' || version[1] != '.') { + printf("Warning: this program expects OpenGL 2.0\n"); + /*exit(1);*/ + } + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + GetExtensionFuncs(); + + InitTextures(); + InitPrograms(); + + glEnable(GL_DEPTH_TEST); + + glClearColor(.6, .6, .9, 0); + glColor3f(1.0, 1.0, 1.0); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(500, 400); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow(Demo); + glutReshapeFunc(Reshape); + glutKeyboardFunc(key); + glutSpecialFunc(specialkey); + glutDisplayFunc(draw); + if (Anim) + glutIdleFunc(idle); + InitGL(); + glutMainLoop(); + return 0; +} diff --git a/progs/glsl/multitex.frag b/progs/glsl/multitex.frag new file mode 100644 index 00000000000..a2633ceba75 --- /dev/null +++ b/progs/glsl/multitex.frag @@ -0,0 +1,15 @@ +// Multi-texture fragment shader +// Brian Paul + +// Composite second texture over first. +// We're assuming the 2nd texture has a meaningful alpha channel. + +uniform sampler2D tex1; +uniform sampler2D tex2; + +void main() +{ + vec4 t1 = texture2D(tex1, gl_TexCoord[0].xy); + vec4 t2 = texture2D(tex2, gl_TexCoord[1].xy); + gl_FragColor = mix(t1, t2, t2.w); +} diff --git a/progs/glsl/multitex.vert b/progs/glsl/multitex.vert new file mode 100644 index 00000000000..5518ca1ddd8 --- /dev/null +++ b/progs/glsl/multitex.vert @@ -0,0 +1,10 @@ +// Multi-texture vertex shader +// Brian Paul + + +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[1] = gl_MultiTexCoord1; + gl_Position = ftransform(); +} diff --git a/progs/glsl/noise.c b/progs/glsl/noise.c index a26a8059449..bd8f50036bf 100644 --- a/progs/glsl/noise.c +++ b/progs/glsl/noise.c @@ -12,6 +12,7 @@ #include <GL/glut.h> #include <GL/glext.h> #include "extfuncs.h" +#include "shaderutil.h" static const char *VertShaderText = @@ -29,23 +30,17 @@ static const char *FragShaderText = " vec4 p;\n" " p.xy = gl_TexCoord[0].xy;\n" " p.z = Slice;\n" + " p.w = 0;\n" " vec4 n = noise4(p * scale);\n" " gl_FragColor = n * Scale + Bias;\n" "}\n"; -struct uniform_info { - const char *name; - GLuint size; - GLint location; - GLfloat value[4]; -}; - static struct uniform_info Uniforms[] = { - { "Scale", 4, -1, { 0.5, 0.4, 0.0, 0} }, - { "Bias", 4, -1, { 0.5, 0.3, 0.0, 0} }, - { "Slice", 1, -1, { 0.5, 0, 0, 0} }, - { NULL, 0, 0, { 0, 0, 0, 0 } } + { "Scale", 4, GL_FLOAT, { 0.5, 0.4, 0.0, 0}, -1 }, + { "Bias", 4, GL_FLOAT, { 0.5, 0.3, 0.0, 0}, -1 }, + { "Slice", 1, GL_FLOAT, { 0.5, 0, 0, 0}, -1 }, + END_OF_UNIFORMS }; /* program/shader objects */ @@ -175,94 +170,20 @@ SpecialKey(int key, int x, int y) static void -LoadAndCompileShader(GLuint shader, const char *text) -{ - GLint stat; - - glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); - - glCompileShader_func(shader); - - glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetShaderInfoLog_func(shader, 1000, &len, log); - fprintf(stderr, "brick: problem compiling shader: %s\n", log); - exit(1); - } - else { - printf("Shader compiled OK\n"); - } -} - - -static void -CheckLink(GLuint prog) -{ - GLint stat; - glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetProgramInfoLog_func(prog, 1000, &len, log); - fprintf(stderr, "Linker error:\n%s\n", log); - } - else { - fprintf(stderr, "Link success!\n"); - } -} - - -static void Init(void) { - const char *version; - GLint i; - - version = (const char *) glGetString(GL_VERSION); - if (version[0] != '2' || version[1] != '.') { - printf("Warning: this program expects OpenGL 2.0\n"); - /*exit(1);*/ - } + if (!ShadersSupported()) + exit(1); GetExtensionFuncs(); - vertShader = glCreateShader_func(GL_VERTEX_SHADER); - LoadAndCompileShader(vertShader, VertShaderText); - - fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); - LoadAndCompileShader(fragShader, FragShaderText); + vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText); + fragShader = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText); + program = LinkShaders(vertShader, fragShader); - program = glCreateProgram_func(); - glAttachShader_func(program, fragShader); - glAttachShader_func(program, vertShader); - glLinkProgram_func(program); - CheckLink(program); glUseProgram_func(program); - for (i = 0; Uniforms[i].name; i++) { - Uniforms[i].location - = glGetUniformLocation_func(program, Uniforms[i].name); - printf("Uniform %s location: %d\n", Uniforms[i].name, - Uniforms[i].location); - switch (Uniforms[i].size) { - case 1: - glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 2: - glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 3: - glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 4: - glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - default: - abort(); - } - } + InitUniforms(program, Uniforms); assert(glGetError() == 0); diff --git a/progs/glsl/pointcoord.c b/progs/glsl/pointcoord.c new file mode 100644 index 00000000000..b240077c252 --- /dev/null +++ b/progs/glsl/pointcoord.c @@ -0,0 +1,205 @@ +/** + * Test GLSL 1.20 gl_PointCoord fragment program attribute. + * Brian Paul + * 11 Aug 2007 + */ + + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static GLint WinWidth = 300, WinHeight = 300; +static char *FragProgFile = NULL; +static char *VertProgFile = NULL; +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; +static GLint win = 0; +static GLint tex0; +static GLenum Filter = GL_NEAREST; + + +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + /* draw one point/sprite */ + glPushMatrix(); + glPointSize(60); + glBegin(GL_POINTS); + glVertex2f(WinWidth / 2.0f, WinHeight / 2.0f); + glEnd(); + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, width, 0, height, -1, 1); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + + WinWidth = width; + WinHeight = height; +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + + +static void +MakeTexture(void) +{ +#define SZ 16 + GLubyte image[SZ][SZ][4]; + GLuint i, j; + + for (i = 0; i < SZ; i++) { + for (j = 0; j < SZ; j++) { + if ((i + j) & 1) { + image[i][j][0] = 0; + image[i][j][1] = 0; + image[i][j][2] = 0; + image[i][j][3] = 255; + } + else { + image[i][j][0] = j * 255 / (SZ-1); + image[i][j][1] = i * 255 / (SZ-1); + image[i][j][2] = 0; + image[i][j][3] = 255; + } + } + } + + glActiveTexture(GL_TEXTURE0); /* unit 0 */ + glBindTexture(GL_TEXTURE_2D, 42); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SZ, SZ, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, Filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); +#undef SZ +} + + +static void +Init(void) +{ + static const char *fragShaderText = + "#version 120 \n" + "uniform sampler2D tex0; \n" + "void main() { \n" + " gl_FragColor = texture2D(tex0, gl_PointCoord.xy, 0.0); \n" + "}\n"; + static const char *vertShaderText = + "void main() {\n" + " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + "}\n"; + + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText); + fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText); + program = LinkShaders(vertShader, fragShader); + + glUseProgram_func(program); + + tex0 = glGetUniformLocation_func(program, "tex0"); + printf("Uniforms: tex0: %d\n", tex0); + + glUniform1i_func(tex0, 0); /* tex unit 0 */ + + /*assert(glGetError() == 0);*/ + + glClearColor(0.3f, 0.3f, 0.3f, 0.0f); + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + MakeTexture(); + + glEnable(GL_POINT_SPRITE); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Redisplay); + ParseOptions(argc, argv); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/glsl/points.c b/progs/glsl/points.c new file mode 100644 index 00000000000..392dc4db853 --- /dev/null +++ b/progs/glsl/points.c @@ -0,0 +1,260 @@ +/** + * Implement smooth (AA) points with shaders. + * A simple variation could be used for sprite points. + * Brian Paul + * 29 July 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static GLuint FragShader; +static GLuint VertShader; +static GLuint Program; + +static GLint Win = 0; +static GLint WinWidth = 500, WinHeight = 200; +static GLfloat Xpos = 0.0f, Ypos = 0.0f; +static GLint uViewportInv; +static GLboolean Smooth = GL_TRUE, Blend = GL_TRUE; + + +/** + * Issue vertices for a "shader point". + * The position is duplicated, only texcoords (or other vertex attrib) change. + * The vertex program will compute the "real" quad corners. + */ +static void +PointVertex3f(GLfloat x, GLfloat y, GLfloat z) +{ + glTexCoord2f(-1, -1); + glVertex3f(x, y, z); + + glTexCoord2f( 1, -1); + glVertex3f(x, y, z); + + glTexCoord2f( 1, 1); + glVertex3f(x, y, z); + + glTexCoord2f(-1, 1); + glVertex3f(x, y, z); +} + + +static void +DrawPoints(GLboolean shaderPoints) +{ + int i; + for (i = 0; i < 9; i++) { + GLfloat x = i - 4, y = 0, z = 0; + /* note: can't call glPointSize inside Begin/End :( */ + glPointSize( 2 + i * 5 ); + if (shaderPoints) { + glBegin(GL_QUADS); + PointVertex3f(x, y, z); + glEnd(); + } + else { + glBegin(GL_POINTS); + glVertex3f(x, y, z); + glEnd(); + } + } +} + + +/** + * Top row of points rendered convetionally, + * bottom row rendered with shaders. + */ +static void +Redisplay(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + if (Smooth) + glEnable(GL_POINT_SMOOTH); + else + glDisable(GL_POINT_SMOOTH); + + if (Blend) + glEnable(GL_BLEND); + else + glDisable(GL_BLEND); + + glPushMatrix(); + glTranslatef(Xpos, Ypos, 0); + + /* + * regular points + */ + glPushMatrix(); + glTranslatef(0, 1.2, 0); + glUseProgram_func(0); + DrawPoints(GL_FALSE); + glPopMatrix(); + + /* + * shader points + */ + glPushMatrix(); + glTranslatef(0, -1.2, 0); + glUseProgram_func(Program); + if (uViewportInv != -1) { + glUniform2f_func(uViewportInv, 1.0 / WinWidth, 1.0 / WinHeight); + } + DrawPoints(GL_TRUE); + glPopMatrix(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + WinWidth = width; + WinHeight = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 4.0, 30.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -20.0f); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case 'b': + Blend = !Blend; + break; + case 's': + Smooth = !Smooth; + break; + case 27: + glDeleteShader_func(FragShader); + glDeleteShader_func(VertShader); + glDeleteProgram_func(Program); + glutDestroyWindow(Win); + exit(0); + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 1/100.0; + switch(key) { + case GLUT_KEY_UP: + Ypos += step; + break; + case GLUT_KEY_DOWN: + Ypos -= step; + break; + case GLUT_KEY_LEFT: + Xpos -= step; + break; + case GLUT_KEY_RIGHT: + Xpos += step; + break; + } + glutPostRedisplay(); +} + + +static void +Init(void) +{ + /* Fragment shader: compute distance of fragment from center of point + * (we're using texcoords but another varying could be used). + * if dist > 1, discard (coverage==0) + * if dist < k, coverage = 1 + * else, coverage = func(dist) + * Note: length() uses sqrt() and may be expensive. The distance could + * be squared instead (with adjustments to the threshold (k) test) + */ + static const char *fragShaderText = + "void main() {\n" + " float cover; \n" + " float k = 2.0 / gl_Point.size; \n" + " float d = length(gl_TexCoord[0].xy); \n" + " if (d >= 1.0) \n" + " discard; \n" + " if (d < 1.0 - k) \n" + " cover = 1.0; \n" + " else \n" + " cover = (1.0 - d) * 0.5 * gl_Point.size; \n" + " gl_FragColor.rgb = gl_Color.rgb; \n" + " gl_FragColor.a = cover; \n" + "}\n"; + /* Vertex shader: compute new vertex position based on incoming vertex pos, + * texcoords, point size, and inverse viewport scale factor. + * Note: should compute point size attenuation here too. + */ + static const char *vertShaderText = + "uniform vec2 viewportInv; \n" + "void main() {\n" + " vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex;\n" + " gl_Position.xy = pos.xy + gl_MultiTexCoord0.xy * viewportInv \n" + " * gl_Point.size * pos.w; \n" + " gl_Position.zw = pos.zw; \n" + " gl_TexCoord[0] = gl_MultiTexCoord0; \n" + " gl_FrontColor = gl_Color; \n" + "}\n"; + + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + VertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText); + FragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText); + Program = LinkShaders(VertShader, FragShader); + + glUseProgram_func(Program); + + uViewportInv = glGetUniformLocation_func(Program, "viewportInv"); + + glUseProgram_func(0); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + Win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + Init(); + glutMainLoop(); + return 0; +} + + diff --git a/progs/glsl/reflect.vert.txt b/progs/glsl/reflect.vert index 402be38bf7b..402be38bf7b 100644 --- a/progs/glsl/reflect.vert.txt +++ b/progs/glsl/reflect.vert diff --git a/progs/glsl/shadowtex.frag.txt b/progs/glsl/shadowtex.frag index a6a80da47f2..a6a80da47f2 100644 --- a/progs/glsl/shadowtex.frag.txt +++ b/progs/glsl/shadowtex.frag diff --git a/progs/glsl/simple.vert.txt b/progs/glsl/simple.vert index a0abe0dc0b2..a0abe0dc0b2 100644 --- a/progs/glsl/simple.vert.txt +++ b/progs/glsl/simple.vert diff --git a/progs/glsl/skinning.c b/progs/glsl/skinning.c new file mode 100644 index 00000000000..8a65d0667ce --- /dev/null +++ b/progs/glsl/skinning.c @@ -0,0 +1,280 @@ +/** + * Vertex "skinning" example. + * The idea is there are multiple modeling matrices applied to every + * vertex. Weighting values in [0,1] control the influence of each + * matrix on each vertex. + * + * 4 Nov 2008 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static char *FragProgFile = "skinning.frag"; +static char *VertProgFile = "skinning.vert"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +static GLint win = 0; +static GLboolean Anim = GL_TRUE; +static GLboolean WireFrame = GL_TRUE; +static GLfloat xRot = 0.0f, yRot = 90.0f, zRot = 0.0f; + +#define NUM_MATS 2 + +static GLfloat Matrices[NUM_MATS][16]; +static GLint uMat0, uMat1; +static GLint WeightAttr; + + +static void +Idle(void) +{ + yRot = 90 + glutGet(GLUT_ELAPSED_TIME) * 0.005; + glutPostRedisplay(); +} + + +static void +Cylinder(GLfloat length, GLfloat radius, GLint slices, GLint stacks) +{ + float dw = 1.0 / (stacks - 1); + float dz = length / stacks; + int i, j; + + for (j = 0; j < stacks; j++) { + float w0 = j * dw; + float z0 = j * dz; + + glBegin(GL_TRIANGLE_STRIP); + for (i = 0; i < slices; i++) { + float a = (float) i / (slices - 1) * M_PI * 2.0; + float x = radius * cos(a); + float y = radius * sin(a); + glVertexAttrib1f_func(WeightAttr, w0); + glNormal3f(x, y, 0.0); + glVertex3f(x, y, z0); + + glVertexAttrib1f_func(WeightAttr, w0 + dw); + glNormal3f(x, y, 0.0); + glVertex3f(x, y, z0 + dz); + } + glEnd(); + } +} + + +/** + * Update/animate the two matrices. One rotates, the other scales. + */ +static void +UpdateMatrices(void) +{ + GLfloat t = glutGet(GLUT_ELAPSED_TIME) * 0.0025; + GLfloat scale = 0.5 * (1.1 + sin(0.5 * t)); + GLfloat rot = cos(t) * 90.0; + + glPushMatrix(); + glLoadIdentity(); + glScalef(1.0, scale, 1.0); + glGetFloatv(GL_MODELVIEW_MATRIX, Matrices[0]); + glPopMatrix(); + + glPushMatrix(); + glLoadIdentity(); + glRotatef(rot, 0, 0, 1); + glGetFloatv(GL_MODELVIEW_MATRIX, Matrices[1]); + glPopMatrix(); +} + + +static void +Redisplay(void) +{ + UpdateMatrices(); + + glUniformMatrix4fv_func(uMat0, 1, GL_FALSE, Matrices[0]); + glUniformMatrix4fv_func(uMat1, 1, GL_FALSE, Matrices[1]); + + if (WireFrame) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glRotatef(zRot, 0.0f, 0.0f, 1.0f); + + glPushMatrix(); + glTranslatef(0, 0, -2.5); + Cylinder(5.0, 1.0, 10, 20); + glPopMatrix(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 2.0; + (void) x; + (void) y; + + switch(key) { + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'w': + WireFrame = !WireFrame; + break; + case 'z': + zRot += step; + break; + case 'Z': + zRot -= step; + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 2.0; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + xRot += step; + break; + case GLUT_KEY_DOWN: + xRot -= step; + break; + case GLUT_KEY_LEFT: + yRot -= step; + break; + case GLUT_KEY_RIGHT: + yRot += step; + break; + } + glutPostRedisplay(); +} + + + +static void +Init(void) +{ + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile); + fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile); + program = LinkShaders(vertShader, fragShader); + + glUseProgram_func(program); + + uMat0 = glGetUniformLocation_func(program, "mat0"); + uMat1 = glGetUniformLocation_func(program, "mat1"); + + WeightAttr = glGetAttribLocation_func(program, "weight"); + + assert(glGetError() == 0); + + glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + + glEnable(GL_DEPTH_TEST); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(500, 500); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + ParseOptions(argc, argv); + Init(); + if (Anim) + glutIdleFunc(Idle); + glutMainLoop(); + return 0; +} + diff --git a/progs/glsl/skinning.frag b/progs/glsl/skinning.frag new file mode 100644 index 00000000000..9053755a830 --- /dev/null +++ b/progs/glsl/skinning.frag @@ -0,0 +1,6 @@ +// color pass-through + +void main() +{ + gl_FragColor = gl_Color; +} diff --git a/progs/glsl/skinning.vert b/progs/glsl/skinning.vert new file mode 100644 index 00000000000..28970eee584 --- /dev/null +++ b/progs/glsl/skinning.vert @@ -0,0 +1,24 @@ +// Vertex weighting/blendin shader +// Brian Paul +// 4 Nov 2008 + +uniform mat4 mat0, mat1; +attribute float weight; + +void main() +{ + // simple diffuse shading + // Note that we should really transform the normal vector along with + // the postion below... someday. + vec3 lightVec = vec3(0, 0, 1); + vec3 norm = gl_NormalMatrix * gl_Normal; + float dot = 0.2 + max(0.0, dot(norm, lightVec)); + gl_FrontColor = vec4(dot); + + // compute sum of weighted transformations + vec4 pos0 = mat0 * gl_Vertex; + vec4 pos1 = mat1 * gl_Vertex; + vec4 pos = mix(pos0, pos1, weight); + + gl_Position = gl_ModelViewProjectionMatrix * pos; +} diff --git a/progs/glsl/texdemo1.c b/progs/glsl/texdemo1.c index 3ceae14b96b..96ddca1f32d 100644 --- a/progs/glsl/texdemo1.c +++ b/progs/glsl/texdemo1.c @@ -31,14 +31,15 @@ #include "GL/glut.h" #include "readtex.h" #include "extfuncs.h" +#include "shaderutil.h" static const char *Demo = "texdemo1"; -static const char *ReflectVertFile = "reflect.vert.txt"; -static const char *CubeFragFile = "cubemap.frag.txt"; +static const char *ReflectVertFile = "reflect.vert"; +static const char *CubeFragFile = "cubemap.frag"; -static const char *SimpleVertFile = "simple.vert.txt"; -static const char *SimpleTexFragFile = "shadowtex.frag.txt"; +static const char *SimpleVertFile = "simple.vert"; +static const char *SimpleTexFragFile = "shadowtex.frag"; static const char *GroundImage = "../images/tile.rgb"; @@ -51,39 +52,20 @@ static GLboolean Anim = GL_TRUE; static int win = 0; -struct uniform_info { - const char *name; - GLuint size; - GLint location; - GLenum type; /**< GL_FLOAT or GL_INT */ - GLfloat value[4]; -}; - static struct uniform_info ReflectUniforms[] = { - { "cubeTex", 1, -1, GL_INT, { 0, 0, 0, 0 } }, - { "lightPos", 3, -1, GL_FLOAT, { 10, 10, 20, 0 } }, - { NULL, 0, 0, 0, { 0, 0, 0, 0 } } + { "cubeTex", 1, GL_INT, { 0, 0, 0, 0 }, -1 }, + { "lightPos", 3, GL_FLOAT, { 10, 10, 20, 0 }, -1 }, + END_OF_UNIFORMS }; static struct uniform_info SimpleUniforms[] = { - { "tex2d", 1, -1, GL_INT, { 1, 0, 0, 0 } }, - { "lightPos", 3, -1, GL_FLOAT, { 10, 10, 20, 0 } }, - { NULL, 0, 0, 0, { 0, 0, 0, 0 } } + { "tex2d", 1, GL_INT, { 1, 0, 0, 0 }, -1 }, + { "lightPos", 3, GL_FLOAT, { 10, 10, 20, 0 }, -1 }, + END_OF_UNIFORMS }; static void -CheckError(int line) -{ - GLenum err = glGetError(); - if (err) { - printf("GL Error %s (0x%x) at line %d\n", - gluErrorString(err), (int) err, line); - } -} - - -static void DrawGround(GLfloat size) { glPushMatrix(); @@ -388,132 +370,19 @@ InitTextures(GLboolean useImageFiles) } -static void -LoadAndCompileShader(GLuint shader, const char *text) -{ - GLint stat; - - glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); - - glCompileShader_func(shader); - - glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetShaderInfoLog_func(shader, 1000, &len, log); - fprintf(stderr, "%s: problem compiling shader: %s\n", Demo, log); - exit(1); - } - else { - printf("Shader compiled OK\n"); - } -} - - -/** - * Read a shader from a file. - */ -static void -ReadShader(GLuint shader, const char *filename) -{ - const int max = 100*1000; - int n; - char *buffer = (char*) malloc(max); - FILE *f = fopen(filename, "r"); - if (!f) { - fprintf(stderr, "%s: Unable to open shader file %s\n", Demo, filename); - exit(1); - } - - n = fread(buffer, 1, max, f); - printf("%s: read %d bytes from shader file %s\n", Demo, n, filename); - if (n > 0) { - buffer[n] = 0; - LoadAndCompileShader(shader, buffer); - } - - fclose(f); - free(buffer); -} - - -static void -CheckLink(GLuint prog) -{ - GLint stat; - glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetProgramInfoLog_func(prog, 1000, &len, log); - fprintf(stderr, "Linker error:\n%s\n", log); - } - else { - fprintf(stderr, "Link success!\n"); - } -} - - static GLuint CreateProgram(const char *vertProgFile, const char *fragProgFile, struct uniform_info *uniforms) { - GLuint fragShader = 0, vertShader = 0, program = 0; - GLint i; - - program = glCreateProgram_func(); - if (vertProgFile) { - vertShader = glCreateShader_func(GL_VERTEX_SHADER); - ReadShader(vertShader, vertProgFile); - glAttachShader_func(program, vertShader); - } + GLuint fragShader, vertShader, program; - if (fragProgFile) { - fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); - ReadShader(fragShader, fragProgFile); - glAttachShader_func(program, fragShader); - } - - glLinkProgram_func(program); - CheckLink(program); + vertShader = CompileShaderFile(GL_VERTEX_SHADER, vertProgFile); + fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, fragProgFile); + program = LinkShaders(vertShader, fragShader); glUseProgram_func(program); - assert(glIsProgram_func(program)); - assert(glIsShader_func(fragShader)); - assert(glIsShader_func(vertShader)); - - CheckError(__LINE__); - for (i = 0; uniforms[i].name; i++) { - uniforms[i].location - = glGetUniformLocation_func(program, uniforms[i].name); - printf("Uniform %s location: %d\n", uniforms[i].name, - uniforms[i].location); - - switch (uniforms[i].size) { - case 1: - if (uniforms[i].type == GL_INT) - glUniform1i_func(uniforms[i].location, - (GLint) uniforms[i].value[0]); - else - glUniform1fv_func(uniforms[i].location, 1, uniforms[i].value); - break; - case 2: - glUniform2fv_func(uniforms[i].location, 1, uniforms[i].value); - break; - case 3: - glUniform3fv_func(uniforms[i].location, 1, uniforms[i].value); - break; - case 4: - glUniform4fv_func(uniforms[i].location, 1, uniforms[i].value); - break; - default: - abort(); - } - } - - CheckError(__LINE__); + InitUniforms(program, uniforms); return program; } diff --git a/progs/glsl/toyball.c b/progs/glsl/toyball.c index cef52c04a6c..37ad6bf2914 100644 --- a/progs/glsl/toyball.c +++ b/progs/glsl/toyball.c @@ -13,10 +13,11 @@ #include <GL/glut.h> #include <GL/glext.h> #include "extfuncs.h" +#include "shaderutil.h" -static char *FragProgFile = "CH11-toyball.frag.txt"; -static char *VertProgFile = "CH11-toyball.vert.txt"; +static char *FragProgFile = "CH11-toyball.frag"; +static char *VertProgFile = "CH11-toyball.vert"; /* program/shader objects */ static GLuint fragShader; @@ -24,30 +25,23 @@ static GLuint vertShader; static GLuint program; -struct uniform_info { - const char *name; - GLuint size; - GLint location; - GLfloat value[4]; -}; - static struct uniform_info Uniforms[] = { - { "LightDir", 4, -1, { 0.57737, 0.57735, 0.57735, 0.0 } }, - { "HVector", 4, -1, { 0.32506, 0.32506, 0.88808, 0.0 } }, - { "BallCenter", 4, -1, { 0.0, 0.0, 0.0, 1.0 } }, - { "SpecularColor", 4, -1, { 0.4, 0.4, 0.4, 60.0 } }, - { "Red", 4, -1, { 0.6, 0.0, 0.0, 1.0 } }, - { "Blue", 4, -1, { 0.0, 0.3, 0.6, 1.0 } }, - { "Yellow", 4, -1, { 0.6, 0.5, 0.0, 1.0 } }, - { "HalfSpace0", 4, -1, { 1.0, 0.0, 0.0, 0.2 } }, - { "HalfSpace1", 4, -1, { 0.309016994, 0.951056516, 0.0, 0.2 } }, - { "HalfSpace2", 4, -1, { -0.809016994, 0.587785252, 0.0, 0.2 } }, - { "HalfSpace3", 4, -1, { -0.809016994, -0.587785252, 0.0, 0.2 } }, - { "HalfSpace4", 4, -1, { 0.309116994, -0.951056516, 0.0, 0.2 } }, - { "InOrOutInit", 1, -1, { -3.0, 0, 0, 0 } }, - { "StripeWidth", 1, -1, { 0.3, 0, 0, 0 } }, - { "FWidth", 1, -1, { 0.005, 0, 0, 0 } }, - { NULL, 0, 0, { 0, 0, 0, 0 } } + { "LightDir", 4, GL_FLOAT, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 }, + { "HVector", 4, GL_FLOAT, { 0.32506, 0.32506, 0.88808, 0.0 }, -1 }, + { "BallCenter", 4, GL_FLOAT, { 0.0, 0.0, 0.0, 1.0 }, -1 }, + { "SpecularColor", 4, GL_FLOAT, { 0.4, 0.4, 0.4, 60.0 }, -1 }, + { "Red", 4, GL_FLOAT, { 0.6, 0.0, 0.0, 1.0 }, -1 }, + { "Blue", 4, GL_FLOAT, { 0.0, 0.3, 0.6, 1.0 }, -1 }, + { "Yellow", 4, GL_FLOAT, { 0.6, 0.5, 0.0, 1.0 }, -1 }, + { "HalfSpace0", 4, GL_FLOAT, { 1.0, 0.0, 0.0, 0.2 }, -1 }, + { "HalfSpace1", 4, GL_FLOAT, { 0.309016994, 0.951056516, 0.0, 0.2 }, -1 }, + { "HalfSpace2", 4, GL_FLOAT, { -0.809016994, 0.587785252, 0.0, 0.2 }, -1 }, + { "HalfSpace3", 4, GL_FLOAT, { -0.809016994, -0.587785252, 0.0, 0.2 }, -1 }, + { "HalfSpace4", 4, GL_FLOAT, { 0.309116994, -0.951056516, 0.0, 0.2 }, -1 }, + { "InOrOutInit", 1, GL_FLOAT, { -3.0, 0, 0, 0 }, -1 }, + { "StripeWidth", 1, GL_FLOAT, { 0.3, 0, 0, 0 }, -1 }, + { "FWidth", 1, GL_FLOAT, { 0.005, 0, 0, 0 }, -1 }, + END_OF_UNIFORMS }; static GLint win = 0; @@ -85,8 +79,6 @@ Redisplay(void) glPopMatrix(); - glFinish(); - glFlush(); glutSwapBuffers(); } @@ -172,127 +164,20 @@ SpecialKey(int key, int x, int y) static void -LoadAndCompileShader(GLuint shader, const char *text) -{ - GLint stat; - - glShaderSource_func(shader, 1, (const GLchar **) &text, NULL); - - glCompileShader_func(shader); - - glGetShaderiv_func(shader, GL_COMPILE_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetShaderInfoLog_func(shader, 1000, &len, log); - fprintf(stderr, "brick: problem compiling shader: %s\n", log); - exit(1); - } - else { - printf("Shader compiled OK\n"); - } -} - - -/** - * Read a shader from a file. - */ -static void -ReadShader(GLuint shader, const char *filename) -{ - const int max = 100*1000; - int n; - char *buffer = (char*) malloc(max); - FILE *f = fopen(filename, "r"); - if (!f) { - fprintf(stderr, "brick: Unable to open shader file %s\n", filename); - exit(1); - } - - n = fread(buffer, 1, max, f); - printf("brick: read %d bytes from shader file %s\n", n, filename); - if (n > 0) { - buffer[n] = 0; - LoadAndCompileShader(shader, buffer); - } - - fclose(f); - free(buffer); -} - - -static void -CheckLink(GLuint prog) -{ - GLint stat; - glGetProgramiv_func(prog, GL_LINK_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetProgramInfoLog_func(prog, 1000, &len, log); - fprintf(stderr, "Linker error:\n%s\n", log); - } - else { - fprintf(stderr, "Link success!\n"); - } -} - - -static void Init(void) { - const char *version; - GLint i; - - version = (const char *) glGetString(GL_VERSION); - if (version[0] != '2' || version[1] != '.') { - printf("Warning: this program expects OpenGL 2.0\n"); - /*exit(1);*/ - } - printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + if (!ShadersSupported()) + exit(1); GetExtensionFuncs(); - vertShader = glCreateShader_func(GL_VERTEX_SHADER); - ReadShader(vertShader, VertProgFile); - - fragShader = glCreateShader_func(GL_FRAGMENT_SHADER); - ReadShader(fragShader, FragProgFile); + vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile); + fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile); + program = LinkShaders(vertShader, fragShader); - program = glCreateProgram_func(); - glAttachShader_func(program, fragShader); - glAttachShader_func(program, vertShader); - glLinkProgram_func(program); - CheckLink(program); glUseProgram_func(program); - assert(glIsProgram_func(program)); - assert(glIsShader_func(fragShader)); - assert(glIsShader_func(vertShader)); - - - for (i = 0; Uniforms[i].name; i++) { - Uniforms[i].location - = glGetUniformLocation_func(program, Uniforms[i].name); - printf("Uniform %s location: %d\n", Uniforms[i].name, - Uniforms[i].location); - switch (Uniforms[i].size) { - case 1: - glUniform1fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 2: - glUniform2fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 3: - glUniform3fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - case 4: - glUniform4fv_func(Uniforms[i].location, 1, Uniforms[i].value); - break; - default: - abort(); - } - } + InitUniforms(program, Uniforms); assert(glGetError() == 0); diff --git a/progs/glsl/trirast.c b/progs/glsl/trirast.c new file mode 100644 index 00000000000..89df64fc718 --- /dev/null +++ b/progs/glsl/trirast.c @@ -0,0 +1,259 @@ +/** + * Demonstration of doing triangle rasterization with a fragment program. + * Basic idea: + * 1. Draw screen-aligned quad / bounding box around the triangle verts. + * 2. For each pixel in the quad, determine if pixel is inside/outside + * the triangle edges. + * + * Brian Paul + * 1 Aug 2007 + */ + + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static GLint WinWidth = 300, WinHeight = 300; +static char *FragProgFile = NULL; +static char *VertProgFile = NULL; +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; +static GLint win = 0; +static GLboolean anim = GL_TRUE; +static GLfloat Zrot = 0.0f; +static GLint uv0, uv1, uv2; + + +static const GLfloat TriVerts[3][2] = { + { 50, 50 }, + { 250, 50 }, + { 150, 250 } +}; + + +static void +RotateVerts(GLfloat a, + GLuint n, const GLfloat vertsIn[][2], GLfloat vertsOut[][2]) +{ + GLuint i; + GLfloat cx = WinWidth / 2, cy = WinHeight / 2; + for (i = 0; i < n; i++) { + float x = vertsIn[i][0] - cx; + float y = vertsIn[i][1] - cy; + + vertsOut[i][0] = x * cos(a) + y * sin(a) + cx; + vertsOut[i][1] = -x * sin(a) + y * cos(a) + cy; + } +} + +static void +ComputeBounds(GLuint n, GLfloat vertsIn[][2], + GLfloat *xmin, GLfloat *ymin, + GLfloat *xmax, GLfloat *ymax) +{ + GLuint i; + *xmin = *xmax = vertsIn[0][0]; + *ymin = *ymax = vertsIn[0][1]; + for (i = 1; i < n; i++) { + if (vertsIn[i][0] < *xmin) + *xmin = vertsIn[i][0]; + else if (vertsIn[i][0] > *xmax) + *xmax = vertsIn[i][0]; + if (vertsIn[i][1] < *ymin) + *ymin = vertsIn[i][1]; + else if (vertsIn[i][1] > *ymax) + *ymax = vertsIn[i][1]; + } +} + + +static void +Redisplay(void) +{ + GLfloat v[3][2], xmin, ymin, xmax, ymax; + + RotateVerts(Zrot, 3, TriVerts, v); + ComputeBounds(3, v, &xmin, &ymin, &xmax, &ymax); + + glUniform2fv_func(uv0, 1, v[0]); + glUniform2fv_func(uv1, 1, v[1]); + glUniform2fv_func(uv2, 1, v[2]); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glBegin(GL_POLYGON); + glVertex2f(xmin, ymin); + glVertex2f(xmax, ymin); + glVertex2f(xmax, ymax); + glVertex2f(xmin, ymax); + glEnd(); + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Idle(void) +{ + if (anim) { + Zrot = glutGet(GLUT_ELAPSED_TIME) * 0.0005; + glutPostRedisplay(); + } + else + abort(); +} + + +static void +Reshape(int width, int 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) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case ' ': + case 'a': + anim = !anim; + if (anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'z': + Zrot = 0; + break; + case 's': + Zrot += 0.05; + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +Init(void) +{ + static const char *fragShaderText = + "uniform vec2 v0, v1, v2; \n" + "float crs(const vec2 u, const vec2 v) \n" + "{ \n" + " return u.x * v.y - u.y * v.x; \n" + "} \n" + "\n" + "void main() {\n" + " vec2 p = gl_FragCoord.xy; \n" + " if (crs(v1 - v0, p - v0) >= 0 && \n" + " crs(v2 - v1, p - v1) >= 0 && \n" + " crs(v0 - v2, p - v2) >= 0) \n" + " gl_FragColor = vec4(1.0); \n" + " else \n" + " gl_FragColor = vec4(0.5); \n" + "}\n"; + static const char *vertShaderText = + "void main() {\n" + " gl_Position = ftransform(); \n" + "}\n"; + + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText); + fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText); + program = LinkShaders(vertShader, fragShader); + + glUseProgram_func(program); + + uv0 = glGetUniformLocation_func(program, "v0"); + uv1 = glGetUniformLocation_func(program, "v1"); + uv2 = glGetUniformLocation_func(program, "v2"); + printf("Uniforms: %d %d %d\n", uv0, uv1, uv2); + + /*assert(glGetError() == 0);*/ + + glClearColor(0.3f, 0.3f, 0.3f, 0.0f); + glEnable(GL_DEPTH_TEST); + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Redisplay); + if (anim) + glutIdleFunc(Idle); + ParseOptions(argc, argv); + Init(); + glutMainLoop(); + return 0; +} diff --git a/progs/glsl/twoside.c b/progs/glsl/twoside.c new file mode 100644 index 00000000000..672a00491e6 --- /dev/null +++ b/progs/glsl/twoside.c @@ -0,0 +1,294 @@ +/** + * Test two-sided lighting with shaders. + * Both GL_VERTEX_PROGRAM_TWO_SIDE and gl_FrontFacing can be tested + * (see keys below). + * + * Brian Paul + * 18 Dec 2007 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static GLint WinWidth = 300, WinHeight = 300; +static char *FragProgFile = NULL; +static char *VertProgFile = NULL; +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; +static GLint win = 0; +static GLboolean anim = 0*GL_TRUE; +static GLboolean DetermineInFragProg = GL_TRUE; +static GLfloat Xrot = 30.0f; +static GLint u_fragface; +static GLenum FrontWinding = GL_CCW; +static int prevTime = 0; + + +static const GLfloat Red[4] = {1, 0, 0, 0}; +static const GLfloat Green[4] = {0, 1, 0, 0}; + + +static void +Redisplay(void) +{ + int i; + float radius = 2; + + glFrontFace(FrontWinding); + + if (DetermineInFragProg) { + glUniform1i_func(u_fragface, 1); + glDisable(GL_VERTEX_PROGRAM_TWO_SIDE); + } + else { + glUniform1i_func(u_fragface, 0); + glEnable(GL_VERTEX_PROGRAM_TWO_SIDE); + } + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glPushMatrix(); + glRotatef(Xrot, 1, 0, 0); + + /* Draw a tristrip ring */ + glBegin(GL_TRIANGLE_STRIP); + glColor4fv(Red); + glSecondaryColor3fv_func(Green); + for (i = 0; i < 20; i++) { + float a = i / 19.0 * M_PI * 2.0; + float x = radius * cos(a); + float y = radius * sin(a); + glVertex3f(x, -1, y); + glVertex3f(x, +1, y); + } + glEnd(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Idle(void) +{ + int curTime = glutGet(GLUT_ELAPSED_TIME); + int dt = curTime - prevTime; + + if (prevTime == 0) { + prevTime = curTime; + return; + } + prevTime = curTime; + + Xrot += dt * 0.1; + glutPostRedisplay(); +} + + +static void +Reshape(int width, int height) +{ + float ar = (float) width / height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-ar, ar, -1, 1, 3, 25); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0, 0, -10); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + (void) x; + (void) y; + + switch(key) { + case ' ': + case 'a': + anim = !anim; + if (anim) { + prevTime = glutGet(GLUT_ELAPSED_TIME); + glutIdleFunc(Idle); + } + else + glutIdleFunc(NULL); + break; + case 'f': + printf("Using frag shader gl_FrontFacing\n"); + DetermineInFragProg = GL_TRUE; + break; + case 'v': + printf("Using vert shader Two-sided lighting\n"); + DetermineInFragProg = GL_FALSE; + break; + case 'r': + /* reset */ + Xrot = 30; + anim = 0; + glutIdleFunc(NULL); + break; + case 's': + Xrot += 5; + break; + case 'S': + Xrot -= 5; + break; + case 'w': + if (FrontWinding == GL_CCW) { + FrontWinding = GL_CW; + printf("FrontFace = GL_CW\n"); + } + else { + FrontWinding = GL_CCW; + printf("FrontFace = GL_CCW\n"); + } + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +Init(void) +{ + static const char *fragShaderText = + "uniform bool fragface; \n" + "void main() { \n" +#if 0 + " if (!fragface || gl_FrontFacing) { \n" + " gl_FragColor = gl_Color; \n" + " } \n" + " else { \n" + " gl_FragColor = 0.8 * gl_SecondaryColor; \n" + " } \n" +#else + " bool f = gl_FrontFacing; \n" + " if (f) { \n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 0.0); \n" + " } \n" + " else { \n" + " gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0); \n" + " } \n" + " //float g = float(gl_FrontFacing) * 0.5 + 0.5; \n" + " //gl_FragColor = vec4(g); \n" +#endif + "} \n"; + static const char *vertShaderText = + "uniform bool fragface; \n" + "void main() { \n" + " gl_FrontColor = gl_Color; \n" + " if (fragface) { \n" + " // front/back chosen in frag prog \n" + " gl_FrontSecondaryColor = gl_SecondaryColor; \n" + " } \n" + " else { \n" + " // front/back chosen in prim setup \n" + " gl_BackColor = gl_SecondaryColor; \n" + " } \n" + " gl_Position = ftransform(); \n" + "} \n"; + + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + vertShader = CompileShaderText(GL_VERTEX_SHADER, vertShaderText); + fragShader = CompileShaderText(GL_FRAGMENT_SHADER, fragShaderText); + program = LinkShaders(vertShader, fragShader); + + glUseProgram_func(program); + + u_fragface = glGetUniformLocation_func(program, "fragface"); + printf("Uniforms: %d\n", u_fragface); + + /*assert(glGetError() == 0);*/ + + glClearColor(0.3f, 0.3f, 0.3f, 0.0f); + + printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); + + assert(glIsProgram_func(program)); + assert(glIsShader_func(fragShader)); + assert(glIsShader_func(vertShader)); + + glEnable(GL_DEPTH_TEST); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +static void +Usage(void) +{ + printf("Keys:\n"); + printf(" f - do front/back determination in fragment shader\n"); + printf(" v - do front/back determination in vertex shader\n"); + printf(" r - reset, show front\n"); + printf(" a - toggle animation\n"); + printf(" s - step rotation\n"); + printf(" w - toggle CW, CCW front-face winding\n"); + printf("NOTE: red = front face, green = back face.\n"); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowPosition( 0, 0); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutDisplayFunc(Redisplay); + if (anim) + glutIdleFunc(Idle); + ParseOptions(argc, argv); + Init(); + Usage(); + glutMainLoop(); + return 0; +} diff --git a/progs/glsl/vert-tex.c b/progs/glsl/vert-tex.c new file mode 100644 index 00000000000..9d00a610540 --- /dev/null +++ b/progs/glsl/vert-tex.c @@ -0,0 +1,279 @@ +/** + * Vertex shader texture sampling test. + * Brian Paul + * 2 Dec 2008 + */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/gl.h> +#include <GL/glut.h> +#include <GL/glext.h> +#include "extfuncs.h" +#include "shaderutil.h" + + +static const char *VertShaderText = + "uniform sampler2D tex1; \n" + "void main() \n" + "{ \n" + " vec4 pos = gl_Vertex; \n" + " pos.z = texture2D(tex1, gl_MultiTexCoord0.xy).x - 0.5; \n" + " gl_Position = gl_ModelViewProjectionMatrix * pos; \n" + " gl_FrontColor = pos; \n" + "} \n"; + +static const char *FragShaderText = + "void main() \n" + "{ \n" + " gl_FragColor = gl_Color; \n" + "} \n"; + + +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + +static GLint win = 0; +static GLboolean Anim = GL_TRUE; +static GLboolean WireFrame = GL_TRUE; +static GLfloat xRot = -70.0f, yRot = 0.0f, zRot = 0.0f; + + +/* value[0] = tex unit */ +static struct uniform_info Uniforms[] = { + { "tex1", 1, GL_INT, { 0, 0, 0, 0 }, -1 }, + END_OF_UNIFORMS +}; + + + +static void +Idle(void) +{ + zRot = 90 + glutGet(GLUT_ELAPSED_TIME) * 0.05; + glutPostRedisplay(); +} + + +static void +DrawMesh(void) +{ + GLfloat xmin = -2.0, xmax = 2.0; + GLfloat ymin = -2.0, ymax = 2.0; + GLuint xdivs = 20, ydivs = 20; + GLfloat dx = (xmax - xmin) / xdivs; + GLfloat dy = (ymax - ymin) / ydivs; + GLfloat ds = 1.0 / xdivs, dt = 1.0 / ydivs; + GLfloat x, y, s, t; + GLuint i, j; + + y = ymin; + t = 0.0; + for (i = 0; i < ydivs; i++) { + x = xmin; + s = 0.0; + glBegin(GL_QUAD_STRIP); + for (j = 0; j < xdivs; j++) { + glTexCoord2f(s, t); + glVertex2f(x, y); + glTexCoord2f(s, t + dt); + glVertex2f(x, y + dy); + x += dx; + s += ds; + } + glEnd(); + y += dy; + t += dt; + } +} + + +static void +Redisplay(void) +{ + if (WireFrame) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glRotatef(zRot, 0.0f, 0.0f, 1.0f); + + glPushMatrix(); + DrawMesh(); + glPopMatrix(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 2.0; + (void) x; + (void) y; + + switch(key) { + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'w': + WireFrame = !WireFrame; + break; + case 'z': + zRot += step; + break; + case 'Z': + zRot -= step; + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 2.0; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + xRot += step; + break; + case GLUT_KEY_DOWN: + xRot -= step; + break; + case GLUT_KEY_LEFT: + yRot -= step; + break; + case GLUT_KEY_RIGHT: + yRot += step; + break; + } + glutPostRedisplay(); +} + + +static void +MakeTexture(void) +{ + const GLuint texWidth = 64, texHeight = 64; + GLfloat texImage[64][64]; + GLuint i, j; + + /* texture is basically z = f(x, y) */ + for (i = 0; i < texHeight; i++) { + GLfloat y = 2.0 * (i / (float) (texHeight - 1)) - 1.0; + for (j = 0; j < texWidth; j++) { + GLfloat x = 2.0 * (j / (float) (texWidth - 1)) - 1.0; + GLfloat z = 0.5 + 0.5 * (sin(4.0 * x) * sin(4.0 * y)); + texImage[i][j] = z; + } + } + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 42); + glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, texWidth, texHeight, 0, + GL_LUMINANCE, GL_FLOAT, texImage); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +} + + +static void +Init(void) +{ + GLint m; + + glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &m); + if (m < 1) { + printf("Error: no vertex shader texture units supported.\n"); + exit(1); + } + + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText); + fragShader = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText); + program = LinkShaders(vertShader, fragShader); + + glUseProgram_func(program); + + assert(glGetError() == 0); + + MakeTexture(); + + glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + + glEnable(GL_DEPTH_TEST); + + glColor3f(1, 1, 1); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(500, 500); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + Init(); + if (Anim) + glutIdleFunc(Idle); + glutMainLoop(); + return 0; +} + |