diff options
Diffstat (limited to 'progs/trivial')
| -rw-r--r-- | progs/trivial/Makefile | 1 | ||||
| -rw-r--r-- | progs/trivial/vp-array-hf.c | 215 | 
2 files changed, 216 insertions, 0 deletions
diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile index 5e08d60389..207215dee9 100644 --- a/progs/trivial/Makefile +++ b/progs/trivial/Makefile @@ -160,6 +160,7 @@ SOURCES = \  	vbo-drawelements.c \  	vbo-drawrange.c \  	vp-array.c \ +	vp-array-hf.c \  	vp-array-int.c \  	vp-clip.c \  	vp-line-clip.c \ diff --git a/progs/trivial/vp-array-hf.c b/progs/trivial/vp-array-hf.c new file mode 100644 index 0000000000..f812436437 --- /dev/null +++ b/progs/trivial/vp-array-hf.c @@ -0,0 +1,215 @@ +/* Test glGenProgramsNV(), glIsProgramNV(), glLoadProgramNV() */ + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glew.h> +#include <GL/glut.h> + +typedef union { GLfloat f; GLint i; } fi_type; +/** + * Convert a 4-byte float to a 2-byte half float. + * Based on code from: + * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html + */ +static GLhalf +_mesa_float_to_half(GLfloat val) +{ + +   const fi_type fi = {val}; +   const int flt_m = fi.i & 0x7fffff; +   const int flt_e = (fi.i >> 23) & 0xff; +   const int flt_s = (fi.i >> 31) & 0x1; +   int s, e, m = 0; +   GLhalf result; +    +   /* sign bit */ +   s = flt_s; + +   /* handle special cases */ +   if ((flt_e == 0) && (flt_m == 0)) { +      /* zero */ +      /* m = 0; - already set */ +      e = 0; +   } +   else if ((flt_e == 0) && (flt_m != 0)) { +      /* denorm -- denorm float maps to 0 half */ +      /* m = 0; - already set */ +      e = 0; +   } +   else if ((flt_e == 0xff) && (flt_m == 0)) { +      /* infinity */ +      /* m = 0; - already set */ +      e = 31; +   } +   else if ((flt_e == 0xff) && (flt_m != 0)) { +      /* NaN */ +      m = 1; +      e = 31; +   } +   else { +      /* regular number */ +      const int new_exp = flt_e - 127; +      if (new_exp < -24) { +         /* this maps to 0 */ +         /* m = 0; - already set */ +         e = 0; +      } +      else if (new_exp < -14) { +         /* this maps to a denorm */ +         unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/ +         e = 0; +         switch (exp_val) { +            case 0: +               /* m = 0; - already set */ +               break; +            case 1: m = 512 + (flt_m >> 14); break; +            case 2: m = 256 + (flt_m >> 15); break; +            case 3: m = 128 + (flt_m >> 16); break; +            case 4: m = 64 + (flt_m >> 17); break; +            case 5: m = 32 + (flt_m >> 18); break; +            case 6: m = 16 + (flt_m >> 19); break; +            case 7: m = 8 + (flt_m >> 20); break; +            case 8: m = 4 + (flt_m >> 21); break; +            case 9: m = 2 + (flt_m >> 22); break; +            case 10: m = 1; break; +         } +      } +      else if (new_exp > 15) { +         /* map this value to infinity */ +         /* m = 0; - already set */ +         e = 31; +      } +      else { +         /* regular */ +         e = new_exp + 15; +         m = flt_m >> 13; +      } +   } + +   result = (s << 15) | (e << 10) | m; +   return result; +} + + +GLfloat verts[][4] = { +   {  0.9, -0.9, 0.0, 1.0 }, +   {  0.9,  0.9, 0.0, 1.0 }, +   { -0.9,  0.9, 0.0, 1.0 }, +   { -0.9, -0.9, 0.0, 1.0 }, +}; + +GLhalf hverts[16]; + +GLubyte color[][4] = { +   { 0x00, 0x00, 0xff, 0x00 }, +   { 0x00, 0xff, 0x00, 0x00 }, +   { 0xff, 0x00, 0x00, 0x00 }, +   { 0xff, 0xff, 0xff, 0x00 }, +}; + +GLuint indices[] = { 0, 1, 2, 3 }; + +static void Init( void ) +{ +   GLint errno; +   GLuint prognum; +   GLuint i, j; + +   static const char *prog1 = +      "!!ARBvp1.0\n" +      "MOV  result.color, vertex.color;\n" +      "MOV  result.position, vertex.position;\n" +      "END\n"; + +   if (!glutExtensionSupported("GL_ARB_half_float_vertex")) { +      printf("GL_ARB_half_float_vertex not found!\n"); +      exit(0); +   } + +   glGenProgramsARB(1, &prognum); +   glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum); +   glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, +		      strlen(prog1), (const GLubyte *) prog1); + +   assert(glIsProgramARB(prognum)); +   errno = glGetError(); +   printf("glGetError = %d\n", errno); +   if (errno != GL_NO_ERROR) +   { +      GLint errorpos; + +      glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos); +      printf("errorpos: %d\n", errorpos); +      printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)); +   } + +   for (i = 0; i < 4; i++) +      for (j = 0; j < 4; j++) +	 hverts[i * 4 + j] = _mesa_float_to_half(verts[i][j]); + +   glEnableClientState( GL_VERTEX_ARRAY ); +   glEnableClientState( GL_COLOR_ARRAY ); +   glVertexPointer( 4, GL_HALF_FLOAT, 8, hverts ); +   glColorPointer( 4, GL_UNSIGNED_BYTE, 0, color ); + +} + + + +static void Display( void ) +{ +   glClearColor(0.3, 0.3, 0.3, 1); +   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + +   glEnable(GL_VERTEX_PROGRAM_NV); +   glDrawElements( GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices ); + +   glFlush();  +} + + +static void Reshape( int width, int height ) +{ +   glViewport( 0, 0, width, height ); +   glMatrixMode( GL_PROJECTION ); +   glLoadIdentity(); +   glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); +   glMatrixMode( GL_MODELVIEW ); +   glLoadIdentity(); +   /*glTranslatef( 0.0, 0.0, -15.0 );*/ +} + + +static void Key( unsigned char key, int x, int y ) +{ +   (void) x; +   (void) y; +   switch (key) { +      case 27: +         exit(0); +         break; +   } +   glutPostRedisplay(); +} + + + + +int main( int argc, char *argv[] ) +{ +   glutInit( &argc, argv ); +   glutInitWindowPosition( 0, 0 ); +   glutInitWindowSize( 250, 250 ); +   glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH ); +   glutCreateWindow(argv[0]); +   glewInit(); +   glutReshapeFunc( Reshape ); +   glutKeyboardFunc( Key ); +   glutDisplayFunc( Display ); +   Init(); +   glutMainLoop(); +   return 0; +}  | 
