shader-interp.c revision 32001f49
1/** 2 * Test conversion of a perspective-interpolated value to be a linearly 3 * interpolated value. 4 * Brian Paul 5 * 22 March 2011 6 */ 7 8 9#include <assert.h> 10#include <string.h> 11#include <stdio.h> 12#include <stdlib.h> 13#include <math.h> 14#include <GL/glew.h> 15#include "glut_wrap.h" 16#include "shaderutil.h" 17 18 19static GLuint VertShader1, VertShader2; 20static GLuint FragShader1, FragShader2; 21static GLuint Program1, Program2; 22static GLint Win = 0; 23static int Width = 600, Height = 300; 24 25 26static void 27Redisplay(void) 28{ 29 GLuint i; 30 31 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 32 33 /* draw left and right perspective projected quads */ 34 for (i = 0; i < 2; i++) { 35 glPushMatrix(); 36 37 if (i == 0) { 38 glUseProgram(Program1); 39 glViewport(0, 0, 300, 300); 40 } 41 else { 42 glUseProgram(Program2); 43 glViewport(300, 0, 300, 300); 44 } 45 46 glScalef(0.9, 0.9, 1.0); 47 48 glBegin(GL_POLYGON); 49 glTexCoord2f(0, 0); glVertex3f(-1, -1, 0); 50 glTexCoord2f(1, 0); glVertex3f( 1, -1, 0); 51 glTexCoord2f(1, 1); glVertex3f( 1, 1, -12); 52 glTexCoord2f(0, 1); glVertex3f(-1, 1, -12); 53 glEnd(); 54 55 glPopMatrix(); 56 } 57 58 /* draw grayscale quad in middle */ 59 glUseProgram(0); 60 glViewport(0, 0, Width, Height); 61 glPushMatrix(); 62 glTranslatef(0.0, -0.38, 0); 63 glScalef(0.05, 0.52, 1.0); 64 glBegin(GL_POLYGON); 65 glColor3f(0, 0, 0); glVertex2f(-1, -1); 66 glColor3f(0, 0, 0); glVertex2f( 1, -1); 67 glColor3f(1, 1, 1); glVertex2f( 1, 1); 68 glColor3f(1, 1, 1); glVertex2f(-1, 1); 69 glEnd(); 70 glPopMatrix(); 71 72 if (0) { 73 GLfloat buf1[300*4], buf2[300*4]; 74 GLuint i; 75 glReadPixels(Width * 1 / 4, 0, 1, Height, GL_RGBA, GL_FLOAT, buf1); 76 glReadPixels(Width * 3 / 4, 0, 1, Height, GL_RGBA, GL_FLOAT, buf2); 77 for (i = 1; i < Height; i++) { 78 printf("row %d: %f (delta %f) %f (delta %f)\n", 79 i, 80 buf1[i*4], buf1[i*4] - buf1[i*4-4], 81 buf2[i*4], buf2[i*4] - buf2[i*4-4]); 82 } 83 } 84 85 glutSwapBuffers(); 86} 87 88 89static void 90Reshape(int width, int height) 91{ 92 glViewport(0, 0, width, height); 93 glMatrixMode(GL_PROJECTION); 94 glLoadIdentity(); 95 glFrustum(-1, 1, -1, 1, 2, 200); 96 glMatrixMode(GL_MODELVIEW); 97 glLoadIdentity(); 98 glTranslatef(0, 0, -2); 99 100 Width = width; 101 Height = height; 102} 103 104 105static void 106CleanUp(void) 107{ 108 glDeleteShader(FragShader1); 109 glDeleteShader(FragShader2); 110 glDeleteShader(VertShader1); 111 glDeleteShader(VertShader2); 112 glDeleteProgram(Program1); 113 glDeleteProgram(Program2); 114 glutDestroyWindow(Win); 115} 116 117 118static void 119Key(unsigned char key, int x, int y) 120{ 121 (void) x; 122 (void) y; 123 124 switch(key) { 125 case 27: 126 CleanUp(); 127 exit(0); 128 break; 129 } 130 glutPostRedisplay(); 131} 132 133 134static void 135Init(void) 136{ 137 /** 138 * Regular perspective interpolation 139 */ 140 static const char *VertShaderText1 = 141 "void main() {\n" 142 " vec4 pos = ftransform();\n" 143 " gl_TexCoord[0] = gl_MultiTexCoord0; \n" 144 " gl_Position = pos;\n" 145 "}\n"; 146 147 static const char *FragShaderText1 = 148 "void main() {\n" 149 " float gray = gl_TexCoord[0].y; \n" 150 " gl_FragColor = vec4(gray); \n" 151 "}\n"; 152 153 /** 154 * Perspective interpolation, converted to linear interpolation 155 * (put window position W in texcoord.w) 156 */ 157 static const char *VertShaderText2 = 158 "void main() {\n" 159 " vec4 pos = ftransform();\n" 160 " gl_TexCoord[0] = gl_MultiTexCoord0 * pos.w; \n" 161 " gl_TexCoord[0].w = pos.w; \n" 162 " gl_Position = pos;\n" 163 "}\n"; 164 165 static const char *FragShaderText2 = 166 "void main() {\n" 167 " float gray = gl_TexCoord[0].y / gl_TexCoord[0].w; \n" 168 " gl_FragColor = vec4(gray); \n" 169 "}\n"; 170 171 if (!ShadersSupported()) 172 exit(1); 173 174 VertShader1 = CompileShaderText(GL_VERTEX_SHADER, VertShaderText1); 175 VertShader2 = CompileShaderText(GL_VERTEX_SHADER, VertShaderText2); 176 177 FragShader1 = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText1); 178 FragShader2 = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText2); 179 180 Program1 = LinkShaders(VertShader1, FragShader1); 181 Program2 = LinkShaders(VertShader2, FragShader2); 182 183 glClearColor(0.5f, 0.5f, 0.5f, 0.0f); 184 glEnable(GL_DEPTH_TEST); 185 186 printf("GL_RENDERER = %s\n",(const char *) glGetString(GL_RENDERER)); 187 188 assert(glIsProgram(Program1)); 189 assert(glIsProgram(Program2)); 190 assert(glIsShader(VertShader1)); 191 assert(glIsShader(VertShader2)); 192 assert(glIsShader(FragShader1)); 193 assert(glIsShader(FragShader2)); 194 195 glColor3f(1, 0, 0); 196} 197 198 199int 200main(int argc, char *argv[]) 201{ 202 glutInit(&argc, argv); 203 glutInitWindowSize(Width, Height); 204 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); 205 Win = glutCreateWindow(argv[0]); 206 glewInit(); 207 glutReshapeFunc(Reshape); 208 glutKeyboardFunc(Key); 209 glutDisplayFunc(Redisplay); 210 Init(); 211 glutMainLoop(); 212 return 0; 213} 214