vp-array-hf.c revision 7ec3b29a
1/* Test glGenProgramsNV(), glIsProgramNV(), glLoadProgramNV() */ 2 3#include <assert.h> 4#include <string.h> 5#include <stdio.h> 6#include <stdlib.h> 7#include <math.h> 8#include <GL/glew.h> 9#include "glut_wrap.h" 10 11typedef union { GLfloat f; GLint i; } fi_type; 12/** 13 * Convert a 4-byte float to a 2-byte half float. 14 * Based on code from: 15 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html 16 */ 17static GLhalf 18_mesa_float_to_half(GLfloat val) 19{ 20 21 const fi_type fi = {val}; 22 const int flt_m = fi.i & 0x7fffff; 23 const int flt_e = (fi.i >> 23) & 0xff; 24 const int flt_s = (fi.i >> 31) & 0x1; 25 int s, e, m = 0; 26 GLhalf result; 27 28 /* sign bit */ 29 s = flt_s; 30 31 /* handle special cases */ 32 if ((flt_e == 0) && (flt_m == 0)) { 33 /* zero */ 34 /* m = 0; - already set */ 35 e = 0; 36 } 37 else if ((flt_e == 0) && (flt_m != 0)) { 38 /* denorm -- denorm float maps to 0 half */ 39 /* m = 0; - already set */ 40 e = 0; 41 } 42 else if ((flt_e == 0xff) && (flt_m == 0)) { 43 /* infinity */ 44 /* m = 0; - already set */ 45 e = 31; 46 } 47 else if ((flt_e == 0xff) && (flt_m != 0)) { 48 /* NaN */ 49 m = 1; 50 e = 31; 51 } 52 else { 53 /* regular number */ 54 const int new_exp = flt_e - 127; 55 if (new_exp < -24) { 56 /* this maps to 0 */ 57 /* m = 0; - already set */ 58 e = 0; 59 } 60 else if (new_exp < -14) { 61 /* this maps to a denorm */ 62 unsigned int exp_val = (unsigned int) (-14 - new_exp); /* 2^-exp_val*/ 63 e = 0; 64 switch (exp_val) { 65 case 0: 66 /* m = 0; - already set */ 67 break; 68 case 1: m = 512 + (flt_m >> 14); break; 69 case 2: m = 256 + (flt_m >> 15); break; 70 case 3: m = 128 + (flt_m >> 16); break; 71 case 4: m = 64 + (flt_m >> 17); break; 72 case 5: m = 32 + (flt_m >> 18); break; 73 case 6: m = 16 + (flt_m >> 19); break; 74 case 7: m = 8 + (flt_m >> 20); break; 75 case 8: m = 4 + (flt_m >> 21); break; 76 case 9: m = 2 + (flt_m >> 22); break; 77 case 10: m = 1; break; 78 } 79 } 80 else if (new_exp > 15) { 81 /* map this value to infinity */ 82 /* m = 0; - already set */ 83 e = 31; 84 } 85 else { 86 /* regular */ 87 e = new_exp + 15; 88 m = flt_m >> 13; 89 } 90 } 91 92 result = (s << 15) | (e << 10) | m; 93 return result; 94} 95 96 97GLfloat verts[][4] = { 98 { 0.9, -0.9, 0.0, 1.0 }, 99 { 0.9, 0.9, 0.0, 1.0 }, 100 { -0.9, 0.9, 0.0, 1.0 }, 101 { -0.9, -0.9, 0.0, 1.0 }, 102}; 103 104GLhalf hverts[16]; 105 106GLubyte color[][4] = { 107 { 0x00, 0x00, 0xff, 0x00 }, 108 { 0x00, 0xff, 0x00, 0x00 }, 109 { 0xff, 0x00, 0x00, 0x00 }, 110 { 0xff, 0xff, 0xff, 0x00 }, 111}; 112 113GLuint indices[] = { 0, 1, 2, 3 }; 114 115static void Init( void ) 116{ 117 GLint errnum; 118 GLuint prognum; 119 GLuint i, j; 120 121 static const char *prog1 = 122 "!!ARBvp1.0\n" 123 "MOV result.color, vertex.color;\n" 124 "MOV result.position, vertex.position;\n" 125 "END\n"; 126 127 if (!glutExtensionSupported("GL_ARB_half_float_vertex")) { 128 printf("GL_ARB_half_float_vertex not found!\n"); 129 exit(0); 130 } 131 132 glGenProgramsARB(1, &prognum); 133 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum); 134 glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, 135 strlen(prog1), (const GLubyte *) prog1); 136 137 assert(glIsProgramARB(prognum)); 138 errnum = glGetError(); 139 printf("glGetError = %d\n", errnum); 140 if (errnum != GL_NO_ERROR) 141 { 142 GLint errorpos; 143 144 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos); 145 printf("errorpos: %d\n", errorpos); 146 printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)); 147 } 148 149 for (i = 0; i < 4; i++) 150 for (j = 0; j < 4; j++) 151 hverts[i * 4 + j] = _mesa_float_to_half(verts[i][j]); 152 153 glEnableClientState( GL_VERTEX_ARRAY ); 154 glEnableClientState( GL_COLOR_ARRAY ); 155 glVertexPointer( 4, GL_HALF_FLOAT, 8, hverts ); 156 glColorPointer( 4, GL_UNSIGNED_BYTE, 0, color ); 157 158} 159 160 161 162static void Display( void ) 163{ 164 glClearColor(0.3, 0.3, 0.3, 1); 165 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 166 167 glEnable(GL_VERTEX_PROGRAM_NV); 168 glDrawElements( GL_TRIANGLES, 3, GL_UNSIGNED_INT, indices ); 169 170 glFlush(); 171} 172 173 174static void Reshape( int width, int height ) 175{ 176 glViewport( 0, 0, width, height ); 177 glMatrixMode( GL_PROJECTION ); 178 glLoadIdentity(); 179 glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0); 180 glMatrixMode( GL_MODELVIEW ); 181 glLoadIdentity(); 182 /*glTranslatef( 0.0, 0.0, -15.0 );*/ 183} 184 185 186static void Key( unsigned char key, int x, int y ) 187{ 188 (void) x; 189 (void) y; 190 switch (key) { 191 case 27: 192 exit(0); 193 break; 194 } 195 glutPostRedisplay(); 196} 197 198 199 200 201int main( int argc, char *argv[] ) 202{ 203 glutInit( &argc, argv ); 204 glutInitWindowPosition( 0, 0 ); 205 glutInitWindowSize( 250, 250 ); 206 glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH ); 207 glutCreateWindow(argv[0]); 208 glewInit(); 209 glutReshapeFunc( Reshape ); 210 glutKeyboardFunc( Key ); 211 glutDisplayFunc( Display ); 212 Init(); 213 glutMainLoop(); 214 return 0; 215} 216