132001f49Smrg/* Copyright (c) 2011 Dave Airlie
232001f49Smrg   based on vbo-drawarrays.c, which should be MIT licensed */
332001f49Smrg
432001f49Smrg/* Basic VBO testing ARB_vertex_type_2_10_10_10_rev */
532001f49Smrg
632001f49Smrg#include <assert.h>
732001f49Smrg#include <string.h>
832001f49Smrg#include <stdio.h>
932001f49Smrg#include <stdlib.h>
1032001f49Smrg#include <math.h>
1132001f49Smrg#include <GL/glew.h>
1232001f49Smrg#include "glut_wrap.h"
1332001f49Smrg
1432001f49SmrgGLboolean bgra = GL_FALSE;
1532001f49Smrg#define i32to10(x) ((x) >= 0 ? (x & 0x1ff) : 1024-(abs((x))& 0x1ff))
1632001f49Smrg#define i32to2(x) ((x) >= 0 ? (x & 0x1) : 3-abs((x)))
1732001f49Smrg
1832001f49Smrgstatic unsigned iconv(int x, int y, int z, int w)
1932001f49Smrg{
2032001f49Smrg	unsigned val;
2132001f49Smrg
2232001f49Smrg	val = i32to10(x);
2332001f49Smrg	val |= i32to10(y) << 10;
2432001f49Smrg	val |= i32to10(z) << 20;
2532001f49Smrg	val |= i32to2(w) << 30;
2632001f49Smrg	return val;
2732001f49Smrg}
2832001f49Smrg#define conv(x,y,z,w) (((x) & 0x3ff) | ((y) & 0x3ff) << 10 | ((z) & 0x3ff)<< 20 | ((w) & 0x3) << 30)
2932001f49Smrg
3032001f49Smrgstruct {
3132001f49Smrg   GLuint pos;
3232001f49Smrg   GLuint color;
3332001f49Smrg} verts[3];
3432001f49Smrg
3532001f49Smrg#define XYVAL 90
3632001f49Smrg#define ZVAL -30
3732001f49Smrg
3832001f49Smrg#define COLVAL 820
3932001f49Smrg
4032001f49Smrgstatic void SetupVerts(void)
4132001f49Smrg{
4232001f49Smrg  verts[0].pos = iconv(-XYVAL, -XYVAL, ZVAL, 1);
4332001f49Smrg  verts[0].color = conv(COLVAL, 0, 0, 0);
4432001f49Smrg
4532001f49Smrg  verts[1].pos = iconv(XYVAL, -XYVAL, ZVAL, 1);
4632001f49Smrg  verts[1].color = conv(0, COLVAL, 0, 0);
4732001f49Smrg
4832001f49Smrg  verts[2].pos = iconv(0, XYVAL, ZVAL, 1);
4932001f49Smrg  verts[2].color = conv(0, 0, COLVAL, 0);
5032001f49Smrg}
5132001f49Smrg
5232001f49SmrgGLuint arrayObj, elementObj;
5332001f49Smrg
5432001f49Smrgstatic void Init( void )
5532001f49Smrg{
567ec3b29aSmrg   GLint errnum;
5732001f49Smrg   GLuint prognum;
5832001f49Smrg   int color_size = 4;
5932001f49Smrg
6032001f49Smrg   static const char *prog1 =
6132001f49Smrg      "!!ARBvp1.0\n"
6232001f49Smrg      "PARAM mvp[4] = {state.matrix.mvp};\n"
6332001f49Smrg      "DP4 result.position.x, vertex.position, mvp[0]; \n"
6432001f49Smrg      "DP4 result.position.y, vertex.position, mvp[1]; \n"
6532001f49Smrg      "DP4 result.position.z, vertex.position, mvp[2]; \n"
6632001f49Smrg      "DP4 result.position.w, vertex.position, mvp[3]; \n"
6732001f49Smrg      "MOV  result.color, vertex.color;\n"
6832001f49Smrg      "END\n";
6932001f49Smrg
7032001f49Smrg#ifndef GL_ARB_vertex_type_2_10_10_10_rev
7132001f49Smrg   fprintf(stderr,"built without ARB_vertex_type_2_10_10_10_rev\n");
7232001f49Smrg   exit(1);
7332001f49Smrg#endif
7432001f49Smrg
7532001f49Smrg  if (!glutExtensionSupported("GL_ARB_vertex_type_2_10_10_10_rev")){
7632001f49Smrg     fprintf(stderr,"requires ARB_vertex_type_2_10_10_10_rev\n");
7732001f49Smrg     exit(1);
7832001f49Smrg   }
7932001f49Smrg
8032001f49Smrg   glGenProgramsARB(1, &prognum);
8132001f49Smrg   glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum);
8232001f49Smrg   glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
8332001f49Smrg		      strlen(prog1), (const GLubyte *) prog1);
8432001f49Smrg
8532001f49Smrg   assert(glIsProgramARB(prognum));
867ec3b29aSmrg   errnum = glGetError();
8732001f49Smrg
887ec3b29aSmrg   if (errnum != GL_NO_ERROR)
8932001f49Smrg   {
9032001f49Smrg      GLint errorpos;
9132001f49Smrg
9232001f49Smrg      glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos);
9332001f49Smrg      printf("errorpos: %d\n", errorpos);
9432001f49Smrg      printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB));
9532001f49Smrg   }
9632001f49Smrg
9732001f49Smrg
9832001f49Smrg   glEnableClientState( GL_VERTEX_ARRAY );
9932001f49Smrg   glEnableClientState( GL_COLOR_ARRAY );
10032001f49Smrg
10132001f49Smrg   SetupVerts();
10232001f49Smrg
10332001f49Smrg   glGenBuffersARB(1, &arrayObj);
10432001f49Smrg   glBindBufferARB(GL_ARRAY_BUFFER_ARB, arrayObj);
10532001f49Smrg   glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts, GL_STATIC_DRAW_ARB);
10632001f49Smrg
10732001f49Smrg   if (bgra)
10832001f49Smrg     color_size = GL_BGRA;
10932001f49Smrg
11032001f49Smrg#ifdef GL_ARB_vertex_type_2_10_10_10_rev
11132001f49Smrg   glVertexPointer( 4, GL_INT_2_10_10_10_REV, sizeof(verts[0]), 0 );
11232001f49Smrg   glColorPointer( color_size, GL_UNSIGNED_INT_2_10_10_10_REV, sizeof(verts[0]), (void *)(sizeof(unsigned int)) );
11332001f49Smrg#endif
11432001f49Smrg}
11532001f49Smrg
11632001f49Smrg
11732001f49Smrg
11832001f49Smrgstatic void Display( void )
11932001f49Smrg{
12032001f49Smrg   glClearColor(0.3, 0.3, 0.3, 1);
12132001f49Smrg   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
12232001f49Smrg
12332001f49Smrg   glEnable(GL_VERTEX_PROGRAM_ARB);
12432001f49Smrg
12532001f49Smrg   glDrawArrays( GL_TRIANGLES, 0, 3 );
12632001f49Smrg
12732001f49Smrg   glFlush();
12832001f49Smrg}
12932001f49Smrg
13032001f49Smrg
13132001f49Smrgstatic void Reshape( int width, int height )
13232001f49Smrg{
13332001f49Smrg   glViewport( 0, 0, width, height );
13432001f49Smrg   glMatrixMode( GL_PROJECTION );
13532001f49Smrg   glLoadIdentity();
13632001f49Smrg   glOrtho(-100.0, 100.0, -100.0, 100.0, -0.5, 1000.0);
13732001f49Smrg   glMatrixMode( GL_MODELVIEW );
13832001f49Smrg   glLoadIdentity();
13932001f49Smrg}
14032001f49Smrg
14132001f49Smrg
14232001f49Smrgstatic void Key( unsigned char key, int x, int y )
14332001f49Smrg{
14432001f49Smrg   (void) x;
14532001f49Smrg   (void) y;
14632001f49Smrg   switch (key) {
14732001f49Smrg      case 27:
14832001f49Smrg         exit(0);
14932001f49Smrg         break;
15032001f49Smrg   }
15132001f49Smrg   glutPostRedisplay();
15232001f49Smrg}
15332001f49Smrg
15432001f49Smrgstatic GLenum Args(int argc, char **argv)
15532001f49Smrg{
15632001f49Smrg   GLint i;
15732001f49Smrg
15832001f49Smrg   for (i = 1; i < argc; i++) {
15932001f49Smrg      if (strcmp(argv[i], "-bgra") == 0) {
16032001f49Smrg 	 bgra = GL_TRUE;
16132001f49Smrg      } else {
16232001f49Smrg         fprintf(stderr, "%s (Bad option).\n", argv[i]);
16332001f49Smrg         return GL_FALSE;
16432001f49Smrg      }
16532001f49Smrg   }
16632001f49Smrg   return GL_TRUE;
16732001f49Smrg}
16832001f49Smrg
16932001f49Smrgint main( int argc, char *argv[] )
17032001f49Smrg{
17132001f49Smrg   glutInit( &argc, argv );
17232001f49Smrg
17332001f49Smrg   if (Args(argc, argv) == GL_FALSE) {
17432001f49Smrg      exit(1);
17532001f49Smrg   }
17632001f49Smrg
17732001f49Smrg   glutInitWindowPosition( 0, 0 );
17832001f49Smrg   glutInitWindowSize( 250, 250 );
17932001f49Smrg   glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );
18032001f49Smrg   glutCreateWindow(argv[0]);
18132001f49Smrg   glewInit();
18232001f49Smrg   glutReshapeFunc( Reshape );
18332001f49Smrg   glutKeyboardFunc( Key );
18432001f49Smrg   glutDisplayFunc( Display );
18532001f49Smrg
18632001f49Smrg   glewInit();
18732001f49Smrg   Init();
18832001f49Smrg   glutMainLoop();
18932001f49Smrg   return 0;
19032001f49Smrg}
191