progs: add trivial ARB_half_float_vertex support.
[mesa.git] / progs / trivial / vp-array-hf.c
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 <GL/glut.h>
10
11 typedef 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 */
17 static 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
97 GLfloat 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
104 GLhalf hverts[16];
105
106 GLubyte color[][4] = {
107 { 0x00, 0x00, 0xff, 0x00 },
108 { 0x00, 0xff, 0x00, 0x00 },
109 { 0xff, 0x00, 0x00, 0x00 },
110 { 0xff, 0xff, 0xff, 0x00 },
111 };
112
113 GLuint indices[] = { 0, 1, 2, 3 };
114
115 static void Init( void )
116 {
117 GLint errno;
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 errno = glGetError();
139 printf("glGetError = %d\n", errno);
140 if (errno != 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
162 static 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
174 static 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
186 static 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
201 int 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 }