Advertisement
Guest User

Untitled

a guest
May 20th, 2012
386
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.55 KB | None | 0 0
  1. #include <cassert>
  2. #include <cmath>
  3. #include <bcm_host.h>
  4. #include <GLES/gl.h>
  5. #include <GLES/glext.h>
  6. #include <EGL/egl.h>
  7. //#include <EGL/eglext.h>
  8. #include "Rpi.h"
  9.  
  10. static inline unsigned get_alignment(unsigned pitch)
  11. {
  12.    if (pitch & 1)
  13.       return 1;
  14.    if (pitch & 2)
  15.       return 2;
  16.    if (pitch & 4)
  17.       return 4;
  18.    return 8;
  19. }
  20.  
  21. static const GLfloat default_vertices[] = {
  22.    0, 0,
  23.    0, 1,
  24.    1, 1,
  25.    1, 0
  26. };
  27.  
  28. Rpi::Rpi(const rarch_video_info_t *info):
  29.     mTextureWidth(0),
  30.     mTextureHeight(0),
  31.     mRenderWidth(0),
  32.     mRenderHeight(0)
  33. {
  34.     int32_t success;
  35.     EGLBoolean result;
  36.     EGLint num_config;
  37.  
  38.     static EGL_DISPMANX_WINDOW_T nativewindow;
  39.  
  40.     DISPMANX_ELEMENT_HANDLE_T dispman_element;
  41.     DISPMANX_DISPLAY_HANDLE_T dispman_display;
  42.     DISPMANX_UPDATE_HANDLE_T dispman_update;
  43.     DISPMANX_MODEINFO_T dispman_modeinfo;
  44.     VC_RECT_T dst_rect;
  45.     VC_RECT_T src_rect;
  46.  
  47.     static const EGLint attribute_list[] =
  48.     {
  49.         EGL_RED_SIZE, 8,
  50.         EGL_GREEN_SIZE, 8,
  51.         EGL_BLUE_SIZE, 8,
  52.         EGL_ALPHA_SIZE, 8,
  53.         EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
  54.         EGL_NONE
  55.     };
  56.  
  57.     EGLConfig config;
  58.  
  59.     // get an EGL display connection
  60.     mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
  61.     assert(mDisplay != EGL_NO_DISPLAY);
  62.  
  63.     // initialize the EGL display connection
  64.     result = eglInitialize(mDisplay, nullptr, nullptr);
  65.     assert(result != EGL_FALSE);
  66.  
  67.     // get an appropriate EGL frame buffer configuration
  68.     result = eglChooseConfig(mDisplay, attribute_list, &config, 1, &num_config);
  69.     assert(result != EGL_FALSE);
  70.  
  71.     // create an EGL rendering context
  72.     mContext = eglCreateContext(mDisplay, config, EGL_NO_CONTEXT, nullptr);
  73.     assert(mContext != EGL_NO_CONTEXT);
  74.  
  75.     // create an EGL window surface
  76.     success = graphics_get_display_size(0 /* LCD */, &mScreenWidth, &mScreenHeight);
  77.     assert(success >= 0);
  78.  
  79.     dst_rect.x = 0;
  80.     dst_rect.y = 0;
  81.     dst_rect.width = mScreenWidth;
  82.     dst_rect.height = mScreenHeight;
  83.  
  84.     src_rect.x = 0;
  85.     src_rect.y = 0;
  86.     src_rect.width = mScreenWidth << 16;
  87.     src_rect.height = mScreenHeight << 16;
  88.  
  89.     dispman_display = vc_dispmanx_display_open(0 /* LCD */);
  90.     dispman_update = vc_dispmanx_update_start(0);
  91.  
  92.     vc_dispmanx_display_get_info(dispman_display, &dispman_modeinfo);
  93.  
  94.     dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
  95.         0/*layer*/, &dst_rect, 0/*src*/,
  96.         &src_rect, DISPMANX_PROTECTION_NONE, 0 /*alpha*/, 0/*clamp*/, DISPMANX_NO_ROTATE);
  97.  
  98.     nativewindow.element = dispman_element;
  99.     nativewindow.width = mScreenWidth;
  100.     nativewindow.height = mScreenHeight;
  101.     vc_dispmanx_update_submit_sync(dispman_update);
  102.  
  103.     mSurface = eglCreateWindowSurface(mDisplay, config, &nativewindow, nullptr);
  104.     assert(mSurface != EGL_NO_SURFACE);
  105.  
  106.     // connect the context to the surface
  107.     result = eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
  108.     assert(EGL_FALSE != result);
  109.  
  110.     mBpp = info->color_format == RARCH_COLOR_FORMAT_XRGB1555 ? 2 : 4;
  111.     mTexType = info->color_format == RARCH_COLOR_FORMAT_XRGB1555 ? GL_UNSIGNED_SHORT_5_5_5_1 : GL_UNSIGNED_INT;
  112.  
  113.     // Set background color and clear buffers
  114.     glClearColor(0, 0, 0, 1);
  115.     glClear(GL_COLOR_BUFFER_BIT);
  116.     glClear(GL_DEPTH_BUFFER_BIT);
  117.     glShadeModel(GL_SMOOTH);
  118.  
  119.     // set viewport for aspect ratio, taken from RetroArch
  120.     if (info->force_aspect == RARCH_TRUE)
  121.     {
  122.         float desired_aspect = info->aspect_ratio;
  123.         float device_aspect = (float) dispman_modeinfo.width / dispman_modeinfo.height;
  124.  
  125.         // If the aspect ratios of screen and desired aspect ratio are sufficiently equal (floating point stuff),
  126.         // assume they are actually equal.
  127.         if (fabs(device_aspect - desired_aspect) < 0.0001)
  128.         {
  129.             glViewport(0, 0, mScreenWidth, mScreenHeight);
  130.         }
  131.         else if (device_aspect > desired_aspect)
  132.         {
  133.             float delta = (desired_aspect / device_aspect - 1.0) / 2.0 + 0.5;
  134.             glViewport(mScreenWidth * (0.5 - delta), 0, 2.0 * mScreenWidth * delta, mScreenHeight);
  135.             mScreenWidth = 2.0 * mScreenWidth * delta;
  136.         }
  137.         else
  138.         {
  139.             float delta = (device_aspect / desired_aspect - 1.0) / 2.0 + 0.5;
  140.             glViewport(0, mScreenHeight * (0.5 - delta), mScreenWidth, 2.0 * mScreenHeight * delta);
  141.             mScreenHeight = 2.0 * mScreenHeight * delta;
  142.         }
  143.     }
  144.     else
  145.     {
  146.         glViewport(0, 0, mScreenWidth, mScreenHeight);
  147.     }
  148.  
  149.     glMatrixMode(GL_PROJECTION);
  150.     glLoadIdentity();
  151.  
  152.     glOrtho(0, 1, 0, 1, -1, 1);
  153.     glMatrixMode(GL_MODELVIEW);
  154.     glLoadIdentity();
  155.  
  156.     mTextureWidth = mTextureHeight = info->input_scale * RARCH_INPUT_SCALE_BASE;
  157.  
  158.     mEmptyBuf = new uint8_t[mTextureWidth * mTextureHeight * info->color_format == RARCH_COLOR_FORMAT_XRGB1555 ? 2 : 4]();
  159.  
  160.     glEnable(GL_TEXTURE_2D);
  161.     glGenTextures(1, &mTexture);
  162.     glBindTexture(GL_TEXTURE_2D, mTexture);
  163.     //glPixelStorei(GL_UNPACK_ROW_LENGTH, mTextureWidth);
  164.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mTextureWidth, mTextureHeight, 0, GL_RGBA, mTexType, mEmptyBuf);
  165.  
  166.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  167.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  168.  
  169.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, info->smooth ? GL_LINEAR : GL_NEAREST);
  170.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, info->smooth ? GL_LINEAR : GL_NEAREST);
  171.  
  172.     glEnableClientState(GL_VERTEX_ARRAY);
  173.     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  174.  
  175.     mTexVertices[0] = 0;
  176.     mTexVertices[1] = 1;
  177.     mTexVertices[2] = 0;
  178.     mTexVertices[3] = 0;
  179.     mTexVertices[4] = 1;
  180.     mTexVertices[5] = 0;
  181.     mTexVertices[6] = 1;
  182.     mTexVertices[7] = 1;
  183.  
  184.     glVertexPointer(2, GL_FLOAT, 0, default_vertices);
  185.     glTexCoordPointer(2, GL_FLOAT, 0, mTexVertices);
  186.  
  187.     set_nonblock_state(info->vsync);
  188. }
  189.  
  190. Rpi::~Rpi()
  191. {
  192.     delete [] mEmptyBuf;
  193.  
  194.     // clear screen
  195.     glClear(GL_COLOR_BUFFER_BIT);
  196.     eglSwapBuffers(mDisplay, mSurface);
  197.  
  198.     // Release OpenGL resources
  199.     eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
  200.     eglDestroySurface(mDisplay, mSurface);
  201.     eglDestroyContext(mDisplay, mContext);
  202.     eglTerminate(mDisplay);
  203. }
  204.  
  205. int Rpi::frame(const void *frame, unsigned width, unsigned height, unsigned pitch, const char *msg)
  206. {
  207.     if (width != mRenderWidth || height != mRenderHeight)
  208.     {
  209.         mRenderWidth = width;
  210.         mRenderHeight = height;
  211.         glPixelStorei(GL_UNPACK_ALIGNMENT, get_alignment(pitch));
  212.     }
  213.  
  214.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, mTexType, frame);
  215.  
  216.     glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
  217.  
  218.     eglSwapBuffers(mDisplay, mSurface);
  219.  
  220.     return RARCH_OK;
  221. }
  222.  
  223. void Rpi::set_nonblock_state(int state)
  224. {
  225.     eglSwapInterval(mDisplay, state == RARCH_TRUE ? 1 : 0);
  226. }
  227.  
  228. int Rpi::alive() const
  229. {
  230.     // assume alive
  231.     return RARCH_TRUE;
  232. }
  233.  
  234. int Rpi::focus() const
  235. {
  236.     // assume focus
  237.     return RARCH_TRUE;
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement