1/*
2 * Test floating point textures.
3 */
4
5
6#include <assert.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10#include <GL/glew.h>
11#include "glut_wrap.h"
12#include "readtex.h"
13#include "shaderutil.h"
14
15
16static const char *TexFile = DEMOS_DATA_DIR "arch.rgb";
17
18static const char *FragShaderText =
19   "uniform sampler2D tex1; \n"
20   "void main() \n"
21   "{ \n"
22   "   vec4 t = texture2D(tex1, gl_TexCoord[0].xy); \n"
23   "   // convert from [-255,0] to [0,1] \n"
24   "   gl_FragColor = t * (-1.0 / 255.0); \n"
25   "} \n";
26
27static const char *VertShaderText =
28   "void main() \n"
29   "{ \n"
30   "   gl_TexCoord[0] = gl_MultiTexCoord0; \n"
31   "   gl_Position = ftransform(); \n"
32   "} \n";
33
34static struct uniform_info Uniforms[] = {
35   { "tex1",  1, GL_SAMPLER_2D, { 0, 0, 0, 0 }, -1 },
36   END_OF_UNIFORMS
37};
38
39
40static GLuint Program;
41
42
43
44static GLboolean
45CheckError( int line )
46{
47   GLenum error = glGetError();
48   if (error) {
49      char *err = (char *) gluErrorString( error );
50      fprintf( stderr, "GL Error: %s at line %d\n", err, line );
51      return GL_TRUE;
52   }
53   return GL_FALSE;
54}
55
56
57static void
58Draw(void)
59{
60   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
61
62   glPushMatrix();
63
64   glBegin(GL_POLYGON);
65   glTexCoord2f( 0.0, 0.0 );   glVertex2f( -1.0, -1.0 );
66   glTexCoord2f( 1.0, 0.0 );   glVertex2f(  1.0, -1.0 );
67   glTexCoord2f( 1.0, 1.0 );   glVertex2f(  1.0,  1.0 );
68   glTexCoord2f( 0.0, 1.0 );   glVertex2f( -1.0,  1.0 );
69   glEnd();
70
71   glPopMatrix();
72
73   glutSwapBuffers();
74}
75
76
77static void
78Reshape(int width, int height)
79{
80   glViewport(0, 0, width, height);
81   glMatrixMode(GL_PROJECTION);
82   glLoadIdentity();
83   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
84   glMatrixMode(GL_MODELVIEW);
85   glLoadIdentity();
86   glTranslatef(0.0, 0.0, -8.0);
87}
88
89
90static void
91Key(unsigned char key, int x, int y)
92{
93   (void) x;
94   (void) y;
95   switch (key) {
96      case 27:
97         exit(0);
98         break;
99   }
100   glutPostRedisplay();
101}
102
103
104static void
105InitTexture(void)
106{
107   GLenum filter = GL_LINEAR;
108   GLint imgWidth, imgHeight;
109   GLenum imgFormat;
110   GLubyte *image = NULL;
111   GLfloat *ftex;
112   GLint i, t;
113
114   image = LoadRGBImage(TexFile, &imgWidth, &imgHeight, &imgFormat);
115   if (!image) {
116      printf("Couldn't read %s\n", TexFile);
117      exit(0);
118   }
119
120   assert(imgFormat == GL_RGB);
121
122   ftex = (float *) malloc(imgWidth * imgHeight * 4 * sizeof(float));
123   if (!ftex) {
124      printf("out of memory\n");
125      exit(0);
126   }
127
128   /* convert ubytes to floats, negated */
129   for (i = 0; i < imgWidth * imgHeight * 3; i++) {
130      ftex[i] = -1.0f * image[i];
131   }
132
133   glActiveTexture(GL_TEXTURE0);
134   glBindTexture(GL_TEXTURE_2D, 42);
135
136   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB,
137                imgWidth, imgHeight, 0,
138                GL_RGB, GL_FLOAT, ftex);
139
140
141   CheckError(__LINE__);
142
143   /* sanity checks */
144   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_TYPE_ARB, &t);
145   assert(t == GL_FLOAT);
146   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_TYPE_ARB, &t);
147   assert(t == GL_FLOAT);
148   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_TYPE_ARB, &t);
149   assert(t == GL_FLOAT);
150   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_TYPE_ARB, &t);
151   assert(t == GL_FLOAT);
152
153   free(image);
154   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
155   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
156   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
157   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
158
159   if (1) {
160      /* read back the texture and make sure values are correct */
161      GLfloat *tex2 = (GLfloat *)
162         malloc(imgWidth * imgHeight * 4 * sizeof(GLfloat));
163      glGetTexImage(GL_TEXTURE_2D, 0, imgFormat, GL_FLOAT, tex2);
164      CheckError(__LINE__);
165      for (i = 0; i < imgWidth * imgHeight * 4; i++) {
166         if (ftex[i] != tex2[i]) {
167            printf("tex[%d] %g != tex2[%d] %g\n",
168                   i, ftex[i], i, tex2[i]);
169         }
170      }
171   }
172
173   free(ftex);
174}
175
176
177static GLuint
178CreateAProgram(void)
179{
180   GLuint fragShader, vertShader, program;
181
182   vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText);
183   fragShader = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText);
184   assert(vertShader);
185   program = LinkShaders(vertShader, fragShader);
186
187   assert(program);
188
189   glUseProgram(program);
190
191   SetUniformValues(program, Uniforms);
192
193   return program;
194}
195
196
197static void
198Init(void)
199{
200   glClearColor(0.25, 0.25, 0.25, 0.0);
201
202   if (!ShadersSupported()) {
203      printf("Sorry, this test requires GLSL\n");
204      exit(1);
205   }
206
207   if (!glutExtensionSupported("GL_MESAX_texture_float") &&
208       !glutExtensionSupported("GL_ARB_texture_float")) {
209      printf("Sorry, this test requires GL_MESAX/ARB_texture_float\n");
210      exit(1);
211   }
212
213   InitTexture();
214
215   Program = CreateAProgram();
216   glUseProgram(Program);
217}
218
219
220int
221main(int argc, char *argv[])
222{
223   glutInit(&argc, argv);
224   glutInitWindowPosition(0, 0);
225   glutInitWindowSize(400, 400);
226   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
227   glutCreateWindow(argv[0]);
228   glewInit();
229   glutReshapeFunc(Reshape);
230   glutKeyboardFunc(Key);
231   glutDisplayFunc(Draw);
232   Init();
233   glutMainLoop();
234   return 0;
235}
236