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