1/** 2 * Vertex shader texture sampling test. 3 * Brian Paul 4 * 2 Dec 2008 5 */ 6 7#include <assert.h> 8#include <string.h> 9#include <stdio.h> 10#include <stdlib.h> 11#include <math.h> 12#include <GL/glew.h> 13#include "glut_wrap.h" 14#include "shaderutil.h" 15 16 17static const char *VertShaderText = 18 "uniform sampler2D tex1; \n" 19 "void main() \n" 20 "{ \n" 21 " vec4 pos = gl_Vertex; \n" 22 " pos.z = texture2D(tex1, gl_MultiTexCoord0.xy).x - 0.5; \n" 23 " gl_Position = gl_ModelViewProjectionMatrix * pos; \n" 24 " gl_FrontColor = pos; \n" 25 "} \n"; 26 27static const char *FragShaderText = 28 "void main() \n" 29 "{ \n" 30 " gl_FragColor = gl_Color; \n" 31 "} \n"; 32 33 34static GLuint fragShader; 35static GLuint vertShader; 36static GLuint program; 37 38static GLint win = 0; 39static GLboolean Anim = GL_TRUE; 40static GLboolean WireFrame = GL_TRUE; 41static GLfloat xRot = -70.0f, yRot = 0.0f, zRot = 0.0f; 42 43static void 44Idle(void) 45{ 46 zRot = 90 + glutGet(GLUT_ELAPSED_TIME) * 0.05; 47 glutPostRedisplay(); 48} 49 50 51static void 52DrawMesh(void) 53{ 54 GLfloat xmin = -2.0, xmax = 2.0; 55 GLfloat ymin = -2.0, ymax = 2.0; 56 GLuint xdivs = 20, ydivs = 20; 57 GLfloat dx = (xmax - xmin) / xdivs; 58 GLfloat dy = (ymax - ymin) / ydivs; 59 GLfloat ds = 1.0 / xdivs, dt = 1.0 / ydivs; 60 GLfloat x, y, s, t; 61 GLuint i, j; 62 63 y = ymin; 64 t = 0.0; 65 for (i = 0; i < ydivs; i++) { 66 x = xmin; 67 s = 0.0; 68 glBegin(GL_QUAD_STRIP); 69 for (j = 0; j < xdivs; j++) { 70 glTexCoord2f(s, t); 71 glVertex2f(x, y); 72 glTexCoord2f(s, t + dt); 73 glVertex2f(x, y + dy); 74 x += dx; 75 s += ds; 76 } 77 glEnd(); 78 y += dy; 79 t += dt; 80 } 81} 82 83 84static void 85Redisplay(void) 86{ 87 if (WireFrame) 88 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 89 else 90 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 91 92 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 93 94 glPushMatrix(); 95 glRotatef(xRot, 1.0f, 0.0f, 0.0f); 96 glRotatef(yRot, 0.0f, 1.0f, 0.0f); 97 glRotatef(zRot, 0.0f, 0.0f, 1.0f); 98 99 glPushMatrix(); 100 DrawMesh(); 101 glPopMatrix(); 102 103 glPopMatrix(); 104 105 glutSwapBuffers(); 106} 107 108 109static void 110Reshape(int width, int height) 111{ 112 glViewport(0, 0, width, height); 113 glMatrixMode(GL_PROJECTION); 114 glLoadIdentity(); 115 glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); 116 glMatrixMode(GL_MODELVIEW); 117 glLoadIdentity(); 118 glTranslatef(0.0f, 0.0f, -15.0f); 119} 120 121 122static void 123CleanUp(void) 124{ 125 glDeleteShader(fragShader); 126 glDeleteShader(vertShader); 127 glDeleteProgram(program); 128 glutDestroyWindow(win); 129} 130 131 132static void 133Key(unsigned char key, int x, int y) 134{ 135 const GLfloat step = 2.0; 136 (void) x; 137 (void) y; 138 139 switch(key) { 140 case 'a': 141 Anim = !Anim; 142 if (Anim) 143 glutIdleFunc(Idle); 144 else 145 glutIdleFunc(NULL); 146 break; 147 case 'w': 148 WireFrame = !WireFrame; 149 break; 150 case 'z': 151 zRot += step; 152 break; 153 case 'Z': 154 zRot -= step; 155 break; 156 case 27: 157 CleanUp(); 158 exit(0); 159 break; 160 } 161 glutPostRedisplay(); 162} 163 164 165static void 166SpecialKey(int key, int x, int y) 167{ 168 const GLfloat step = 2.0; 169 170 (void) x; 171 (void) y; 172 173 switch(key) { 174 case GLUT_KEY_UP: 175 xRot += step; 176 break; 177 case GLUT_KEY_DOWN: 178 xRot -= step; 179 break; 180 case GLUT_KEY_LEFT: 181 yRot -= step; 182 break; 183 case GLUT_KEY_RIGHT: 184 yRot += step; 185 break; 186 } 187 glutPostRedisplay(); 188} 189 190 191static void 192MakeTexture(void) 193{ 194 const GLuint texWidth = 64, texHeight = 64; 195 GLfloat texImage[64][64]; 196 GLuint i, j; 197 198 /* texture is basically z = f(x, y) */ 199 for (i = 0; i < texHeight; i++) { 200 GLfloat y = 2.0 * (i / (float) (texHeight - 1)) - 1.0; 201 for (j = 0; j < texWidth; j++) { 202 GLfloat x = 2.0 * (j / (float) (texWidth - 1)) - 1.0; 203 GLfloat z = 0.5 + 0.5 * (sin(4.0 * x) * sin(4.0 * y)); 204 texImage[i][j] = z; 205 } 206 } 207 208 glActiveTexture(GL_TEXTURE0); 209 glBindTexture(GL_TEXTURE_2D, 42); 210 glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, texWidth, texHeight, 0, 211 GL_LUMINANCE, GL_FLOAT, texImage); 212 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 213 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 214} 215 216 217static void 218Init(void) 219{ 220 GLint m; 221 222 glGetIntegerv(GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB, &m); 223 if (m < 1) { 224 printf("Error: no vertex shader texture units supported.\n"); 225 exit(1); 226 } 227 228 if (!ShadersSupported()) 229 exit(1); 230 231 vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText); 232 fragShader = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText); 233 program = LinkShaders(vertShader, fragShader); 234 235 glUseProgram(program); 236 237 assert(glGetError() == 0); 238 239 MakeTexture(); 240 241 glClearColor(0.4f, 0.4f, 0.8f, 0.0f); 242 243 glEnable(GL_DEPTH_TEST); 244 245 glColor3f(1, 1, 1); 246} 247 248 249int 250main(int argc, char *argv[]) 251{ 252 glutInit(&argc, argv); 253 glutInitWindowSize(500, 500); 254 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 255 win = glutCreateWindow(argv[0]); 256 glewInit(); 257 glutReshapeFunc(Reshape); 258 glutKeyboardFunc(Key); 259 glutSpecialFunc(SpecialKey); 260 glutDisplayFunc(Redisplay); 261 Init(); 262 if (Anim) 263 glutIdleFunc(Idle); 264 glutMainLoop(); 265 return 0; 266} 267 268