132001f49Smrg/* Test glGenProgramsNV(), glIsProgramNV(), glLoadProgramNV() */ 232001f49Smrg 332001f49Smrg#include <assert.h> 432001f49Smrg#include <string.h> 532001f49Smrg#include <stdio.h> 632001f49Smrg#include <stdlib.h> 732001f49Smrg#include <math.h> 832001f49Smrg#include <GL/glew.h> 932001f49Smrg#include "glut_wrap.h" 1032001f49Smrg 1132001f49Smrgtypedef union { GLfloat f; GLint i; } fi_type; 1232001f49Smrg/** 1332001f49Smrg * Convert a 4-byte float to a 2-byte half float. 1432001f49Smrg * Based on code from: 1532001f49Smrg * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html 1632001f49Smrg */ 1732001f49Smrgstatic GLhalf 1832001f49Smrg_mesa_float_to_half(GLfloat val) 1932001f49Smrg{ 2032001f49Smrg 2132001f49Smrg const fi_type fi = {val}; 2232001f49Smrg const int flt_m = fi.i & 0x7fffff; 2332001f49Smrg const int flt_e = (fi.i >> 23) & 0xff; 2432001f49Smrg const int flt_s = (fi.i >> 31) & 0x1; 2532001f49Smrg int s, e, m = 0; 2632001f49Smrg GLhalf result; 2732001f49Smrg 2832001f49Smrg /* sign bit */ 2932001f49Smrg s = flt_s; 3032001f49Smrg 3132001f49Smrg /* handle special cases */ 3232001f49Smrg if ((flt_e == 0) && (flt_m == 0)) { 3332001f49Smrg /* zero */ 3432001f49Smrg /* m = 0; - already set */ 3532001f49Smrg e = 0; 3632001f49Smrg } 3732001f49Smrg else if ((flt_e == 0) && (flt_m != 0)) { 3832001f49Smrg /* denorm -- denorm float maps to 0 half */ 3932001f49Smrg /* m = 0; - already set */ 4032001f49Smrg e = 0; 4132001f49Smrg } 4232001f49Smrg else if ((flt_e == 0xff) && (flt_m == 0)) { 4332001f49Smrg /* infinity */ 4432001f49Smrg /* m = 0; - already set */ 4532001f49Smrg e = 31; 4632001f49Smrg } 4732001f49Smrg else if ((flt_e == 0xff) && (flt_m != 0)) { 4832001f49Smrg /* NaN */ 4932001f49Smrg m = 1; 5032001f49Smrg e = 31; 5132001f49Smrg } 5232001f49Smrg else { 5332001f49Smrg /* regular number */ 5432001f49Smrg const int new_exp = flt_e - 127; 5532001f49Smrg if (new_exp < -24) { 5632001f49Smrg /* this maps to 0 */ 5732001f49Smrg /* m = 0; - already set */ 5832001f49Smrg e = 0; 5932001f49Smrg } 6032001f49Smrg else if (new_exp < -14) { 6132001f49Smrg /* this maps to a denorm */ 6232001f49Smrg unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/ 6332001f49Smrg e = 0; 6432001f49Smrg switch (exp_val) { 6532001f49Smrg case 0: 6632001f49Smrg /* m = 0; - already set */ 6732001f49Smrg break; 6832001f49Smrg case 1: m = 512 + (flt_m >> 14); break; 6932001f49Smrg case 2: m = 256 + (flt_m >> 15); break; 7032001f49Smrg case 3: m = 128 + (flt_m >> 16); break; 7132001f49Smrg case 4: m = 64 + (flt_m >> 17); break; 7232001f49Smrg case 5: m = 32 + (flt_m >> 18); break; 7332001f49Smrg case 6: m = 16 + (flt_m >> 19); break; 7432001f49Smrg case 7: m = 8 + (flt_m >> 20); break; 7532001f49Smrg case 8: m = 4 + (flt_m >> 21); break; 7632001f49Smrg case 9: m = 2 + (flt_m >> 22); break; 7732001f49Smrg case 10: m = 1; break; 7832001f49Smrg } 7932001f49Smrg } 8032001f49Smrg else if (new_exp > 15) { 8132001f49Smrg /* map this value to infinity */ 8232001f49Smrg /* m = 0; - already set */ 8332001f49Smrg e = 31; 8432001f49Smrg } 8532001f49Smrg else { 8632001f49Smrg /* regular */ 8732001f49Smrg e = new_exp + 15; 8832001f49Smrg m = flt_m >> 13; 8932001f49Smrg } 9032001f49Smrg } 9132001f49Smrg 9232001f49Smrg result = (s << 15) | (e << 10) | m; 9332001f49Smrg return result; 9432001f49Smrg} 9532001f49Smrg 9632001f49Smrg 9732001f49SmrgGLfloat verts[][4] = { 9832001f49Smrg { 0.9, -0.9, 0.0, 1.0 }, 9932001f49Smrg { 0.9, 0.9, 0.0, 1.0 }, 10032001f49Smrg { -0.9, 0.9, 0.0, 1.0 }, 10132001f49Smrg { -0.9, -0.9, 0.0, 1.0 }, 10232001f49Smrg}; 10332001f49Smrg 10432001f49SmrgGLhalf hverts[16]; 10532001f49Smrg 10632001f49SmrgGLubyte color[][4] = { 10732001f49Smrg { 0x00, 0x00, 0xff, 0x00 }, 10832001f49Smrg { 0x00, 0xff, 0x00, 0x00 }, 10932001f49Smrg { 0xff, 0x00, 0x00, 0x00 }, 11032001f49Smrg { 0xff, 0xff, 0xff, 0x00 }, 11132001f49Smrg}; 11232001f49Smrg 11332001f49SmrgGLuint indices[] = { 0, 1, 2, 3 }; 11432001f49Smrg 11532001f49Smrgstatic void Init( void ) 11632001f49Smrg{ 1177ec3b29aSmrg GLint errnum; 11832001f49Smrg GLuint prognum; 11932001f49Smrg GLuint i, j; 12032001f49Smrg 12132001f49Smrg static const char *prog1 = 12232001f49Smrg "!!ARBvp1.0\n" 12332001f49Smrg "MOV result.color, vertex.color;\n" 12432001f49Smrg "MOV result.position, vertex.position;\n" 12532001f49Smrg "END\n"; 12632001f49Smrg 12732001f49Smrg if (!glutExtensionSupported("GL_ARB_half_float_vertex")) { 12832001f49Smrg printf("GL_ARB_half_float_vertex not found!\n"); 12932001f49Smrg exit(0); 13032001f49Smrg } 13132001f49Smrg 13232001f49Smrg glGenProgramsARB(1, &prognum); 13332001f49Smrg glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum); 13432001f49Smrg glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, 13532001f49Smrg strlen(prog1), (const GLubyte *) prog1); 13632001f49Smrg 13732001f49Smrg assert(glIsProgramARB(prognum)); 1387ec3b29aSmrg errnum = glGetError(); 1397ec3b29aSmrg printf("glGetError = %d\n", errnum); 1407ec3b29aSmrg if (errnum != GL_NO_ERROR) 14132001f49Smrg { 14232001f49Smrg GLint errorpos; 14332001f49Smrg 14432001f49Smrg glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos); 14532001f49Smrg printf("errorpos: %d\n", errorpos); 14632001f49Smrg printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)); 14732001f49Smrg } 14832001f49Smrg 14932001f49Smrg for (i = 0; i < 4; i++) 15032001f49Smrg for (j = 0; j < 4; j++) 15132001f49Smrg hverts[i * 4 + j] = _mesa_float_to_half(verts[i][j]); 15232001f49Smrg 15332001f49Smrg glEnableClientState( GL_VERTEX_ARRAY ); 15432001f49Smrg glEnableClientState( GL_COLOR_ARRAY ); 15532001f49Smrg glVertexPointer( 4, GL_HALF_FLOAT, 8, hverts ); 15632001f49Smrg glColorPointer( 4, GL_UNSIGNED_BYTE, 0, color ); 15732001f49Smrg 15832001f49Smrg} 15932001f49Smrg 16032001f49Smrg 16132001f49Smrg 16232001f49Smrgstatic void Display( void ) 16332001f49Smrg{ 16432001f49Smrg glClearColor(0.3, 0.3, 0.3, 1); 16532001f49Smrg glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 16632001f49Smrg 16732001f49Smrg glEnable(GL_VERTEX_PROGRAM_NV); 16832001f49Smrg glDrawElements( GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices ); 16932001f49Smrg 17032001f49Smrg glFlush(); 17132001f49Smrg} 17232001f49Smrg 17332001f49Smrg 17432001f49Smrgstatic void Reshape( int width, int height ) 17532001f49Smrg{ 17632001f49Smrg glViewport( 0, 0, width, height ); 17732001f49Smrg glMatrixMode( GL_PROJECTION ); 17832001f49Smrg glLoadIdentity(); 17932001f49Smrg glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); 18032001f49Smrg glMatrixMode( GL_MODELVIEW ); 18132001f49Smrg glLoadIdentity(); 18232001f49Smrg /*glTranslatef( 0.0, 0.0, -15.0 );*/ 18332001f49Smrg} 18432001f49Smrg 18532001f49Smrg 18632001f49Smrgstatic void Key( unsigned char key, int x, int y ) 18732001f49Smrg{ 18832001f49Smrg (void) x; 18932001f49Smrg (void) y; 19032001f49Smrg switch (key) { 19132001f49Smrg case 27: 19232001f49Smrg exit(0); 19332001f49Smrg break; 19432001f49Smrg } 19532001f49Smrg glutPostRedisplay(); 19632001f49Smrg} 19732001f49Smrg 19832001f49Smrg 19932001f49Smrg 20032001f49Smrg 20132001f49Smrgint main( int argc, char *argv[] ) 20232001f49Smrg{ 20332001f49Smrg glutInit( &argc, argv ); 20432001f49Smrg glutInitWindowPosition( 0, 0 ); 20532001f49Smrg glutInitWindowSize( 250, 250 ); 20632001f49Smrg glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH ); 20732001f49Smrg glutCreateWindow(argv[0]); 20832001f49Smrg glewInit(); 20932001f49Smrg glutReshapeFunc( Reshape ); 21032001f49Smrg glutKeyboardFunc( Key ); 21132001f49Smrg glutDisplayFunc( Display ); 21232001f49Smrg Init(); 21332001f49Smrg glutMainLoop(); 21432001f49Smrg return 0; 21532001f49Smrg} 216