Advertisement
Guest User

hello_trinagle_lcd.c

a guest
Apr 11th, 2013
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 24.64 KB | None | 0 0
  1. // set screen size
  2. #define SCREEN_WIDTH  480
  3. #define SCREEN_HEIGHT 272
  4.  
  5.  
  6.  
  7. /*
  8. Copyright (c) 2012, Broadcom Europe Ltd
  9. All rights reserved.
  10.  
  11. Redistribution and use in source and binary forms, with or without
  12. modification, are permitted provided that the following conditions are met:
  13.     * Redistributions of source code must retain the above copyright
  14.       notice, this list of conditions and the following disclaimer.
  15.     * Redistributions in binary form must reproduce the above copyright
  16.       notice, this list of conditions and the following disclaimer in the
  17.       documentation and/or other materials provided with the distribution.
  18.     * Neither the name of the copyright holder nor the
  19.       names of its contributors may be used to endorse or promote products
  20.       derived from this software without specific prior written permission.
  21.  
  22. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23. ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24. WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  25. DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
  26. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27. (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28. LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  29. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30. (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32. */
  33.  
  34. // A rotating cube rendered with OpenGL|ES. Three images used as textures on the cube faces.
  35.  
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <math.h>
  40. #include <assert.h>
  41. #include <unistd.h>
  42.  
  43. #include "bcm_host.h"
  44.  
  45. #include "GLES/gl.h"
  46. #include "GLES/glext.h"
  47. #include "EGL/egl.h"
  48. #include "EGL/eglext.h"
  49.  
  50. #include "cube_texture_and_coords.h"
  51.  
  52. #define PATH "./"
  53.  
  54. #define IMAGE_SIZE 128
  55.  
  56. #ifndef M_PI
  57.    #define M_PI 3.141592654
  58. #endif
  59.    
  60.  
  61. typedef struct
  62. {
  63.    uint32_t screen_width;
  64.    uint32_t screen_height;
  65. // OpenGL|ES objects
  66.    EGLDisplay display;
  67.    EGLSurface surface;
  68.    EGLContext context;
  69.    GLuint tex[6];
  70. // model rotation vector and direction
  71.    GLfloat rot_angle_x_inc;
  72.    GLfloat rot_angle_y_inc;
  73.    GLfloat rot_angle_z_inc;
  74. // current model rotation angles
  75.    GLfloat rot_angle_x;
  76.    GLfloat rot_angle_y;
  77.    GLfloat rot_angle_z;
  78. // current distance from camera
  79.    GLfloat distance;
  80.    GLfloat distance_inc;
  81. // pointers to texture buffers
  82.    char *tex_buf1;
  83.    char *tex_buf2;
  84.    char *tex_buf3;
  85. } CUBE_STATE_T;
  86.  
  87. static void init_ogl(CUBE_STATE_T *state);
  88. static void init_model_proj(CUBE_STATE_T *state);
  89. static void reset_model(CUBE_STATE_T *state);
  90. static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc);
  91. static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc);
  92. static void redraw_scene(CUBE_STATE_T *state);
  93. static void update_model(CUBE_STATE_T *state);
  94. static void init_textures(CUBE_STATE_T *state);
  95. static void load_tex_images(CUBE_STATE_T *state);
  96. static void exit_func(void);
  97. static volatile int terminate;
  98. static CUBE_STATE_T _state, *state=&_state;
  99.  
  100.  
  101. /***********************************************************
  102.  * Name: init_ogl
  103.  *
  104.  * Arguments:
  105.  *       CUBE_STATE_T *state - holds OGLES model info
  106.  *
  107.  * Description: Sets the display, OpenGL|ES context and screen stuff
  108.  *
  109.  * Returns: void
  110.  *
  111.  ***********************************************************/
  112. static void init_ogl(CUBE_STATE_T *state)
  113. {
  114.    int32_t success = 0;
  115.    EGLBoolean result;
  116.    EGLint num_config;
  117.  
  118.    static EGL_DISPMANX_WINDOW_T nativewindow;
  119.  
  120.    DISPMANX_ELEMENT_HANDLE_T dispman_element;
  121.    DISPMANX_DISPLAY_HANDLE_T dispman_display;
  122.    DISPMANX_UPDATE_HANDLE_T dispman_update;
  123.    VC_RECT_T dst_rect;
  124.    VC_RECT_T src_rect;
  125.  
  126.    static const EGLint attribute_list[] =
  127.    {
  128.       EGL_RED_SIZE, 8,
  129.       EGL_GREEN_SIZE, 8,
  130.       EGL_BLUE_SIZE, 8,
  131.       EGL_ALPHA_SIZE, 8,
  132.       EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
  133.       EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,//EGL_WINDOW_BIT,
  134.       EGL_NONE
  135.    };
  136.    
  137.    EGLConfig config;
  138.  
  139.    // get an EGL display connection
  140.    state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  141.    assert(state->display!=EGL_NO_DISPLAY);
  142.  
  143.    // initialize the EGL display connection
  144.    result = eglInitialize(state->display, NULL, NULL);
  145.    assert(EGL_FALSE != result);
  146.  
  147.    // get an appropriate EGL frame buffer configuration
  148.    result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
  149.    assert(EGL_FALSE != result);
  150.  
  151.    // create an EGL rendering context
  152.    state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL);
  153.    assert(state->context!=EGL_NO_CONTEXT);
  154.  
  155.    // create an EGL window surface
  156.    success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
  157.    state->screen_width = SCREEN_WIDTH;
  158.    state->screen_height = SCREEN_HEIGHT;
  159.    assert( success >= 0 );
  160.  
  161.    dst_rect.x = 0;
  162.    dst_rect.y = 0;
  163.    dst_rect.width = SCREEN_WIDTH;
  164.    dst_rect.height = SCREEN_HEIGHT;
  165.      
  166.    src_rect.x = 0;
  167.    src_rect.y = 0;
  168.    src_rect.width = SCREEN_WIDTH << 16;
  169.    src_rect.height = SCREEN_HEIGHT << 16;        
  170.  
  171.    dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
  172.    dispman_update = vc_dispmanx_update_start( 0 );
  173.          
  174.    dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
  175.       0/*layer*/, &dst_rect, 0/*src*/,
  176.       &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);
  177.      
  178.    nativewindow.element = dispman_element;
  179.    nativewindow.width = SCREEN_WIDTH;
  180.    nativewindow.height = SCREEN_HEIGHT;
  181.    vc_dispmanx_update_submit_sync( dispman_update );
  182.      
  183.    state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
  184.    assert(state->surface != EGL_NO_SURFACE);
  185.  
  186.    // connect the context to the surface
  187.    result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
  188.    assert(EGL_FALSE != result);
  189.  
  190.    // Set background color and clear buffers
  191.    glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
  192.    glClear( GL_COLOR_BUFFER_BIT );
  193.    glClear( GL_DEPTH_BUFFER_BIT );
  194.    glShadeModel(GL_FLAT);
  195.  
  196.    // Enable back face culling.
  197.    glEnable(GL_CULL_FACE);
  198. }
  199.  
  200. /***********************************************************
  201.  * Name: init_model_proj
  202.  *
  203.  * Arguments:
  204.  *       CUBE_STATE_T *state - holds OGLES model info
  205.  *
  206.  * Description: Sets the OpenGL|ES model to default values
  207.  *
  208.  * Returns: void
  209.  *
  210.  ***********************************************************/
  211. static void init_model_proj(CUBE_STATE_T *state)
  212. {
  213.    float nearp = 1.0f;
  214.    float farp = 500.0f;
  215.    float hht;
  216.    float hwd;
  217.  
  218.    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
  219.  
  220.    glViewport(0, 0, (GLsizei)SCREEN_WIDTH, (GLsizei)SCREEN_HEIGHT);
  221.      
  222.    glMatrixMode(GL_PROJECTION);
  223.    glLoadIdentity();
  224.  
  225.    hht = nearp * (float)tan(45.0 / 2.0 / 180.0 * M_PI);
  226.    hwd = hht * (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT;
  227.  
  228.    glFrustumf(-hwd, hwd, -hht, hht, nearp, farp);
  229.    
  230.    glEnableClientState( GL_VERTEX_ARRAY );
  231.    glVertexPointer( 3, GL_BYTE, 0, quadx );
  232.  
  233.    glEnableClientState( GL_COLOR_ARRAY );
  234.    glColorPointer(4, GL_FLOAT, 0, colorsf);
  235.  
  236.    reset_model(state);
  237. }
  238.  
  239. /***********************************************************
  240.  * Name: reset_model
  241.  *
  242.  * Arguments:
  243.  *       CUBE_STATE_T *state - holds OGLES model info
  244.  *
  245.  * Description: Resets the Model projection and rotation direction
  246.  *
  247.  * Returns: void
  248.  *
  249.  ***********************************************************/
  250. static void reset_model(CUBE_STATE_T *state)
  251. {
  252.    // reset model position
  253.    glMatrixMode(GL_MODELVIEW);
  254.    glLoadIdentity();
  255.    glTranslatef(0.f, 0.f, -50.f);
  256.  
  257.    // reset model rotation
  258.    state->rot_angle_x = 45.f; state->rot_angle_y = 30.f; state->rot_angle_z = 0.f;
  259.    state->rot_angle_x_inc = 0.5f; state->rot_angle_y_inc = 0.5f; state->rot_angle_z_inc = 0.f;
  260.    state->distance = 40.f;
  261. }
  262.  
  263. /***********************************************************
  264.  * Name: update_model
  265.  *
  266.  * Arguments:
  267.  *       CUBE_STATE_T *state - holds OGLES model info
  268.  *
  269.  * Description: Updates model projection to current position/rotation
  270.  *
  271.  * Returns: void
  272.  *
  273.  ***********************************************************/
  274. static void update_model(CUBE_STATE_T *state)
  275. {
  276.    // update position
  277.    state->rot_angle_x = inc_and_wrap_angle(state->rot_angle_x, state->rot_angle_x_inc);
  278.    state->rot_angle_y = inc_and_wrap_angle(state->rot_angle_y, state->rot_angle_y_inc);
  279.    state->rot_angle_z = inc_and_wrap_angle(state->rot_angle_z, state->rot_angle_z_inc);
  280.    state->distance    = inc_and_clip_distance(state->distance, state->distance_inc);
  281.  
  282.    glLoadIdentity();
  283.    // move camera back to see the cube
  284.    glTranslatef(0.f, 0.f, -state->distance);
  285.  
  286.    // Rotate model to new position
  287.    glRotatef(state->rot_angle_x, 1.f, 0.f, 0.f);
  288.    glRotatef(state->rot_angle_y, 0.f, 1.f, 0.f);
  289.    glRotatef(state->rot_angle_z, 0.f, 0.f, 1.f);
  290. }
  291.  
  292. /***********************************************************
  293.  * Name: inc_and_wrap_angle
  294.  *
  295.  * Arguments:
  296.  *       GLfloat angle     current angle
  297.  *       GLfloat angle_inc angle increment
  298.  *
  299.  * Description:   Increments or decrements angle by angle_inc degrees
  300.  *                Wraps to 0 at 360 deg.
  301.  *
  302.  * Returns: new value of angle
  303.  *
  304.  ***********************************************************/
  305. static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc)
  306. {
  307.    angle += angle_inc;
  308.  
  309.    if (angle >= 360.0)
  310.       angle -= 360.f;
  311.    else if (angle <=0)
  312.       angle += 360.f;
  313.  
  314.    return angle;
  315. }
  316.  
  317. /***********************************************************
  318.  * Name: inc_and_clip_distance
  319.  *
  320.  * Arguments:
  321.  *       GLfloat distance     current distance
  322.  *       GLfloat distance_inc distance increment
  323.  *
  324.  * Description:   Increments or decrements distance by distance_inc units
  325.  *                Clips to range
  326.  *
  327.  * Returns: new value of angle
  328.  *
  329.  ***********************************************************/
  330. static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc)
  331. {
  332.    distance += distance_inc;
  333.  
  334.    if (distance >= 120.0f)
  335.       distance = 120.f;
  336.    else if (distance <= 40.0f)
  337.       distance = 40.0f;
  338.  
  339.    return distance;
  340. }
  341.  
  342. /***********************************************************
  343.  * Name: redraw_scene
  344.  *
  345.  * Arguments:
  346.  *       CUBE_STATE_T *state - holds OGLES model info
  347.  *
  348.  * Description:   Draws the model and calls eglSwapBuffers
  349.  *                to render to screen
  350.  *
  351.  * Returns: void
  352.  *
  353.  ***********************************************************/
  354. static void redraw_scene(CUBE_STATE_T *state)
  355. {
  356.    // Start with a clear screen
  357.    glClear( GL_COLOR_BUFFER_BIT );
  358.    glMatrixMode(GL_MODELVIEW);
  359.  
  360.    glEnable(GL_TEXTURE_2D);
  361.    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  362.  
  363.    // Draw first (front) face:
  364.    // Bind texture surface to current vertices
  365.    glBindTexture(GL_TEXTURE_2D, state->tex[0]);
  366.  
  367.    // Need to rotate textures - do this by rotating each cube face
  368.    glRotatef(270.f, 0.f, 0.f, 1.f ); // front face normal along z axis
  369.  
  370.    // draw first 4 vertices
  371.    glDrawArrays( GL_TRIANGLE_STRIP, 0, 4);
  372.  
  373.    // same pattern for other 5 faces - rotation chosen to make image orientation 'nice'
  374.    glBindTexture(GL_TEXTURE_2D, state->tex[1]);
  375.    glRotatef(90.f, 0.f, 0.f, 1.f ); // back face normal along z axis
  376.    glDrawArrays( GL_TRIANGLE_STRIP, 4, 4);
  377.  
  378.    glBindTexture(GL_TEXTURE_2D, state->tex[2]);
  379.    glRotatef(90.f, 1.f, 0.f, 0.f ); // left face normal along x axis
  380.    glDrawArrays( GL_TRIANGLE_STRIP, 8, 4);
  381.  
  382.    glBindTexture(GL_TEXTURE_2D, state->tex[3]);
  383.    glRotatef(90.f, 1.f, 0.f, 0.f ); // right face normal along x axis
  384.    glDrawArrays( GL_TRIANGLE_STRIP, 12, 4);
  385.  
  386.    glBindTexture(GL_TEXTURE_2D, state->tex[4]);
  387.    glRotatef(270.f, 0.f, 1.f, 0.f ); // top face normal along y axis
  388.    glDrawArrays( GL_TRIANGLE_STRIP, 16, 4);
  389.  
  390.    glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  391.  
  392.    glBindTexture(GL_TEXTURE_2D, state->tex[5]);
  393.    glRotatef(90.f, 0.f, 1.f, 0.f ); // bottom face normal along y axis
  394.    glDrawArrays( GL_TRIANGLE_STRIP, 20, 4);
  395.  
  396.    glDisable(GL_TEXTURE_2D);
  397.  
  398.    eglSwapBuffers(state->display, state->surface);
  399. }
  400.  
  401. /***********************************************************
  402.  * Name: init_textures
  403.  *
  404.  * Arguments:
  405.  *       CUBE_STATE_T *state - holds OGLES model info
  406.  *
  407.  * Description:   Initialise OGL|ES texture surfaces to use image
  408.  *                buffers
  409.  *
  410.  * Returns: void
  411.  *
  412.  ***********************************************************/
  413. static void init_textures(CUBE_STATE_T *state)
  414. {
  415.    // load three texture buffers but use them on six OGL|ES texture surfaces
  416.    load_tex_images(state);
  417.    glGenTextures(6, &state->tex[0]);
  418.  
  419.    // setup first texture
  420.    glBindTexture(GL_TEXTURE_2D, state->tex[0]);
  421.    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  422.                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
  423.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  424.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  425.  
  426.    // setup second texture - reuse first image
  427.    glBindTexture(GL_TEXTURE_2D, state->tex[1]);
  428.    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  429.                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
  430.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  431.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  432.  
  433.    // third texture
  434.    glBindTexture(GL_TEXTURE_2D, state->tex[2]);
  435.    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  436.                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
  437.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  438.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  439.  
  440.    // fourth texture  - reuse second image
  441.    glBindTexture(GL_TEXTURE_2D, state->tex[3]);
  442.    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  443.                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
  444.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  445.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  446.  
  447.    //fifth texture
  448.    glBindTexture(GL_TEXTURE_2D, state->tex[4]);
  449.    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  450.                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
  451.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  452.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  453.  
  454.    // sixth texture  - reuse third image
  455.    glBindTexture(GL_TEXTURE_2D, state->tex[5]);
  456.    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
  457.                 GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
  458.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
  459.    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
  460.  
  461.    // setup overall texture environment
  462.    glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
  463.    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  464. }
  465.  
  466. /***********************************************************
  467.  * Name: load_tex_images
  468.  *
  469.  * Arguments:
  470.  *       void
  471.  *
  472.  * Description: Loads three raw images to use as textures on faces
  473.  *
  474.  * Returns: void
  475.  *
  476.  ***********************************************************/
  477. static void load_tex_images(CUBE_STATE_T *state)
  478. {
  479.    FILE *tex_file1 = NULL, *tex_file2=NULL, *tex_file3 = NULL;
  480.    int bytes_read, image_sz = IMAGE_SIZE*IMAGE_SIZE*3;
  481.  
  482.    state->tex_buf1 = malloc(image_sz);
  483.    state->tex_buf2 = malloc(image_sz);
  484.    state->tex_buf3 = malloc(image_sz);
  485.  
  486.    tex_file1 = fopen(PATH "Lucca_128_128.raw", "rb");
  487.    if (tex_file1 && state->tex_buf1)
  488.    {
  489.       bytes_read=fread(state->tex_buf1, 1, image_sz, tex_file1);
  490.       assert(bytes_read == image_sz);  // some problem with file?
  491.       fclose(tex_file1);
  492.    }
  493.  
  494.    tex_file2 = fopen(PATH "Djenne_128_128.raw", "rb");
  495.    if (tex_file2 && state->tex_buf2)
  496.    {
  497.       bytes_read=fread(state->tex_buf2, 1, image_sz, tex_file2);
  498.       assert(bytes_read == image_sz);  // some problem with file?
  499.       fclose(tex_file2);      
  500.    }
  501.  
  502.    tex_file3 = fopen(PATH "Gaudi_128_128.raw", "rb");
  503.    if (tex_file3 && state->tex_buf3)
  504.    {
  505.       bytes_read=fread(state->tex_buf3, 1, image_sz, tex_file3);
  506.       assert(bytes_read == image_sz);  // some problem with file?
  507.       fclose(tex_file3);
  508.    }  
  509. }
  510.  
  511. //------------------------------------------------------------------------------
  512.  
  513. static void exit_func(void)
  514. // Function to be passed to atexit().
  515. {
  516.    // clear screen
  517.    glClear( GL_COLOR_BUFFER_BIT );
  518.    eglSwapBuffers(state->display, state->surface);
  519.  
  520.    // Release OpenGL resources
  521.    eglMakeCurrent( state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
  522.    eglDestroySurface( state->display, state->surface );
  523.    eglDestroyContext( state->display, state->context );
  524.    eglTerminate( state->display );
  525.  
  526.    // release texture buffers
  527.    free(state->tex_buf1);
  528.    free(state->tex_buf2);
  529.    free(state->tex_buf3);
  530.  
  531.    printf("\ncube closed\n");
  532. } // exit_func()
  533.  
  534. //==============================================================================
  535.  
  536. GLuint pbo_ids[1];
  537. const int DATA_SIZE = SCREEN_WIDTH * SCREEN_HEIGHT * 4;
  538.  
  539. void main_init()
  540. {
  541.     printf("%i\n", sizeof(unsigned short));
  542. }
  543.  
  544. void render_frames_init()
  545. {
  546.    bcm_host_init();
  547.  
  548.    // Clear application state
  549.    memset( state, 0, sizeof( *state ) );
  550.      
  551.    // Start OGLES
  552.    init_ogl(state);
  553.  
  554.    // Setup the model world
  555.    init_model_proj(state);
  556.  
  557.    // initialise the OGLES texture(s)
  558.    init_textures(state);
  559. }
  560.  
  561. int check_for_terminate()
  562. {
  563.     return terminate;
  564. }
  565.  
  566. void populate_frame_buffer(unsigned char* frame_buffer)
  567. {
  568.     //usleep(5*1000);
  569.     update_model(state);
  570.     redraw_scene(state);
  571.    
  572.     GLint params;
  573.     glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &params);
  574.     printf("GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: 0x%x\n", params);
  575.     glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &params);
  576.     printf("GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: 0x%x\n", params);
  577.    
  578.     glReadPixels(
  579.         0, 0,
  580.         480, 272,
  581.         GL_RGB,
  582.         GL_UNSIGNED_BYTE,
  583.         frame_buffer
  584.         );
  585.    
  586.     glGetError();
  587. }
  588.  
  589. void main_deconstruct()
  590. {
  591.     exit_func();
  592. }
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601. //#define MULTI_THREAD 1
  602.  
  603. #include <usb.h>
  604.  
  605.  
  606. // vendor and prodict ids for the usbd480
  607. #define USBD480_VID 0x16C0
  608. #define USBD480_PID 0x08A6
  609.  
  610. // set sdram address
  611. #define USBD480_SET_ADDRESS 0xC0
  612.  
  613. // thread for rendering frames
  614. #define MAX_NUM_PRERENDERED_FRAMES 3
  615.  
  616. pthread_t render_thread;
  617. pthread_mutex_t frame_lock = PTHREAD_MUTEX_INITIALIZER;
  618. pthread_cond_t frame_cond_null = PTHREAD_COND_INITIALIZER;
  619. pthread_cond_t frame_cond_not_null = PTHREAD_COND_INITIALIZER;
  620. unsigned char* frame = NULL;
  621.  
  622. // buffers and pixel data
  623. int pixelSize = 3;
  624. int stride;
  625. unsigned char* frame_buffer_1;
  626. unsigned char* frame_buffer_2;
  627.  
  628. unsigned int buffer_to_use = 1;
  629.  
  630. // fps
  631. int fps_check_interval = 1; // in seconds
  632. int fps_last_check_time;
  633. int fps_last_check_frame_count = 0;
  634. char fps_str[20];
  635.  
  636. //void main_init(); // main initialize
  637. //void render_frames_init(); // off thread initialize
  638. //void populate_frame_buffer(unsigned char* frame_buffer);
  639. //bool check_for_terminate(); // check if program should end
  640. //void main_deconstruct(); // cleanup
  641.  
  642. unsigned char* render_frame()
  643. {
  644.     unsigned char *frame_buffer;
  645.    
  646.     if (buffer_to_use == 1)
  647.     {
  648.         frame_buffer = frame_buffer_1;
  649.         buffer_to_use = 2;
  650.     }
  651.     else
  652.     {
  653.         frame_buffer = frame_buffer_2;
  654.         buffer_to_use = 1;
  655.     }
  656.    
  657.     populate_frame_buffer(frame_buffer);
  658.    
  659.     return frame_buffer;
  660. }
  661.  
  662. // render frames thread
  663. void* render_frames(void* arg)
  664. {
  665.     render_frames_init();
  666.    
  667.     while(1)
  668.     {
  669.         pthread_mutex_lock(&frame_lock);
  670.         while (frame != NULL)
  671.             pthread_cond_wait(&frame_cond_null, &frame_lock);
  672.        
  673.         //printf("rendering frame...\n");
  674.         frame = render_frame();
  675.         //printf("done rendering!\n");
  676.         pthread_cond_signal(&frame_cond_not_null);
  677.         pthread_mutex_unlock(&frame_lock);
  678.     }
  679. }
  680.  
  681. unsigned char* get_frame()
  682. {
  683.     // wait until the frame is ready
  684.     pthread_mutex_lock(&frame_lock);
  685.     while (frame == NULL)
  686.         pthread_cond_wait(&frame_cond_not_null, &frame_lock);
  687.    
  688.     unsigned char* frame_buffer = frame;
  689.     frame = NULL;
  690.    
  691.     pthread_cond_signal(&frame_cond_null);
  692.     pthread_mutex_unlock(&frame_lock);
  693.    
  694.     return frame_buffer;
  695. }
  696.  
  697. // finds our lcd device
  698. static struct usb_device* find_usbd480(void)
  699. {
  700.     // find the usb busses and devices
  701.     usb_find_busses();
  702.     usb_find_devices();
  703.    
  704.     // get usb busses
  705.     struct usb_bus* usb_busses = usb_get_busses();
  706.    
  707.     // loop through each bus and each device to find our lcd
  708.     struct usb_bus* usb_bus;
  709.     for (usb_bus = usb_busses; usb_bus; usb_bus = usb_bus->next)
  710.     {
  711.         struct usb_device *usb_device;
  712.         for (usb_device = usb_bus->devices; usb_device; usb_device = usb_device->next)
  713.         {
  714.             // check the vendor and product ids
  715.             if (usb_device->descriptor.idVendor == USBD480_VID && usb_device->descriptor.idProduct == USBD480_PID)
  716.                 return usb_device;
  717.         }
  718.     }
  719.     return NULL;
  720. }
  721.  
  722. // initialize
  723. int main(int argc, char* argv[])
  724. {
  725.     srand((unsigned)time(NULL));
  726.    
  727.     stride = SCREEN_WIDTH * pixelSize;
  728.    
  729.     frame_buffer_1 = malloc(SCREEN_HEIGHT * stride);
  730.     frame_buffer_2 = malloc(SCREEN_HEIGHT * stride);
  731.    
  732.     #ifndef MULTI_THREAD
  733.         render_frames_init();
  734.     #endif
  735.    
  736.     usb_dev_handle *usb_handle = NULL;
  737.    
  738.     // initate the libusb library and find our lcd
  739.     usb_init();
  740.    
  741.     struct usb_device *usb_device = find_usbd480();
  742.    
  743.     if (!usb_device)
  744.     {
  745.         printf("No USBD480 device found\n");
  746.         return 1;
  747.     }
  748.    
  749.     // claim our usb device
  750.     usb_handle = usb_open(usb_device);
  751.    
  752.     if(usb_handle==NULL)
  753.         printf("error: usb_open\n");
  754.    
  755.     if(usb_set_configuration(usb_handle, 1) < 0)
  756.     {
  757.         printf("error: setting config 1 failed\n");
  758.         printf("%s\n", usb_strerror());
  759.         usb_close(usb_handle);
  760.         return 1;
  761.     }
  762.    
  763.     if(usb_claim_interface(usb_handle, 0) < 0)
  764.     {
  765.         printf("error: claiming interface 0 failed\n");
  766.         printf("%s\n", usb_strerror());
  767.         usb_close(usb_handle);
  768.         return 1;
  769.     }
  770.    
  771.     usb_set_debug(3);
  772.    
  773.     int err = 0;
  774.     #ifdef MULTI_THREAD
  775.         // start rendering the frames
  776.         err = pthread_create(&render_thread, NULL, &render_frames, NULL);
  777.     #endif
  778.    
  779.     if (err != 0)
  780.     {
  781.         printf("can't create thread :[%i]\n", err);
  782.         return 1;
  783.     }
  784.    
  785.     if (pthread_mutex_init(&frame_lock, NULL) != 0)
  786.     {
  787.         printf("mutex init failed\n");
  788.         return 1;
  789.     }
  790.    
  791.     if (pthread_cond_init(&frame_cond_null, NULL) != 0)
  792.     {
  793.         printf("cond init failed\n");
  794.         return 1;
  795.     }
  796.    
  797.     if (pthread_cond_init(&frame_cond_not_null, NULL) != 0)
  798.     {
  799.         printf("cond init failed\n");
  800.         return 1;
  801.     }
  802.    
  803.     unsigned int bytes_to_write = 261120;
  804.     unsigned int addr = 0;
  805.    
  806.     main_init();
  807.    
  808.     // use a max number of frames just in case
  809.     int frame_count;
  810.     for (frame_count = 0; frame_count < 1000; ++frame_count)
  811.     {
  812.         if (check_for_terminate())
  813.             break;
  814.        
  815.         int cur_time = time(NULL);
  816.         int fps_check_lapse = cur_time - fps_last_check_time;
  817.        
  818.         if (fps_check_lapse >= fps_check_interval)
  819.         {
  820.             int fps = (frame_count - fps_last_check_frame_count) / fps_check_lapse;
  821.            
  822.             fps_last_check_frame_count = frame_count;
  823.             fps_last_check_time = cur_time;
  824.            
  825.             sprintf(fps_str, "FPS: %i", fps);
  826.         }
  827.        
  828.         unsigned char* frame_buffer;
  829.         #ifdef MULTI_THREAD
  830.             frame_buffer = get_frame();
  831.         #else
  832.             frame_buffer = render_frame();
  833.         #endif
  834.        
  835.         bytes_to_write = 261120;
  836.         addr = 0;
  837.        
  838.         int err = usb_control_msg(usb_handle, 0x40, USBD480_SET_ADDRESS, addr, (addr>>16)&0xffff, NULL, 0, 500);
  839.         if (err < 0)
  840.             printf("control_msg error. %i\n", err);
  841.        
  842.         int bytes_written = usb_bulk_write(usb_handle, 0x02, (char*)frame_buffer, bytes_to_write, 5000);
  843.        
  844.         if (bytes_written < 0)
  845.             printf("bulk_write error. %i\n", bytes_written);
  846.         else if (bytes_written != bytes_to_write)
  847.             printf("bulk_write error. Wrote %i\n", bytes_written);
  848.     }
  849.    
  850.     free(frame_buffer_1);
  851.     free(frame_buffer_2);
  852.    
  853.     usb_release_interface(usb_handle, 0);
  854.     usb_close(usb_handle);
  855.    
  856.     main_deconstruct();
  857.    
  858.     return 0;
  859. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement