Advertisement
Guest User

Untitled

a guest
Feb 7th, 2012
523
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.94 KB | None | 0 0
  1. /*
  2. * Copyright (c) 2012 Broadcom Europe Ltd
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one or more
  5. * contributor license agreements. See the NOTICE file distributed with
  6. * this work for additional information regarding copyright ownership.
  7. * The ASF licenses this file to You under the Apache License, Version 2.0
  8. * (the "License"); you may not use this file except in compliance with
  9. * the License. You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. *
  20. * A rotating cube rendered with OpenGL|ES. Three images used as textures on the cube faces.
  21. */
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26. #include <math.h>
  27. #include <assert.h>
  28. #include <unistd.h>
  29.  
  30. #include "bcm_host.h"
  31.  
  32. #include "GLES/gl.h"
  33. #include "EGL/egl.h"
  34. #include "EGL/eglext.h"
  35.  
  36. #include "cube_texture_and_coords.h"
  37.  
  38. #define PATH "./"
  39.  
  40. #define IMAGE_SIZE 128
  41.  
  42. #ifndef M_PI
  43. #define M_PI 3.141592654
  44. #endif
  45.  
  46.  
  47. typedef struct
  48. {
  49. uint32_t screen_width;
  50. uint32_t screen_height;
  51. // OpenGL|ES objects
  52. EGLDisplay display;
  53. EGLSurface surface;
  54. EGLContext context;
  55. GLuint tex[6];
  56. // model rotation vector and direction
  57. GLfloat rot_angle_x_inc;
  58. GLfloat rot_angle_y_inc;
  59. GLfloat rot_angle_z_inc;
  60. // current model rotation angles
  61. GLfloat rot_angle_x;
  62. GLfloat rot_angle_y;
  63. GLfloat rot_angle_z;
  64. // current distance from camera
  65. GLfloat distance;
  66. GLfloat distance_inc;
  67. // pointers to texture buffers
  68. char *tex_buf1;
  69. char *tex_buf2;
  70. char *tex_buf3;
  71. } CUBE_STATE_T;
  72.  
  73. static void init_ogl(CUBE_STATE_T *state);
  74. static void init_model_proj(CUBE_STATE_T *state);
  75. static void reset_model(CUBE_STATE_T *state);
  76. static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc);
  77. static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc);
  78. static void redraw_scene(CUBE_STATE_T *state);
  79. static void update_model(CUBE_STATE_T *state);
  80. static void init_textures(CUBE_STATE_T *state);
  81. static void load_tex_images(CUBE_STATE_T *state);
  82. static void exit_func(void);
  83. static volatile int terminate;
  84. static CUBE_STATE_T _state, *state=&_state;
  85.  
  86.  
  87. /***********************************************************
  88. * Name: init_ogl
  89. *
  90. * Arguments:
  91. * CUBE_STATE_T *state - holds OGLES model info
  92. *
  93. * Description: Sets the display, OpenGL|ES context and screen stuff
  94. *
  95. * Returns: void
  96. *
  97. ***********************************************************/
  98. static void init_ogl(CUBE_STATE_T *state)
  99. {
  100. int32_t success = 0;
  101. EGLBoolean result;
  102. EGLint num_config;
  103.  
  104. static EGL_DISPMANX_WINDOW_T nativewindow;
  105.  
  106. DISPMANX_ELEMENT_HANDLE_T dispman_element;
  107. DISPMANX_DISPLAY_HANDLE_T dispman_display;
  108. DISPMANX_UPDATE_HANDLE_T dispman_update;
  109. VC_RECT_T dst_rect;
  110. VC_RECT_T src_rect;
  111.  
  112. static const EGLint attribute_list[] =
  113. {
  114. EGL_RED_SIZE, 8,
  115. EGL_GREEN_SIZE, 8,
  116. EGL_BLUE_SIZE, 8,
  117. EGL_ALPHA_SIZE, 8,
  118. EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  119. EGL_NONE
  120. };
  121.  
  122. EGLConfig config;
  123.  
  124. // get an EGL display connection
  125. state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  126. assert(state->display!=EGL_NO_DISPLAY);
  127.  
  128. // initialize the EGL display connection
  129. result = eglInitialize(state->display, NULL, NULL);
  130. assert(EGL_FALSE != result);
  131.  
  132. // get an appropriate EGL frame buffer configuration
  133. result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
  134. assert(EGL_FALSE != result);
  135.  
  136. // create an EGL rendering context
  137. state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL);
  138. assert(state->context!=EGL_NO_CONTEXT);
  139.  
  140. // create an EGL window surface
  141. success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
  142. assert( success >= 0 );
  143.  
  144. dst_rect.x = 0;
  145. dst_rect.y = 0;
  146. dst_rect.width = state->screen_width;
  147. dst_rect.height = state->screen_height;
  148.  
  149. src_rect.x = 0;
  150. src_rect.y = 0;
  151. src_rect.width = state->screen_width << 16;
  152. src_rect.height = state->screen_height << 16;
  153.  
  154. dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
  155. dispman_update = vc_dispmanx_update_start( 0 );
  156.  
  157. dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
  158. 0/*layer*/, &dst_rect, 0/*src*/,
  159. &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);
  160.  
  161. nativewindow.element = dispman_element;
  162. nativewindow.width = state->screen_width;
  163. nativewindow.height = state->screen_height;
  164. vc_dispmanx_update_submit_sync( dispman_update );
  165.  
  166. state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
  167. assert(state->surface != EGL_NO_SURFACE);
  168.  
  169. // connect the context to the surface
  170. result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
  171. assert(EGL_FALSE != result);
  172.  
  173. // Set background color and clear buffers
  174. glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
  175. glClear( GL_COLOR_BUFFER_BIT );
  176. glClear( GL_DEPTH_BUFFER_BIT );
  177. glShadeModel(GL_FLAT);
  178.  
  179. // Enable back face culling.
  180. glEnable(GL_CULL_FACE);
  181. }
  182.  
  183. /***********************************************************
  184. * Name: init_model_proj
  185. *
  186. * Arguments:
  187. * CUBE_STATE_T *state - holds OGLES model info
  188. *
  189. * Description: Sets the OpenGL|ES model to default values
  190. *
  191. * Returns: void
  192. *
  193. ***********************************************************/
  194. static void init_model_proj(CUBE_STATE_T *state)
  195. {
  196. float nearp = 1.0f;
  197. float farp = 500.0f;
  198. float hht;
  199. float hwd;
  200.  
  201. glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
  202.  
  203. glViewport(0, 0, (GLsizei)state->screen_width, (GLsizei)state->screen_height);
  204.  
  205. glMatrixMode(GL_PROJECTION);
  206. glLoadIdentity();
  207.  
  208. hht = nearp * (float)tan(45.0 / 2.0 / 180.0 * M_PI);
  209. hwd = hht * (float)state->screen_width / (float)state->screen_height;
  210.  
  211. glFrustumf(-hwd, hwd, -hht, hht, nearp, farp);
  212.  
  213. glEnableClientState( GL_VERTEX_ARRAY );
  214. glVertexPointer( 3, GL_BYTE, 0, quadx );
  215.  
  216. glEnableClientState( GL_COLOR_ARRAY );
  217. glColorPointer(4, GL_FLOAT, 0, colorsf);
  218.  
  219. reset_model(state);
  220. }
  221.  
  222. /***********************************************************
  223. * Name: reset_model
  224. *
  225. * Arguments:
  226. * CUBE_STATE_T *state - holds OGLES model info
  227. *
  228. * Description: Resets the Model projection and rotation direction
  229. *
  230. * Returns: void
  231. *
  232. ***********************************************************/
  233. static void reset_model(CUBE_STATE_T *state)
  234. {
  235. // reset model position
  236. glMatrixMode(GL_MODELVIEW);
  237. glLoadIdentity();
  238. glTranslatef(0.f, 0.f, -50.f);
  239.  
  240. // reset model rotation
  241. state->rot_angle_x = 45.f; state->rot_angle_y = 30.f; state->rot_angle_z = 0.f;
  242. state->rot_angle_x_inc = 0.5f; state->rot_angle_y_inc = 0.5f; state->rot_angle_z_inc = 0.f;
  243. state->distance = 40.f;
  244. }
  245.  
  246. /***********************************************************
  247. * Name: update_model
  248. *
  249. * Arguments:
  250. * CUBE_STATE_T *state - holds OGLES model info
  251. *
  252. * Description: Updates model projection to current position/rotation
  253. *
  254. * Returns: void
  255. *
  256. ***********************************************************/
  257. static void update_model(CUBE_STATE_T *state)
  258. {
  259. // update position
  260. state->rot_angle_x = inc_and_wrap_angle(state->rot_angle_x, state->rot_angle_x_inc);
  261. state->rot_angle_y = inc_and_wrap_angle(state->rot_angle_y, state->rot_angle_y_inc);
  262. state->rot_angle_z = inc_and_wrap_angle(state->rot_angle_z, state->rot_angle_z_inc);
  263. state->distance = inc_and_clip_distance(state->distance, state->distance_inc);
  264.  
  265. glLoadIdentity();
  266. // move camera back to see the cube
  267. glTranslatef(0.f, 0.f, -state->distance);
  268.  
  269. // Rotate model to new position
  270. glRotatef(state->rot_angle_x, 1.f, 0.f, 0.f);
  271. glRotatef(state->rot_angle_y, 0.f, 1.f, 0.f);
  272. glRotatef(state->rot_angle_z, 0.f, 0.f, 1.f);
  273. }
  274.  
  275. /***********************************************************
  276. * Name: inc_and_wrap_angle
  277. *
  278. * Arguments:
  279. * GLfloat angle current angle
  280. * GLfloat angle_inc angle increment
  281. *
  282. * Description: Increments or decrements angle by angle_inc degrees
  283. * Wraps to 0 at 360 deg.
  284. *
  285. * Returns: new value of angle
  286. *
  287. ***********************************************************/
  288. static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc)
  289. {
  290. angle += angle_inc;
  291.  
  292. if (angle >= 360.0)
  293. angle -= 360.f;
  294. else if (angle <=0)
  295. angle += 360.f;
  296.  
  297. return angle;
  298. }
  299.  
  300. /***********************************************************
  301. * Name: inc_and_clip_distance
  302. *
  303. * Arguments:
  304. * GLfloat distance current distance
  305. * GLfloat distance_inc distance increment
  306. *
  307. * Description: Increments or decrements distance by distance_inc units
  308. * Clips to range
  309. *
  310. * Returns: new value of angle
  311. *
  312. ***********************************************************/
  313. static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc)
  314. {
  315. distance += distance_inc;
  316.  
  317. if (distance >= 120.0f)
  318. distance = 120.f;
  319. else if (distance <= 40.0f)
  320. distance = 40.0f;
  321.  
  322. return distance;
  323. }
  324.  
  325. /***********************************************************
  326. * Name: redraw_scene
  327. *
  328. * Arguments:
  329. * CUBE_STATE_T *state - holds OGLES model info
  330. *
  331. * Description: Draws the model and calls eglSwapBuffers
  332. * to render to screen
  333. *
  334. * Returns: void
  335. *
  336. ***********************************************************/
  337. static void redraw_scene(CUBE_STATE_T *state)
  338. {
  339. // Start with a clear screen
  340. glClear( GL_COLOR_BUFFER_BIT );
  341. glMatrixMode(GL_MODELVIEW);
  342.  
  343. glEnable(GL_TEXTURE_2D);
  344. glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  345.  
  346. // Draw first (front) face:
  347. // Bind texture surface to current vertices
  348. glBindTexture(GL_TEXTURE_2D, state->tex[0]);
  349.  
  350. // Need to rotate textures - do this by rotating each cube face
  351. glRotatef(270.f, 0.f, 0.f, 1.f ); // front face normal along z axis
  352.  
  353. // draw first 4 vertices
  354. glDrawArrays( GL_TRIANGLE_STRIP, 0, 4);
  355.  
  356. // same pattern for other 5 faces - rotation chosen to make image orientation 'nice'
  357. glBindTexture(GL_TEXTURE_2D, state->tex[1]);
  358. glRotatef(90.f, 0.f, 0.f, 1.f ); // back face normal along z axis
  359. glDrawArrays( GL_TRIANGLE_STRIP, 4, 4);
  360.  
  361. glBindTexture(GL_TEXTURE_2D, state->tex[2]);
  362. glRotatef(90.f, 1.f, 0.f, 0.f ); // left face normal along x axis
  363. glDrawArrays( GL_TRIANGLE_STRIP, 8, 4);
  364.  
  365. glBindTexture(GL_TEXTURE_2D, state->tex[3]);
  366. glRotatef(90.f, 1.f, 0.f, 0.f ); // right face normal along x axis
  367. glDrawArrays( GL_TRIANGLE_STRIP, 12, 4);
  368.  
  369. glBindTexture(GL_TEXTURE_2D, state->tex[4]);
  370. glRotatef(270.f, 0.f, 1.f, 0.f ); // top face normal along y axis
  371. glDrawArrays( GL_TRIANGLE_STRIP, 16, 4);
  372.  
  373. glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  374.  
  375. glBindTexture(GL_TEXTURE_2D, state->tex[5]);
  376. glRotatef(90.f, 0.f, 1.f, 0.f ); // bottom face normal along y axis
  377. glDrawArrays( GL_TRIANGLE_STRIP, 20, 4);
  378.  
  379. glDisable(GL_TEXTURE_2D);
  380.  
  381. eglSwapBuffers(state->display, state->surface);
  382. }
  383.  
  384. /***********************************************************
  385. * Name: init_textures
  386. *
  387. * Arguments:
  388. * CUBE_STATE_T *state - holds OGLES model info
  389. *
  390. * Description: Initialise OGL|ES texture surfaces to use image
  391. * buffers
  392. *
  393. * Returns: void
  394. *
  395. ***********************************************************/
  396. static void init_textures(CUBE_STATE_T *state)
  397. {
  398. // load three texture buffers but use them on six OGL|ES texture surfaces
  399. load_tex_images(state);
  400. glGenTextures(6, &state->tex[0]);
  401.  
  402. // setup first texture
  403. glBindTexture(GL_TEXTURE_2D, state->tex[0]);
  404. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  405. GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
  406. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  407. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  408.  
  409. // setup second texture - reuse first image
  410. glBindTexture(GL_TEXTURE_2D, state->tex[1]);
  411. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  412. GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
  413. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  414. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  415.  
  416. // third texture
  417. glBindTexture(GL_TEXTURE_2D, state->tex[2]);
  418. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  419. GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
  420. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  421. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  422.  
  423. // fourth texture - reuse second image
  424. glBindTexture(GL_TEXTURE_2D, state->tex[3]);
  425. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  426. GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
  427. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  428. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  429.  
  430. //fifth texture
  431. glBindTexture(GL_TEXTURE_2D, state->tex[4]);
  432. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  433. GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
  434. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  435. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  436.  
  437. // sixth texture - reuse third image
  438. glBindTexture(GL_TEXTURE_2D, state->tex[5]);
  439. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  440. GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
  441. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  442. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  443.  
  444. // setup overall texture environment
  445. glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
  446. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  447. }
  448.  
  449. /***********************************************************
  450. * Name: load_tex_images
  451. *
  452. * Arguments:
  453. * void
  454. *
  455. * Description: Loads three raw images to use as textures on faces
  456. *
  457. * Returns: void
  458. *
  459. ***********************************************************/
  460. static void load_tex_images(CUBE_STATE_T *state)
  461. {
  462. FILE *tex_file1 = NULL, *tex_file2=NULL, *tex_file3 = NULL;
  463. int bytes_read, image_sz = IMAGE_SIZE*IMAGE_SIZE*3;
  464.  
  465. state->tex_buf1 = malloc(image_sz);
  466. state->tex_buf2 = malloc(image_sz);
  467. state->tex_buf3 = malloc(image_sz);
  468.  
  469. tex_file1 = fopen(PATH "Lucca_128_128.raw", "rb");
  470. if (tex_file1 && state->tex_buf1)
  471. {
  472. bytes_read=fread(state->tex_buf1, 1, image_sz, tex_file1);
  473. assert(bytes_read == image_sz); // some problem with file?
  474. fclose(tex_file1);
  475. }
  476.  
  477. tex_file2 = fopen(PATH "Djenne_128_128.raw", "rb");
  478. if (tex_file2 && state->tex_buf2)
  479. {
  480. bytes_read=fread(state->tex_buf2, 1, image_sz, tex_file2);
  481. assert(bytes_read == image_sz); // some problem with file?
  482. fclose(tex_file2);
  483. }
  484.  
  485. tex_file3 = fopen(PATH "Gaudi_128_128.raw", "rb");
  486. if (tex_file3 && state->tex_buf3)
  487. {
  488. bytes_read=fread(state->tex_buf3, 1, image_sz, tex_file3);
  489. assert(bytes_read == image_sz); // some problem with file?
  490. fclose(tex_file3);
  491. }
  492. }
  493.  
  494. //------------------------------------------------------------------------------
  495.  
  496. static void exit_func(void)
  497. // Function to be passed to atexit().
  498. {
  499. // clear screen
  500. glClear( GL_COLOR_BUFFER_BIT );
  501. eglSwapBuffers(state->display, state->surface);
  502.  
  503. // Release OpenGL resources
  504. eglMakeCurrent( state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
  505. eglDestroySurface( state->display, state->surface );
  506. eglDestroyContext( state->display, state->context );
  507. eglTerminate( state->display );
  508.  
  509. // release texture buffers
  510. free(state->tex_buf1);
  511. free(state->tex_buf2);
  512. free(state->tex_buf3);
  513.  
  514. printf("\ncube closed\n");
  515. } // exit_func()
  516.  
  517. //==============================================================================
  518.  
  519. int main ()
  520. {
  521. bcm_host_init();
  522.  
  523. // Clear application state
  524. memset( state, 0, sizeof( *state ) );
  525.  
  526. // Start OGLES
  527. init_ogl(state);
  528.  
  529. // Setup the model world
  530. init_model_proj(state);
  531.  
  532. // initialise the OGLES texture(s)
  533. init_textures(state);
  534.  
  535. while (!terminate)
  536. {
  537. //usleep(5*1000);
  538. update_model(state);
  539. redraw_scene(state);
  540. }
  541. exit_func();
  542. return 0;
  543. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement