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