Clone of mesa.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

interleave.c 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /*
  2. * (C) Copyright IBM Corporation 2005
  3. * All Rights Reserved.
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a
  6. * copy of this software and associated documentation files (the "Software"),
  7. * to deal in the Software without restriction, including without limitation
  8. * on the rights to use, copy, modify, merge, publish, distribute, sub
  9. * license, and/or sell copies of the Software, and to permit persons to whom
  10. * the Software is furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice (including the next
  13. * paragraph) shall be included in all copies or substantial portions of the
  14. * Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  19. * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
  20. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22. * USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. */
  24. /**
  25. * \file interleave.c
  26. *
  27. * Simple test of glInterleavedArrays functionality. For each mode, two
  28. * meshes are drawn. One is drawn using interleaved arrays and the othe is
  29. * drawn using immediate mode. Both should look identical.
  30. *
  31. * \author Ian Romanick <idr@us.ibm.com>
  32. */
  33. #include <stdio.h>
  34. #include <stdlib.h>
  35. #include <string.h>
  36. #include <time.h>
  37. #include <GL/glut.h>
  38. static int Width = 400;
  39. static int Height = 300;
  40. static const GLfloat Near = 5.0, Far = 25.0;
  41. static const GLfloat t[][4] = {
  42. { 0.5, 0.0, 0.0, 1.0 },
  43. { 0.25, 0.5, 0.0, 1.0 },
  44. { 0.75, 0.5, 0.0, 1.0 },
  45. { 0.0, 1.0, 0.0, 1.0 },
  46. { 0.5, 1.0, 0.0, 1.0 },
  47. { 1.0, 1.0, 0.0, 1.0 },
  48. };
  49. static const GLfloat c_f[][4] = {
  50. { 1.0, 0.0, 0.0, 1.0 },
  51. { 0.0, 1.0, 0.0, 1.0 },
  52. { 0.0, 1.0, 0.0, 1.0 },
  53. { 0.0, 0.0, 1.0, 1.0 },
  54. { 1.0, 0.0, 1.0, 1.0 },
  55. { 0.0, 0.0, 1.0, 1.0 },
  56. };
  57. static const GLubyte c_ub[][4] = {
  58. { 0xff, 0x00, 0x00, 0xff },
  59. { 0x00, 0xff, 0x00, 0xff },
  60. { 0x00, 0xff, 0x00, 0xff },
  61. { 0x00, 0x00, 0xff, 0xff },
  62. { 0xff, 0x00, 0xff, 0xff },
  63. { 0x00, 0x00, 0xff, 0xff },
  64. };
  65. static const GLfloat n[][3] = {
  66. { 0.0, 0.0, -1.0 },
  67. { 0.0, 0.0, -1.0 },
  68. { 0.0, 0.0, -1.0 },
  69. { 0.0, 0.0, -1.0 },
  70. { 0.0, 0.0, -1.0 },
  71. { 0.0, 0.0, -1.0 },
  72. };
  73. static const GLfloat v[][4] = {
  74. { 0.0, 1.0, 0.0, 1.0, },
  75. { -0.5, 0.0, 0.0, 1.0, },
  76. { 0.5, 0.0, 0.0, 1.0, },
  77. { -1.0, -1.0, 0.0, 1.0, },
  78. { 0.0, -1.0, 0.0, 1.0, },
  79. { 1.0, -1.0, 0.0, 1.0, },
  80. };
  81. static const unsigned indicies[12] = {
  82. 0, 1, 2,
  83. 1, 3, 4,
  84. 2, 4, 5,
  85. 1, 4, 2
  86. };
  87. #define NONE { NULL, 0, 0, 0 }
  88. #define V2F { v, 2, 2 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) }
  89. #define V3F { v, 3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) }
  90. #define V4F { v, 4, 4 * sizeof( GLfloat ), GL_FLOAT, sizeof( v[0] ) }
  91. #define C4UB { c_ub, 4, 4 * sizeof( GLubyte ), GL_UNSIGNED_BYTE, sizeof( c_ub[0] ) }
  92. #define C3F { c_f, 3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( c_f[0] ) }
  93. #define C4F { c_f, 4, 4 * sizeof( GLfloat ), GL_FLOAT, sizeof( c_f[0] ) }
  94. #define T2F { t, 2, 2 * sizeof( GLfloat ), GL_FLOAT, sizeof( t[0] ) }
  95. #define T4F { t, 4, 4 * sizeof( GLfloat ), GL_FLOAT, sizeof( t[0] ) }
  96. #define N3F { n, 3, 3 * sizeof( GLfloat ), GL_FLOAT, sizeof( n[0] ) }
  97. struct interleave_info {
  98. const void * data;
  99. unsigned count;
  100. unsigned size;
  101. GLenum type;
  102. unsigned stride;
  103. };
  104. #define NUM_MODES 14
  105. #define INVALID_MODE 14
  106. #define INVALID_STRIDE 15
  107. struct interleave_info info[ NUM_MODES ][4] = {
  108. { NONE, NONE, NONE, V2F },
  109. { NONE, NONE, NONE, V3F },
  110. { NONE, C4UB, NONE, V2F },
  111. { NONE, C4UB, NONE, V3F },
  112. { NONE, C3F, NONE, V3F },
  113. { NONE, NONE, N3F, V3F },
  114. { NONE, C4F, N3F, V3F },
  115. { T2F, NONE, NONE, V3F },
  116. { T4F, NONE, NONE, V4F },
  117. { T2F, C4UB, NONE, V3F },
  118. { T2F, C3F, NONE, V3F },
  119. { T2F, NONE, N3F, V3F },
  120. { T2F, C4F, N3F, V3F },
  121. { T4F, C4F, N3F, V4F },
  122. };
  123. const char * const mode_names[ NUM_MODES ] = {
  124. "GL_V2F",
  125. "GL_V3F",
  126. "GL_C4UB_V2F",
  127. "GL_C4UB_V3F",
  128. "GL_C3F_V3F",
  129. "GL_N3F_V3F",
  130. "GL_C4F_N3F_V3F",
  131. "GL_T2F_V3F",
  132. "GL_T4F_V4F",
  133. "GL_T2F_C4UB_V3F",
  134. "GL_T2F_C3F_V3F",
  135. "GL_T2F_N3F_V3F",
  136. "GL_T2F_C4F_N3F_V3F",
  137. "GL_T4F_C4F_N3F_V4F",
  138. };
  139. static unsigned interleave_mode = 0;
  140. static GLboolean use_invalid_mode = GL_FALSE;
  141. static GLboolean use_invalid_stride = GL_FALSE;
  142. #define DEREF(item,idx) (void *) & ((char *)curr_info[item].data)[idx * curr_info[item].stride]
  143. static void Display( void )
  144. {
  145. const struct interleave_info * const curr_info = info[ interleave_mode ];
  146. /* 4 floats for 12 verticies for 4 data elements.
  147. */
  148. char data[ (sizeof( GLfloat ) * 4) * 12 * 4 ];
  149. unsigned i;
  150. unsigned offset;
  151. GLenum err;
  152. GLenum format;
  153. GLsizei stride;
  154. glClearColor(0.2, 0.2, 0.8, 0);
  155. glClear( GL_COLOR_BUFFER_BIT );
  156. glPushMatrix();
  157. glTranslatef(-1.5, 0, 0);
  158. glColor3fv( c_f[0] );
  159. if ( curr_info[0].data != NULL ) {
  160. glEnable( GL_TEXTURE_2D );
  161. }
  162. else {
  163. glDisable( GL_TEXTURE_2D );
  164. }
  165. offset = 0;
  166. glBegin(GL_TRIANGLES);
  167. for ( i = 0 ; i < 12 ; i++ ) {
  168. const unsigned index = indicies[i];
  169. /* Handle the vertex texture coordinate.
  170. */
  171. if ( curr_info[0].data != NULL ) {
  172. if ( curr_info[0].count == 2 ) {
  173. glTexCoord2fv( DEREF(0, index) );
  174. }
  175. else {
  176. glTexCoord4fv( DEREF(0, index) );
  177. }
  178. (void) memcpy( & data[ offset ], DEREF(0, index),
  179. curr_info[0].size );
  180. offset += curr_info[0].size;
  181. }
  182. /* Handle the vertex color.
  183. */
  184. if ( curr_info[1].data != NULL ) {
  185. if ( curr_info[1].type == GL_FLOAT ) {
  186. if ( curr_info[1].count == 3 ) {
  187. glColor3fv( DEREF(1, index) );
  188. }
  189. else {
  190. glColor4fv( DEREF(1, index) );
  191. }
  192. }
  193. else {
  194. glColor4ubv( DEREF(1, index) );
  195. }
  196. (void) memcpy( & data[ offset ], DEREF(1, index),
  197. curr_info[1].size );
  198. offset += curr_info[1].size;
  199. }
  200. /* Handle the vertex normal.
  201. */
  202. if ( curr_info[2].data != NULL ) {
  203. glNormal3fv( DEREF(2, index) );
  204. (void) memcpy( & data[ offset ], DEREF(2, index),
  205. curr_info[2].size );
  206. offset += curr_info[2].size;
  207. }
  208. switch( curr_info[3].count ) {
  209. case 2:
  210. glVertex2fv( DEREF(3, index) );
  211. break;
  212. case 3:
  213. glVertex3fv( DEREF(3, index) );
  214. break;
  215. case 4:
  216. glVertex4fv( DEREF(3, index) );
  217. break;
  218. }
  219. (void) memcpy( & data[ offset ], DEREF(3, index),
  220. curr_info[3].size );
  221. offset += curr_info[3].size;
  222. }
  223. glEnd();
  224. glTranslatef(3.0, 0, 0);
  225. format = (use_invalid_mode)
  226. ? (rand() & ~0x2A00) : GL_V2F + interleave_mode;
  227. stride = (use_invalid_stride) ? -abs(rand()) : 0;
  228. (void) glGetError();
  229. glInterleavedArrays( format, 0, data );
  230. err = glGetError();
  231. if ( err ) {
  232. printf("glInterleavedArrays(0x%04x, %d, %p) generated the error 0x%04x\n",
  233. format, stride, data, err );
  234. }
  235. else {
  236. glDrawArrays( GL_TRIANGLES, 0, 12 );
  237. }
  238. glPopMatrix();
  239. glutSwapBuffers();
  240. }
  241. static void Reshape( int width, int height )
  242. {
  243. GLfloat ar = (float) width / (float) height;
  244. Width = width;
  245. Height = height;
  246. glViewport( 0, 0, width, height );
  247. glMatrixMode( GL_PROJECTION );
  248. glLoadIdentity();
  249. glFrustum( -ar, ar, -1.0, 1.0, Near, Far );
  250. glMatrixMode( GL_MODELVIEW );
  251. glLoadIdentity();
  252. glTranslatef( 0.0, 0.0, -15.0 );
  253. }
  254. static void Key( unsigned char key, int x, int y )
  255. {
  256. (void) x;
  257. (void) y;
  258. switch (key) {
  259. case 27:
  260. exit(0);
  261. break;
  262. }
  263. glutPostRedisplay();
  264. }
  265. static void ModeMenu( int entry )
  266. {
  267. if ( entry == INVALID_MODE ) {
  268. use_invalid_mode = GL_TRUE;
  269. use_invalid_stride = GL_FALSE;
  270. }
  271. else if ( entry == INVALID_STRIDE ) {
  272. use_invalid_mode = GL_FALSE;
  273. use_invalid_stride = GL_TRUE;
  274. }
  275. else {
  276. use_invalid_mode = GL_FALSE;
  277. use_invalid_stride = GL_FALSE;
  278. interleave_mode = entry;
  279. }
  280. }
  281. static void Init( void )
  282. {
  283. const char * const ver_string = (const char * const)
  284. glGetString( GL_VERSION );
  285. const GLubyte tex[16] = {
  286. 0xff, 0x00, 0xff, 0x00,
  287. 0x00, 0xff, 0x00, 0xff,
  288. 0xff, 0x00, 0xff, 0x00,
  289. 0x00, 0xff, 0x00, 0xff,
  290. };
  291. printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
  292. printf("GL_VERSION = %s\n", ver_string);
  293. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  294. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  295. glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
  296. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0,
  297. GL_LUMINANCE, GL_UNSIGNED_BYTE, tex );
  298. printf("Use the context menu (right click) to select the interleaved array mode.\n");
  299. printf("Press ESCAPE to exit.\n\n");
  300. printf("NOTE: This is *NOT* a very good test of the modes that use normals.\n");
  301. }
  302. int main( int argc, char *argv[] )
  303. {
  304. unsigned i;
  305. srand( time( NULL ) );
  306. glutInit( &argc, argv );
  307. glutInitWindowPosition( 0, 0 );
  308. glutInitWindowSize( Width, Height );
  309. glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
  310. glutCreateWindow( "glInterleavedArrays test" );
  311. glutReshapeFunc( Reshape );
  312. glutKeyboardFunc( Key );
  313. glutDisplayFunc( Display );
  314. glutCreateMenu( ModeMenu );
  315. for ( i = 0 ; i < NUM_MODES ; i++ ) {
  316. glutAddMenuEntry( mode_names[i], i);
  317. }
  318. glutAddMenuEntry( "Random invalid mode", INVALID_MODE);
  319. glutAddMenuEntry( "Random invalid stride", INVALID_STRIDE);
  320. glutAttachMenu(GLUT_RIGHT_BUTTON);
  321. Init();
  322. glutMainLoop();
  323. return 0;
  324. }