132001f49Smrg/*
232001f49Smrg * Test floating point textures.
332001f49Smrg */
432001f49Smrg
532001f49Smrg
632001f49Smrg#include <assert.h>
732001f49Smrg#include <stdio.h>
832001f49Smrg#include <stdlib.h>
932001f49Smrg#include <math.h>
1032001f49Smrg#include <GL/glew.h>
1132001f49Smrg#include "glut_wrap.h"
1232001f49Smrg#include "readtex.h"
1332001f49Smrg#include "shaderutil.h"
1432001f49Smrg
1532001f49Smrg
1632001f49Smrgstatic const char *TexFile = DEMOS_DATA_DIR "arch.rgb";
1732001f49Smrg
1832001f49Smrgstatic const char *FragShaderText =
1932001f49Smrg   "uniform sampler2D tex1; \n"
2032001f49Smrg   "void main() \n"
2132001f49Smrg   "{ \n"
2232001f49Smrg   "   vec4 t = texture2D(tex1, gl_TexCoord[0].xy); \n"
2332001f49Smrg   "   // convert from [-255,0] to [0,1] \n"
2432001f49Smrg   "   gl_FragColor = t * (-1.0 / 255.0); \n"
2532001f49Smrg   "} \n";
2632001f49Smrg
2732001f49Smrgstatic const char *VertShaderText =
2832001f49Smrg   "void main() \n"
2932001f49Smrg   "{ \n"
3032001f49Smrg   "   gl_TexCoord[0] = gl_MultiTexCoord0; \n"
3132001f49Smrg   "   gl_Position = ftransform(); \n"
3232001f49Smrg   "} \n";
3332001f49Smrg
3432001f49Smrgstatic struct uniform_info Uniforms[] = {
3532001f49Smrg   { "tex1",  1, GL_SAMPLER_2D, { 0, 0, 0, 0 }, -1 },
3632001f49Smrg   END_OF_UNIFORMS
3732001f49Smrg};
3832001f49Smrg
3932001f49Smrg
4032001f49Smrgstatic GLuint Program;
4132001f49Smrg
4232001f49Smrg
4332001f49Smrg
4432001f49Smrgstatic GLboolean
4532001f49SmrgCheckError( int line )
4632001f49Smrg{
4732001f49Smrg   GLenum error = glGetError();
4832001f49Smrg   if (error) {
4932001f49Smrg      char *err = (char *) gluErrorString( error );
5032001f49Smrg      fprintf( stderr, "GL Error: %s at line %d\n", err, line );
5132001f49Smrg      return GL_TRUE;
5232001f49Smrg   }
5332001f49Smrg   return GL_FALSE;
5432001f49Smrg}
5532001f49Smrg
5632001f49Smrg
5732001f49Smrgstatic void
5832001f49SmrgDraw(void)
5932001f49Smrg{
6032001f49Smrg   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
6132001f49Smrg
6232001f49Smrg   glPushMatrix();
6332001f49Smrg
6432001f49Smrg   glBegin(GL_POLYGON);
6532001f49Smrg   glTexCoord2f( 0.0, 0.0 );   glVertex2f( -1.0, -1.0 );
6632001f49Smrg   glTexCoord2f( 1.0, 0.0 );   glVertex2f(  1.0, -1.0 );
6732001f49Smrg   glTexCoord2f( 1.0, 1.0 );   glVertex2f(  1.0,  1.0 );
6832001f49Smrg   glTexCoord2f( 0.0, 1.0 );   glVertex2f( -1.0,  1.0 );
6932001f49Smrg   glEnd();
7032001f49Smrg
7132001f49Smrg   glPopMatrix();
7232001f49Smrg
7332001f49Smrg   glutSwapBuffers();
7432001f49Smrg}
7532001f49Smrg
7632001f49Smrg
7732001f49Smrgstatic void
7832001f49SmrgReshape(int width, int height)
7932001f49Smrg{
8032001f49Smrg   glViewport(0, 0, width, height);
8132001f49Smrg   glMatrixMode(GL_PROJECTION);
8232001f49Smrg   glLoadIdentity();
8332001f49Smrg   glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
8432001f49Smrg   glMatrixMode(GL_MODELVIEW);
8532001f49Smrg   glLoadIdentity();
8632001f49Smrg   glTranslatef(0.0, 0.0, -8.0);
8732001f49Smrg}
8832001f49Smrg
8932001f49Smrg
9032001f49Smrgstatic void
9132001f49SmrgKey(unsigned char key, int x, int y)
9232001f49Smrg{
9332001f49Smrg   (void) x;
9432001f49Smrg   (void) y;
9532001f49Smrg   switch (key) {
9632001f49Smrg      case 27:
9732001f49Smrg         exit(0);
9832001f49Smrg         break;
9932001f49Smrg   }
10032001f49Smrg   glutPostRedisplay();
10132001f49Smrg}
10232001f49Smrg
10332001f49Smrg
10432001f49Smrgstatic void
10532001f49SmrgInitTexture(void)
10632001f49Smrg{
10732001f49Smrg   GLenum filter = GL_LINEAR;
10832001f49Smrg   GLint imgWidth, imgHeight;
10932001f49Smrg   GLenum imgFormat;
11032001f49Smrg   GLubyte *image = NULL;
11132001f49Smrg   GLfloat *ftex;
11232001f49Smrg   GLint i, t;
11332001f49Smrg
11432001f49Smrg   image = LoadRGBImage(TexFile, &imgWidth, &imgHeight, &imgFormat);
11532001f49Smrg   if (!image) {
11632001f49Smrg      printf("Couldn't read %s\n", TexFile);
11732001f49Smrg      exit(0);
11832001f49Smrg   }
11932001f49Smrg
12032001f49Smrg   assert(imgFormat == GL_RGB);
12132001f49Smrg
12232001f49Smrg   ftex = (float *) malloc(imgWidth * imgHeight * 4 * sizeof(float));
12332001f49Smrg   if (!ftex) {
12432001f49Smrg      printf("out of memory\n");
12532001f49Smrg      exit(0);
12632001f49Smrg   }
12732001f49Smrg
12832001f49Smrg   /* convert ubytes to floats, negated */
12932001f49Smrg   for (i = 0; i < imgWidth * imgHeight * 3; i++) {
13032001f49Smrg      ftex[i] = -1.0f * image[i];
13132001f49Smrg   }
13232001f49Smrg
13332001f49Smrg   glActiveTexture(GL_TEXTURE0);
13432001f49Smrg   glBindTexture(GL_TEXTURE_2D, 42);
13532001f49Smrg
13632001f49Smrg   glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB,
13732001f49Smrg                imgWidth, imgHeight, 0,
13832001f49Smrg                GL_RGB, GL_FLOAT, ftex);
13932001f49Smrg
14032001f49Smrg
14132001f49Smrg   CheckError(__LINE__);
14232001f49Smrg
14332001f49Smrg   /* sanity checks */
14432001f49Smrg   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_TYPE_ARB, &t);
14532001f49Smrg   assert(t == GL_FLOAT);
14632001f49Smrg   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_TYPE_ARB, &t);
14732001f49Smrg   assert(t == GL_FLOAT);
14832001f49Smrg   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_TYPE_ARB, &t);
14932001f49Smrg   assert(t == GL_FLOAT);
15032001f49Smrg   glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_TYPE_ARB, &t);
15132001f49Smrg   assert(t == GL_FLOAT);
15232001f49Smrg
15332001f49Smrg   free(image);
15432001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
15532001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
15632001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
15732001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
15832001f49Smrg
15932001f49Smrg   if (1) {
16032001f49Smrg      /* read back the texture and make sure values are correct */
16132001f49Smrg      GLfloat *tex2 = (GLfloat *)
16232001f49Smrg         malloc(imgWidth * imgHeight * 4 * sizeof(GLfloat));
16332001f49Smrg      glGetTexImage(GL_TEXTURE_2D, 0, imgFormat, GL_FLOAT, tex2);
16432001f49Smrg      CheckError(__LINE__);
16532001f49Smrg      for (i = 0; i < imgWidth * imgHeight * 4; i++) {
16632001f49Smrg         if (ftex[i] != tex2[i]) {
16732001f49Smrg            printf("tex[%d] %g != tex2[%d] %g\n",
16832001f49Smrg                   i, ftex[i], i, tex2[i]);
16932001f49Smrg         }
17032001f49Smrg      }
17132001f49Smrg   }
17232001f49Smrg
17332001f49Smrg   free(ftex);
17432001f49Smrg}
17532001f49Smrg
17632001f49Smrg
17732001f49Smrgstatic GLuint
17832001f49SmrgCreateAProgram(void)
17932001f49Smrg{
18032001f49Smrg   GLuint fragShader, vertShader, program;
18132001f49Smrg
18232001f49Smrg   vertShader = CompileShaderText(GL_VERTEX_SHADER, VertShaderText);
18332001f49Smrg   fragShader = CompileShaderText(GL_FRAGMENT_SHADER, FragShaderText);
18432001f49Smrg   assert(vertShader);
18532001f49Smrg   program = LinkShaders(vertShader, fragShader);
18632001f49Smrg
18732001f49Smrg   assert(program);
18832001f49Smrg
18932001f49Smrg   glUseProgram(program);
19032001f49Smrg
19132001f49Smrg   SetUniformValues(program, Uniforms);
19232001f49Smrg
19332001f49Smrg   return program;
19432001f49Smrg}
19532001f49Smrg
19632001f49Smrg
19732001f49Smrgstatic void
19832001f49SmrgInit(void)
19932001f49Smrg{
20032001f49Smrg   glClearColor(0.25, 0.25, 0.25, 0.0);
20132001f49Smrg
20232001f49Smrg   if (!ShadersSupported()) {
20332001f49Smrg      printf("Sorry, this test requires GLSL\n");
20432001f49Smrg      exit(1);
20532001f49Smrg   }
20632001f49Smrg
20732001f49Smrg   if (!glutExtensionSupported("GL_MESAX_texture_float") &&
20832001f49Smrg       !glutExtensionSupported("GL_ARB_texture_float")) {
20932001f49Smrg      printf("Sorry, this test requires GL_MESAX/ARB_texture_float\n");
21032001f49Smrg      exit(1);
21132001f49Smrg   }
21232001f49Smrg
21332001f49Smrg   InitTexture();
21432001f49Smrg
21532001f49Smrg   Program = CreateAProgram();
21632001f49Smrg   glUseProgram(Program);
21732001f49Smrg}
21832001f49Smrg
21932001f49Smrg
22032001f49Smrgint
22132001f49Smrgmain(int argc, char *argv[])
22232001f49Smrg{
22332001f49Smrg   glutInit(&argc, argv);
22432001f49Smrg   glutInitWindowPosition(0, 0);
22532001f49Smrg   glutInitWindowSize(400, 400);
22632001f49Smrg   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
22732001f49Smrg   glutCreateWindow(argv[0]);
22832001f49Smrg   glewInit();
22932001f49Smrg   glutReshapeFunc(Reshape);
23032001f49Smrg   glutKeyboardFunc(Key);
23132001f49Smrg   glutDisplayFunc(Draw);
23232001f49Smrg   Init();
23332001f49Smrg   glutMainLoop();
23432001f49Smrg   return 0;
23532001f49Smrg}
236