| /* 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; |
| } |