Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // set screen size
- #define SCREEN_WIDTH 480
- #define SCREEN_HEIGHT 272
- /*
- Copyright (c) 2012, Broadcom Europe Ltd
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of the copyright holder nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
- DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- // A rotating cube rendered with OpenGL|ES. Three images used as textures on the cube faces.
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include <assert.h>
- #include <unistd.h>
- #include "bcm_host.h"
- #include "GLES/gl.h"
- #include "GLES/glext.h"
- #include "EGL/egl.h"
- #include "EGL/eglext.h"
- #include "cube_texture_and_coords.h"
- #define PATH "./"
- #define IMAGE_SIZE 128
- #ifndef M_PI
- #define M_PI 3.141592654
- #endif
- typedef struct
- {
- uint32_t screen_width;
- uint32_t screen_height;
- // OpenGL|ES objects
- EGLDisplay display;
- EGLSurface surface;
- EGLContext context;
- GLuint tex[6];
- // model rotation vector and direction
- GLfloat rot_angle_x_inc;
- GLfloat rot_angle_y_inc;
- GLfloat rot_angle_z_inc;
- // current model rotation angles
- GLfloat rot_angle_x;
- GLfloat rot_angle_y;
- GLfloat rot_angle_z;
- // current distance from camera
- GLfloat distance;
- GLfloat distance_inc;
- // pointers to texture buffers
- char *tex_buf1;
- char *tex_buf2;
- char *tex_buf3;
- } CUBE_STATE_T;
- static void init_ogl(CUBE_STATE_T *state);
- static void init_model_proj(CUBE_STATE_T *state);
- static void reset_model(CUBE_STATE_T *state);
- static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc);
- static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc);
- static void redraw_scene(CUBE_STATE_T *state);
- static void update_model(CUBE_STATE_T *state);
- static void init_textures(CUBE_STATE_T *state);
- static void load_tex_images(CUBE_STATE_T *state);
- static void exit_func(void);
- static volatile int terminate;
- static CUBE_STATE_T _state, *state=&_state;
- /***********************************************************
- * Name: init_ogl
- *
- * Arguments:
- * CUBE_STATE_T *state - holds OGLES model info
- *
- * Description: Sets the display, OpenGL|ES context and screen stuff
- *
- * Returns: void
- *
- ***********************************************************/
- static void init_ogl(CUBE_STATE_T *state)
- {
- int32_t success = 0;
- EGLBoolean result;
- EGLint num_config;
- static EGL_DISPMANX_WINDOW_T nativewindow;
- DISPMANX_ELEMENT_HANDLE_T dispman_element;
- DISPMANX_DISPLAY_HANDLE_T dispman_display;
- DISPMANX_UPDATE_HANDLE_T dispman_update;
- VC_RECT_T dst_rect;
- VC_RECT_T src_rect;
- static const EGLint attribute_list[] =
- {
- EGL_RED_SIZE, 8,
- EGL_GREEN_SIZE, 8,
- EGL_BLUE_SIZE, 8,
- EGL_ALPHA_SIZE, 8,
- EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER,
- EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,//EGL_WINDOW_BIT,
- EGL_NONE
- };
- EGLConfig config;
- // get an EGL display connection
- state->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- assert(state->display!=EGL_NO_DISPLAY);
- // initialize the EGL display connection
- result = eglInitialize(state->display, NULL, NULL);
- assert(EGL_FALSE != result);
- // get an appropriate EGL frame buffer configuration
- result = eglChooseConfig(state->display, attribute_list, &config, 1, &num_config);
- assert(EGL_FALSE != result);
- // create an EGL rendering context
- state->context = eglCreateContext(state->display, config, EGL_NO_CONTEXT, NULL);
- assert(state->context!=EGL_NO_CONTEXT);
- // create an EGL window surface
- success = graphics_get_display_size(0 /* LCD */, &state->screen_width, &state->screen_height);
- state->screen_width = SCREEN_WIDTH;
- state->screen_height = SCREEN_HEIGHT;
- assert( success >= 0 );
- dst_rect.x = 0;
- dst_rect.y = 0;
- dst_rect.width = SCREEN_WIDTH;
- dst_rect.height = SCREEN_HEIGHT;
- src_rect.x = 0;
- src_rect.y = 0;
- src_rect.width = SCREEN_WIDTH << 16;
- src_rect.height = SCREEN_HEIGHT << 16;
- dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
- dispman_update = vc_dispmanx_update_start( 0 );
- dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
- 0/*layer*/, &dst_rect, 0/*src*/,
- &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, 0/*transform*/);
- nativewindow.element = dispman_element;
- nativewindow.width = SCREEN_WIDTH;
- nativewindow.height = SCREEN_HEIGHT;
- vc_dispmanx_update_submit_sync( dispman_update );
- state->surface = eglCreateWindowSurface( state->display, config, &nativewindow, NULL );
- assert(state->surface != EGL_NO_SURFACE);
- // connect the context to the surface
- result = eglMakeCurrent(state->display, state->surface, state->surface, state->context);
- assert(EGL_FALSE != result);
- // Set background color and clear buffers
- glClearColor(0.15f, 0.25f, 0.35f, 1.0f);
- glClear( GL_COLOR_BUFFER_BIT );
- glClear( GL_DEPTH_BUFFER_BIT );
- glShadeModel(GL_FLAT);
- // Enable back face culling.
- glEnable(GL_CULL_FACE);
- }
- /***********************************************************
- * Name: init_model_proj
- *
- * Arguments:
- * CUBE_STATE_T *state - holds OGLES model info
- *
- * Description: Sets the OpenGL|ES model to default values
- *
- * Returns: void
- *
- ***********************************************************/
- static void init_model_proj(CUBE_STATE_T *state)
- {
- float nearp = 1.0f;
- float farp = 500.0f;
- float hht;
- float hwd;
- glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
- glViewport(0, 0, (GLsizei)SCREEN_WIDTH, (GLsizei)SCREEN_HEIGHT);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- hht = nearp * (float)tan(45.0 / 2.0 / 180.0 * M_PI);
- hwd = hht * (float)SCREEN_WIDTH / (float)SCREEN_HEIGHT;
- glFrustumf(-hwd, hwd, -hht, hht, nearp, farp);
- glEnableClientState( GL_VERTEX_ARRAY );
- glVertexPointer( 3, GL_BYTE, 0, quadx );
- glEnableClientState( GL_COLOR_ARRAY );
- glColorPointer(4, GL_FLOAT, 0, colorsf);
- reset_model(state);
- }
- /***********************************************************
- * Name: reset_model
- *
- * Arguments:
- * CUBE_STATE_T *state - holds OGLES model info
- *
- * Description: Resets the Model projection and rotation direction
- *
- * Returns: void
- *
- ***********************************************************/
- static void reset_model(CUBE_STATE_T *state)
- {
- // reset model position
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.f, 0.f, -50.f);
- // reset model rotation
- state->rot_angle_x = 45.f; state->rot_angle_y = 30.f; state->rot_angle_z = 0.f;
- state->rot_angle_x_inc = 0.5f; state->rot_angle_y_inc = 0.5f; state->rot_angle_z_inc = 0.f;
- state->distance = 40.f;
- }
- /***********************************************************
- * Name: update_model
- *
- * Arguments:
- * CUBE_STATE_T *state - holds OGLES model info
- *
- * Description: Updates model projection to current position/rotation
- *
- * Returns: void
- *
- ***********************************************************/
- static void update_model(CUBE_STATE_T *state)
- {
- // update position
- state->rot_angle_x = inc_and_wrap_angle(state->rot_angle_x, state->rot_angle_x_inc);
- state->rot_angle_y = inc_and_wrap_angle(state->rot_angle_y, state->rot_angle_y_inc);
- state->rot_angle_z = inc_and_wrap_angle(state->rot_angle_z, state->rot_angle_z_inc);
- state->distance = inc_and_clip_distance(state->distance, state->distance_inc);
- glLoadIdentity();
- // move camera back to see the cube
- glTranslatef(0.f, 0.f, -state->distance);
- // Rotate model to new position
- glRotatef(state->rot_angle_x, 1.f, 0.f, 0.f);
- glRotatef(state->rot_angle_y, 0.f, 1.f, 0.f);
- glRotatef(state->rot_angle_z, 0.f, 0.f, 1.f);
- }
- /***********************************************************
- * Name: inc_and_wrap_angle
- *
- * Arguments:
- * GLfloat angle current angle
- * GLfloat angle_inc angle increment
- *
- * Description: Increments or decrements angle by angle_inc degrees
- * Wraps to 0 at 360 deg.
- *
- * Returns: new value of angle
- *
- ***********************************************************/
- static GLfloat inc_and_wrap_angle(GLfloat angle, GLfloat angle_inc)
- {
- angle += angle_inc;
- if (angle >= 360.0)
- angle -= 360.f;
- else if (angle <=0)
- angle += 360.f;
- return angle;
- }
- /***********************************************************
- * Name: inc_and_clip_distance
- *
- * Arguments:
- * GLfloat distance current distance
- * GLfloat distance_inc distance increment
- *
- * Description: Increments or decrements distance by distance_inc units
- * Clips to range
- *
- * Returns: new value of angle
- *
- ***********************************************************/
- static GLfloat inc_and_clip_distance(GLfloat distance, GLfloat distance_inc)
- {
- distance += distance_inc;
- if (distance >= 120.0f)
- distance = 120.f;
- else if (distance <= 40.0f)
- distance = 40.0f;
- return distance;
- }
- /***********************************************************
- * Name: redraw_scene
- *
- * Arguments:
- * CUBE_STATE_T *state - holds OGLES model info
- *
- * Description: Draws the model and calls eglSwapBuffers
- * to render to screen
- *
- * Returns: void
- *
- ***********************************************************/
- static void redraw_scene(CUBE_STATE_T *state)
- {
- // Start with a clear screen
- glClear( GL_COLOR_BUFFER_BIT );
- glMatrixMode(GL_MODELVIEW);
- glEnable(GL_TEXTURE_2D);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- // Draw first (front) face:
- // Bind texture surface to current vertices
- glBindTexture(GL_TEXTURE_2D, state->tex[0]);
- // Need to rotate textures - do this by rotating each cube face
- glRotatef(270.f, 0.f, 0.f, 1.f ); // front face normal along z axis
- // draw first 4 vertices
- glDrawArrays( GL_TRIANGLE_STRIP, 0, 4);
- // same pattern for other 5 faces - rotation chosen to make image orientation 'nice'
- glBindTexture(GL_TEXTURE_2D, state->tex[1]);
- glRotatef(90.f, 0.f, 0.f, 1.f ); // back face normal along z axis
- glDrawArrays( GL_TRIANGLE_STRIP, 4, 4);
- glBindTexture(GL_TEXTURE_2D, state->tex[2]);
- glRotatef(90.f, 1.f, 0.f, 0.f ); // left face normal along x axis
- glDrawArrays( GL_TRIANGLE_STRIP, 8, 4);
- glBindTexture(GL_TEXTURE_2D, state->tex[3]);
- glRotatef(90.f, 1.f, 0.f, 0.f ); // right face normal along x axis
- glDrawArrays( GL_TRIANGLE_STRIP, 12, 4);
- glBindTexture(GL_TEXTURE_2D, state->tex[4]);
- glRotatef(270.f, 0.f, 1.f, 0.f ); // top face normal along y axis
- glDrawArrays( GL_TRIANGLE_STRIP, 16, 4);
- glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glBindTexture(GL_TEXTURE_2D, state->tex[5]);
- glRotatef(90.f, 0.f, 1.f, 0.f ); // bottom face normal along y axis
- glDrawArrays( GL_TRIANGLE_STRIP, 20, 4);
- glDisable(GL_TEXTURE_2D);
- eglSwapBuffers(state->display, state->surface);
- }
- /***********************************************************
- * Name: init_textures
- *
- * Arguments:
- * CUBE_STATE_T *state - holds OGLES model info
- *
- * Description: Initialise OGL|ES texture surfaces to use image
- * buffers
- *
- * Returns: void
- *
- ***********************************************************/
- static void init_textures(CUBE_STATE_T *state)
- {
- // load three texture buffers but use them on six OGL|ES texture surfaces
- load_tex_images(state);
- glGenTextures(6, &state->tex[0]);
- // setup first texture
- glBindTexture(GL_TEXTURE_2D, state->tex[0]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
- GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
- // setup second texture - reuse first image
- glBindTexture(GL_TEXTURE_2D, state->tex[1]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
- GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf1);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
- // third texture
- glBindTexture(GL_TEXTURE_2D, state->tex[2]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
- GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
- // fourth texture - reuse second image
- glBindTexture(GL_TEXTURE_2D, state->tex[3]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
- GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf2);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
- //fifth texture
- glBindTexture(GL_TEXTURE_2D, state->tex[4]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
- GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
- // sixth texture - reuse third image
- glBindTexture(GL_TEXTURE_2D, state->tex[5]);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_SIZE, IMAGE_SIZE, 0,
- GL_RGB, GL_UNSIGNED_BYTE, state->tex_buf3);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, (GLfloat)GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, (GLfloat)GL_NEAREST);
- // setup overall texture environment
- glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- /***********************************************************
- * Name: load_tex_images
- *
- * Arguments:
- * void
- *
- * Description: Loads three raw images to use as textures on faces
- *
- * Returns: void
- *
- ***********************************************************/
- static void load_tex_images(CUBE_STATE_T *state)
- {
- FILE *tex_file1 = NULL, *tex_file2=NULL, *tex_file3 = NULL;
- int bytes_read, image_sz = IMAGE_SIZE*IMAGE_SIZE*3;
- state->tex_buf1 = malloc(image_sz);
- state->tex_buf2 = malloc(image_sz);
- state->tex_buf3 = malloc(image_sz);
- tex_file1 = fopen(PATH "Lucca_128_128.raw", "rb");
- if (tex_file1 && state->tex_buf1)
- {
- bytes_read=fread(state->tex_buf1, 1, image_sz, tex_file1);
- assert(bytes_read == image_sz); // some problem with file?
- fclose(tex_file1);
- }
- tex_file2 = fopen(PATH "Djenne_128_128.raw", "rb");
- if (tex_file2 && state->tex_buf2)
- {
- bytes_read=fread(state->tex_buf2, 1, image_sz, tex_file2);
- assert(bytes_read == image_sz); // some problem with file?
- fclose(tex_file2);
- }
- tex_file3 = fopen(PATH "Gaudi_128_128.raw", "rb");
- if (tex_file3 && state->tex_buf3)
- {
- bytes_read=fread(state->tex_buf3, 1, image_sz, tex_file3);
- assert(bytes_read == image_sz); // some problem with file?
- fclose(tex_file3);
- }
- }
- //------------------------------------------------------------------------------
- static void exit_func(void)
- // Function to be passed to atexit().
- {
- // clear screen
- glClear( GL_COLOR_BUFFER_BIT );
- eglSwapBuffers(state->display, state->surface);
- // Release OpenGL resources
- eglMakeCurrent( state->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
- eglDestroySurface( state->display, state->surface );
- eglDestroyContext( state->display, state->context );
- eglTerminate( state->display );
- // release texture buffers
- free(state->tex_buf1);
- free(state->tex_buf2);
- free(state->tex_buf3);
- printf("\ncube closed\n");
- } // exit_func()
- //==============================================================================
- GLuint pbo_ids[1];
- const int DATA_SIZE = SCREEN_WIDTH * SCREEN_HEIGHT * 4;
- void main_init()
- {
- printf("%i\n", sizeof(unsigned short));
- }
- void render_frames_init()
- {
- bcm_host_init();
- // Clear application state
- memset( state, 0, sizeof( *state ) );
- // Start OGLES
- init_ogl(state);
- // Setup the model world
- init_model_proj(state);
- // initialise the OGLES texture(s)
- init_textures(state);
- }
- int check_for_terminate()
- {
- return terminate;
- }
- void populate_frame_buffer(unsigned char* frame_buffer)
- {
- //usleep(5*1000);
- update_model(state);
- redraw_scene(state);
- GLint params;
- glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, ¶ms);
- printf("GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES: 0x%x\n", params);
- glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, ¶ms);
- printf("GL_IMPLEMENTATION_COLOR_READ_TYPE_OES: 0x%x\n", params);
- glReadPixels(
- 0, 0,
- 480, 272,
- GL_RGB,
- GL_UNSIGNED_BYTE,
- frame_buffer
- );
- glGetError();
- }
- void main_deconstruct()
- {
- exit_func();
- }
- //#define MULTI_THREAD 1
- #include <usb.h>
- // vendor and prodict ids for the usbd480
- #define USBD480_VID 0x16C0
- #define USBD480_PID 0x08A6
- // set sdram address
- #define USBD480_SET_ADDRESS 0xC0
- // thread for rendering frames
- #define MAX_NUM_PRERENDERED_FRAMES 3
- pthread_t render_thread;
- pthread_mutex_t frame_lock = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t frame_cond_null = PTHREAD_COND_INITIALIZER;
- pthread_cond_t frame_cond_not_null = PTHREAD_COND_INITIALIZER;
- unsigned char* frame = NULL;
- // buffers and pixel data
- int pixelSize = 3;
- int stride;
- unsigned char* frame_buffer_1;
- unsigned char* frame_buffer_2;
- unsigned int buffer_to_use = 1;
- // fps
- int fps_check_interval = 1; // in seconds
- int fps_last_check_time;
- int fps_last_check_frame_count = 0;
- char fps_str[20];
- //void main_init(); // main initialize
- //void render_frames_init(); // off thread initialize
- //void populate_frame_buffer(unsigned char* frame_buffer);
- //bool check_for_terminate(); // check if program should end
- //void main_deconstruct(); // cleanup
- unsigned char* render_frame()
- {
- unsigned char *frame_buffer;
- if (buffer_to_use == 1)
- {
- frame_buffer = frame_buffer_1;
- buffer_to_use = 2;
- }
- else
- {
- frame_buffer = frame_buffer_2;
- buffer_to_use = 1;
- }
- populate_frame_buffer(frame_buffer);
- return frame_buffer;
- }
- // render frames thread
- void* render_frames(void* arg)
- {
- render_frames_init();
- while(1)
- {
- pthread_mutex_lock(&frame_lock);
- while (frame != NULL)
- pthread_cond_wait(&frame_cond_null, &frame_lock);
- //printf("rendering frame...\n");
- frame = render_frame();
- //printf("done rendering!\n");
- pthread_cond_signal(&frame_cond_not_null);
- pthread_mutex_unlock(&frame_lock);
- }
- }
- unsigned char* get_frame()
- {
- // wait until the frame is ready
- pthread_mutex_lock(&frame_lock);
- while (frame == NULL)
- pthread_cond_wait(&frame_cond_not_null, &frame_lock);
- unsigned char* frame_buffer = frame;
- frame = NULL;
- pthread_cond_signal(&frame_cond_null);
- pthread_mutex_unlock(&frame_lock);
- return frame_buffer;
- }
- // finds our lcd device
- static struct usb_device* find_usbd480(void)
- {
- // find the usb busses and devices
- usb_find_busses();
- usb_find_devices();
- // get usb busses
- struct usb_bus* usb_busses = usb_get_busses();
- // loop through each bus and each device to find our lcd
- struct usb_bus* usb_bus;
- for (usb_bus = usb_busses; usb_bus; usb_bus = usb_bus->next)
- {
- struct usb_device *usb_device;
- for (usb_device = usb_bus->devices; usb_device; usb_device = usb_device->next)
- {
- // check the vendor and product ids
- if (usb_device->descriptor.idVendor == USBD480_VID && usb_device->descriptor.idProduct == USBD480_PID)
- return usb_device;
- }
- }
- return NULL;
- }
- // initialize
- int main(int argc, char* argv[])
- {
- srand((unsigned)time(NULL));
- stride = SCREEN_WIDTH * pixelSize;
- frame_buffer_1 = malloc(SCREEN_HEIGHT * stride);
- frame_buffer_2 = malloc(SCREEN_HEIGHT * stride);
- #ifndef MULTI_THREAD
- render_frames_init();
- #endif
- usb_dev_handle *usb_handle = NULL;
- // initate the libusb library and find our lcd
- usb_init();
- struct usb_device *usb_device = find_usbd480();
- if (!usb_device)
- {
- printf("No USBD480 device found\n");
- return 1;
- }
- // claim our usb device
- usb_handle = usb_open(usb_device);
- if(usb_handle==NULL)
- printf("error: usb_open\n");
- if(usb_set_configuration(usb_handle, 1) < 0)
- {
- printf("error: setting config 1 failed\n");
- printf("%s\n", usb_strerror());
- usb_close(usb_handle);
- return 1;
- }
- if(usb_claim_interface(usb_handle, 0) < 0)
- {
- printf("error: claiming interface 0 failed\n");
- printf("%s\n", usb_strerror());
- usb_close(usb_handle);
- return 1;
- }
- usb_set_debug(3);
- int err = 0;
- #ifdef MULTI_THREAD
- // start rendering the frames
- err = pthread_create(&render_thread, NULL, &render_frames, NULL);
- #endif
- if (err != 0)
- {
- printf("can't create thread :[%i]\n", err);
- return 1;
- }
- if (pthread_mutex_init(&frame_lock, NULL) != 0)
- {
- printf("mutex init failed\n");
- return 1;
- }
- if (pthread_cond_init(&frame_cond_null, NULL) != 0)
- {
- printf("cond init failed\n");
- return 1;
- }
- if (pthread_cond_init(&frame_cond_not_null, NULL) != 0)
- {
- printf("cond init failed\n");
- return 1;
- }
- unsigned int bytes_to_write = 261120;
- unsigned int addr = 0;
- main_init();
- // use a max number of frames just in case
- int frame_count;
- for (frame_count = 0; frame_count < 1000; ++frame_count)
- {
- if (check_for_terminate())
- break;
- int cur_time = time(NULL);
- int fps_check_lapse = cur_time - fps_last_check_time;
- if (fps_check_lapse >= fps_check_interval)
- {
- int fps = (frame_count - fps_last_check_frame_count) / fps_check_lapse;
- fps_last_check_frame_count = frame_count;
- fps_last_check_time = cur_time;
- sprintf(fps_str, "FPS: %i", fps);
- }
- unsigned char* frame_buffer;
- #ifdef MULTI_THREAD
- frame_buffer = get_frame();
- #else
- frame_buffer = render_frame();
- #endif
- bytes_to_write = 261120;
- addr = 0;
- int err = usb_control_msg(usb_handle, 0x40, USBD480_SET_ADDRESS, addr, (addr>>16)&0xffff, NULL, 0, 500);
- if (err < 0)
- printf("control_msg error. %i\n", err);
- int bytes_written = usb_bulk_write(usb_handle, 0x02, (char*)frame_buffer, bytes_to_write, 5000);
- if (bytes_written < 0)
- printf("bulk_write error. %i\n", bytes_written);
- else if (bytes_written != bytes_to_write)
- printf("bulk_write error. Wrote %i\n", bytes_written);
- }
- free(frame_buffer_1);
- free(frame_buffer_2);
- usb_release_interface(usb_handle, 0);
- usb_close(usb_handle);
- main_deconstruct();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement