1/* Copyright (c) 2011 Dave Airlie
2   based on vbo-drawarrays.c, which should be MIT licensed */
3
4/* Basic VBO testing ARB_vertex_type_2_10_10_10_rev */
5
6#include <assert.h>
7#include <string.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <math.h>
11#include <GL/glew.h>
12#include "glut_wrap.h"
13
14GLboolean bgra = GL_FALSE;
15#define i32to10(x) ((x) >= 0 ? (x & 0x1ff) : 1024-(abs((x))& 0x1ff))
16#define i32to2(x) ((x) >= 0 ? (x & 0x1) : 3-abs((x)))
17
18static unsigned iconv(int x, int y, int z, int w)
19{
20	unsigned val;
21
22	val = i32to10(x);
23	val |= i32to10(y) << 10;
24	val |= i32to10(z) << 20;
25	val |= i32to2(w) << 30;
26	return val;
27}
28#define conv(x,y,z,w) (((x) & 0x3ff) | ((y) & 0x3ff) << 10 | ((z) & 0x3ff)<< 20 | ((w) & 0x3) << 30)
29
30struct {
31   GLuint pos;
32   GLuint color;
33} verts[3];
34
35#define XYVAL 90
36#define ZVAL -30
37
38#define COLVAL 820
39
40static void SetupVerts(void)
41{
42  verts[0].pos = iconv(-XYVAL, -XYVAL, ZVAL, 1);
43  verts[0].color = conv(COLVAL, 0, 0, 0);
44
45  verts[1].pos = iconv(XYVAL, -XYVAL, ZVAL, 1);
46  verts[1].color = conv(0, COLVAL, 0, 0);
47
48  verts[2].pos = iconv(0, XYVAL, ZVAL, 1);
49  verts[2].color = conv(0, 0, COLVAL, 0);
50}
51
52GLuint arrayObj, elementObj;
53
54static void Init( void )
55{
56   GLint errnum;
57   GLuint prognum;
58   int color_size = 4;
59
60   static const char *prog1 =
61      "!!ARBvp1.0\n"
62      "PARAM mvp[4] = {state.matrix.mvp};\n"
63      "DP4 result.position.x, vertex.position, mvp[0]; \n"
64      "DP4 result.position.y, vertex.position, mvp[1]; \n"
65      "DP4 result.position.z, vertex.position, mvp[2]; \n"
66      "DP4 result.position.w, vertex.position, mvp[3]; \n"
67      "MOV  result.color, vertex.color;\n"
68      "END\n";
69
70#ifndef GL_ARB_vertex_type_2_10_10_10_rev
71   fprintf(stderr,"built without ARB_vertex_type_2_10_10_10_rev\n");
72   exit(1);
73#endif
74
75  if (!glutExtensionSupported("GL_ARB_vertex_type_2_10_10_10_rev")){
76     fprintf(stderr,"requires ARB_vertex_type_2_10_10_10_rev\n");
77     exit(1);
78   }
79
80   glGenProgramsARB(1, &prognum);
81   glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum);
82   glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
83		      strlen(prog1), (const GLubyte *) prog1);
84
85   assert(glIsProgramARB(prognum));
86   errnum = glGetError();
87
88   if (errnum != GL_NO_ERROR)
89   {
90      GLint errorpos;
91
92      glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos);
93      printf("errorpos: %d\n", errorpos);
94      printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB));
95   }
96
97
98   glEnableClientState( GL_VERTEX_ARRAY );
99   glEnableClientState( GL_COLOR_ARRAY );
100
101   SetupVerts();
102
103   glGenBuffersARB(1, &arrayObj);
104   glBindBufferARB(GL_ARRAY_BUFFER_ARB, arrayObj);
105   glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, GL_STATIC_DRAW_ARB);
106
107   if (bgra)
108     color_size = GL_BGRA;
109
110#ifdef GL_ARB_vertex_type_2_10_10_10_rev
111   glVertexPointer( 4, GL_INT_2_10_10_10_REV, sizeof(verts[0]), 0 );
112   glColorPointer( color_size, GL_UNSIGNED_INT_2_10_10_10_REV, sizeof(verts[0]), (void *)(sizeof(unsigned int)) );
113#endif
114}
115
116
117
118static void Display( void )
119{
120   glClearColor(0.3, 0.3, 0.3, 1);
121   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
122
123   glEnable(GL_VERTEX_PROGRAM_ARB);
124
125   glDrawArrays( GL_TRIANGLES, 0, 3 );
126
127   glFlush();
128}
129
130
131static void Reshape( int width, int height )
132{
133   glViewport( 0, 0, width, height );
134   glMatrixMode( GL_PROJECTION );
135   glLoadIdentity();
136   glOrtho(-100.0, 100.0, -100.0, 100.0, -0.5, 1000.0);
137   glMatrixMode( GL_MODELVIEW );
138   glLoadIdentity();
139}
140
141
142static void Key( unsigned char key, int x, int y )
143{
144   (void) x;
145   (void) y;
146   switch (key) {
147      case 27:
148         exit(0);
149         break;
150   }
151   glutPostRedisplay();
152}
153
154static GLenum Args(int argc, char **argv)
155{
156   GLint i;
157
158   for (i = 1; i < argc; i++) {
159      if (strcmp(argv[i], "-bgra") == 0) {
160 	 bgra = GL_TRUE;
161      } else {
162         fprintf(stderr, "%s (Bad option).\n", argv[i]);
163         return GL_FALSE;
164      }
165   }
166   return GL_TRUE;
167}
168
169int main( int argc, char *argv[] )
170{
171   glutInit( &argc, argv );
172
173   if (Args(argc, argv) == GL_FALSE) {
174      exit(1);
175   }
176
177   glutInitWindowPosition( 0, 0 );
178   glutInitWindowSize( 250, 250 );
179   glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );
180   glutCreateWindow(argv[0]);
181   glewInit();
182   glutReshapeFunc( Reshape );
183   glutKeyboardFunc( Key );
184   glutDisplayFunc( Display );
185
186   glewInit();
187   Init();
188   glutMainLoop();
189   return 0;
190}
191