diff options
Diffstat (limited to 'raspberrypi/gles_video.c')
-rw-r--r-- | raspberrypi/gles_video.c | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/raspberrypi/gles_video.c b/raspberrypi/gles_video.c deleted file mode 100644 index adf9b03..0000000 --- a/raspberrypi/gles_video.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - -This file is based on Portable ZX-Spectrum emulator. -Copyright (C) 2001-2012 SMT, Dexus, Alone Coder, deathsoft, djdron, scor - -C++ to C code conversion by Pate - -Modified by DPR for gpsp for Raspberry Pi - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see <http://www.gnu.org/licenses/>. - -*/ - -#include "bcm_host.h" -#include "GLES/gl.h" -#include "EGL/egl.h" -#include "EGL/eglext.h" -#include "GLES2/gl2.h" -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <memory.h> - -static uint32_t frame_width = 0; -static uint32_t frame_height = 0; - - -#define SHOW_ERROR gles_show_error(); - -static void SetOrtho(GLfloat m[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far, GLfloat scale_x, GLfloat scale_y); - -static const char* vertex_shader = - "uniform mat4 u_vp_matrix; \n" - "attribute vec4 a_position; \n" - "attribute vec2 a_texcoord; \n" - "varying mediump vec2 v_texcoord; \n" - "void main() \n" - "{ \n" - " v_texcoord = a_texcoord; \n" - " gl_Position = u_vp_matrix * a_position; \n" - "} \n"; - -static const char* fragment_shader = - "varying mediump vec2 v_texcoord; \n" - "uniform sampler2D u_texture; \n" - "void main() \n" - "{ \n" - " gl_FragColor = texture2D(u_texture, v_texcoord); \n" - "} \n"; -/* -static const GLfloat vertices[] = -{ - -0.5f, -0.5f, 0.0f, - +0.5f, -0.5f, 0.0f, - +0.5f, +0.5f, 0.0f, - -0.5f, +0.5f, 0.0f, -}; -*/ -static const GLfloat vertices[] = -{ - -0.5f, -0.5f, 0.0f, - -0.5f, +0.5f, 0.0f, - +0.5f, +0.5f, 0.0f, - +0.5f, -0.5f, 0.0f, -}; - -#define TEX_WIDTH 1024 -#define TEX_HEIGHT 512 - -static const GLfloat uvs[8]; - -static const GLushort indices[] = -{ - 0, 1, 2, - 0, 2, 3, -}; - -static const int kVertexCount = 4; -static const int kIndexCount = 6; - - -void Create_uvs(GLfloat * matrix, GLfloat max_u, GLfloat max_v) { - memset(matrix,0,sizeof(GLfloat)*8); - matrix[3]=max_v; - matrix[4]=max_u; - matrix[5]=max_v; - matrix[6]=max_u; - -} - -void gles_show_error() -{ - GLenum error = GL_NO_ERROR; - error = glGetError(); - if (GL_NO_ERROR != error) - printf("GL Error %x encountered!\n", error); -} - -static GLuint CreateShader(GLenum type, const char *shader_src) -{ - GLuint shader = glCreateShader(type); - if(!shader) - return 0; - - // Load and compile the shader source - glShaderSource(shader, 1, &shader_src, NULL); - glCompileShader(shader); - - // Check the compile status - GLint compiled = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); - if(!compiled) - { - GLint info_len = 0; - glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_len); - if(info_len > 1) - { - char* info_log = (char *)malloc(sizeof(char) * info_len); - glGetShaderInfoLog(shader, info_len, NULL, info_log); - // TODO(dspringer): We could really use a logging API. - printf("Error compiling shader:\n%s\n", info_log); - free(info_log); - } - glDeleteShader(shader); - return 0; - } - return shader; -} - -static GLuint CreateProgram(const char *vertex_shader_src, const char *fragment_shader_src) -{ - GLuint vertex_shader = CreateShader(GL_VERTEX_SHADER, vertex_shader_src); - if(!vertex_shader) - return 0; - GLuint fragment_shader = CreateShader(GL_FRAGMENT_SHADER, fragment_shader_src); - if(!fragment_shader) - { - glDeleteShader(vertex_shader); - return 0; - } - - GLuint program_object = glCreateProgram(); - if(!program_object) - return 0; - glAttachShader(program_object, vertex_shader); - glAttachShader(program_object, fragment_shader); - - // Link the program - glLinkProgram(program_object); - - // Check the link status - GLint linked = 0; - glGetProgramiv(program_object, GL_LINK_STATUS, &linked); - if(!linked) - { - GLint info_len = 0; - glGetProgramiv(program_object, GL_INFO_LOG_LENGTH, &info_len); - if(info_len > 1) - { - char* info_log = (char *)malloc(info_len); - glGetProgramInfoLog(program_object, info_len, NULL, info_log); - // TODO(dspringer): We could really use a logging API. - printf("Error linking program:\n%s\n", info_log); - free(info_log); - } - glDeleteProgram(program_object); - return 0; - } - // Delete these here because they are attached to the program object. - glDeleteShader(vertex_shader); - glDeleteShader(fragment_shader); - return program_object; -} - -typedef struct ShaderInfo { - GLuint program; - GLint a_position; - GLint a_texcoord; - GLint u_vp_matrix; - GLint u_texture; -} ShaderInfo; - -static ShaderInfo shader; -static ShaderInfo shader_filtering; -static GLuint buffers[3]; -static GLuint textures[2]; - - -static void gles2_create() -{ - memset(&shader, 0, sizeof(ShaderInfo)); - shader.program = CreateProgram(vertex_shader, fragment_shader); - if(shader.program) - { - shader.a_position = glGetAttribLocation(shader.program, "a_position"); - shader.a_texcoord = glGetAttribLocation(shader.program, "a_texcoord"); - shader.u_vp_matrix = glGetUniformLocation(shader.program, "u_vp_matrix"); - shader.u_texture = glGetUniformLocation(shader.program, "u_texture"); - } - glGenTextures(1, textures); - glBindTexture(GL_TEXTURE_2D, textures[0]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); - - Create_uvs(uvs, (float)frame_width/TEX_WIDTH, (float)frame_height/TEX_HEIGHT); - - glGenBuffers(3, buffers); - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glBufferData(GL_ARRAY_BUFFER, kVertexCount * sizeof(GLfloat) * 3, vertices, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, buffers[1]); - glBufferData(GL_ARRAY_BUFFER, kVertexCount * sizeof(GLfloat) * 2, uvs, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, kIndexCount * sizeof(GL_UNSIGNED_SHORT), indices, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glDisable(GL_DEPTH_TEST); - glDisable(GL_BLEND); - glDisable(GL_DITHER); -} - -static uint32_t screen_width = 0; -static uint32_t screen_height = 0; - -static EGLDisplay display = NULL; -static EGLSurface surface = NULL; -static EGLContext context = NULL; -static EGL_DISPMANX_WINDOW_T nativewindow; - -static GLfloat proj[4][4]; -static GLint filter_min; -static GLint filter_mag; - -void video_set_filter(uint32_t filter) { - if (filter==0) { - filter_min = GL_NEAREST; - filter_mag = GL_NEAREST; - } else { - filter_min = GL_LINEAR; - filter_mag = GL_LINEAR; - } -} - -void video_init(uint32_t _width, uint32_t _height, uint32_t filter) -{ - if ((_width==0)||(_height==0)) - return; - - frame_width = _width; - frame_height = _height; - - //bcm_host_init(); - - // get an EGL display connection - display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - assert(display != EGL_NO_DISPLAY); - - // initialize the EGL display connection - EGLBoolean result = eglInitialize(display, NULL, NULL); - assert(EGL_FALSE != result); - - // get an appropriate EGL frame buffer configuration - EGLint num_config; - EGLConfig config; - static const EGLint attribute_list[] = - { - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_NONE - }; - result = eglChooseConfig(display, attribute_list, &config, 1, &num_config); - assert(EGL_FALSE != result); - - result = eglBindAPI(EGL_OPENGL_ES_API); - assert(EGL_FALSE != result); - - // create an EGL rendering context - static const EGLint context_attributes[] = - { - EGL_CONTEXT_CLIENT_VERSION, 2, - EGL_NONE - }; - context = eglCreateContext(display, config, EGL_NO_CONTEXT, context_attributes); - assert(context != EGL_NO_CONTEXT); - - // create an EGL window surface - int32_t success = graphics_get_display_size(0, &screen_width, &screen_height); - assert(success >= 0); - - VC_RECT_T dst_rect; - dst_rect.x = 0; - dst_rect.y = 0; - dst_rect.width = screen_width; - dst_rect.height = screen_height; - - VC_RECT_T src_rect; - src_rect.x = 0; - src_rect.y = 0; - src_rect.width = screen_width << 16; - src_rect.height = screen_height << 16; - - DISPMANX_DISPLAY_HANDLE_T dispman_display = vc_dispmanx_display_open(0); - DISPMANX_UPDATE_HANDLE_T dispman_update = vc_dispmanx_update_start(0); - DISPMANX_ELEMENT_HANDLE_T dispman_element = vc_dispmanx_element_add(dispman_update, dispman_display, - 1, &dst_rect, 0, &src_rect, DISPMANX_PROTECTION_NONE, NULL, NULL, DISPMANX_NO_ROTATE); - - nativewindow.element = dispman_element; - nativewindow.width = screen_width; - nativewindow.height = screen_height; - vc_dispmanx_update_submit_sync(dispman_update); - - surface = eglCreateWindowSurface(display, config, &nativewindow, NULL); - assert(surface != EGL_NO_SURFACE); - - // connect the context to the surface - result = eglMakeCurrent(display, surface, surface, context); - assert(EGL_FALSE != result); - - gles2_create(); - - int r=(screen_height*10/frame_height); - int h = (frame_height*r)/10; - int w = (frame_width*r)/10; - if (w>screen_width) { - r = (screen_width*10/frame_width); - h = (frame_height*r)/10; - w = (frame_width*r)/10; - } - glViewport((screen_width-w)/2, (screen_height-h)/2, w, h); - SetOrtho(proj, -0.5f, +0.5f, +0.5f, -0.5f, -1.0f, 1.0f, 1.0f ,1.0f ); - video_set_filter(filter); -} - -static void gles2_destroy() -{ - if(!shader.program) - return; - glDeleteBuffers(3, buffers); SHOW_ERROR - glDeleteProgram(shader.program); SHOW_ERROR -} - -static void SetOrtho(GLfloat m[4][4], GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near, GLfloat far, GLfloat scale_x, GLfloat scale_y) -{ - memset(m, 0, 4*4*sizeof(GLfloat)); - m[0][0] = 2.0f/(right - left)*scale_x; - m[1][1] = 2.0f/(top - bottom)*scale_y; - m[2][2] = -2.0f/(far - near); - m[3][0] = -(right + left)/(right - left); - m[3][1] = -(top + bottom)/(top - bottom); - m[3][2] = -(far + near)/(far - near); - m[3][3] = 1; -} -#define RGB15(r, g, b) (((r) << (5+6)) | ((g) << 6) | (b)) - -static void gles2_Draw( uint16_t *pixels) -{ - if(!shader.program) - return; - - glClear(GL_COLOR_BUFFER_BIT); - - glUseProgram(shader.program); - - glBindTexture(GL_TEXTURE_2D, textures[0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frame_width, frame_height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, pixels); - glActiveTexture(GL_TEXTURE0); - glUniform1i(shader.u_texture, 0); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_mag); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter_min); - glGenerateMipmap(GL_TEXTURE_2D); - - glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); - glVertexAttribPointer(shader.a_position, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), NULL); - glEnableVertexAttribArray(shader.a_position); - - glBindBuffer(GL_ARRAY_BUFFER, buffers[1]); - glVertexAttribPointer(shader.a_texcoord, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), NULL); - glEnableVertexAttribArray(shader.a_texcoord); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[2]); - glUniformMatrix4fv(shader.u_vp_matrix, 1, GL_FALSE, (const GLfloat * )&proj); - glDrawElements(GL_TRIANGLES, kIndexCount, GL_UNSIGNED_SHORT, 0); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - //glFlush(); -} - -void video_close() -{ - gles2_destroy(); - // Release OpenGL resources - eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT ); - eglDestroySurface( display, surface ); - eglDestroyContext( display, context ); - eglTerminate( display ); -} - -void video_draw(uint16_t *pixels) -{ - gles2_Draw (pixels); - eglSwapBuffers(display, surface); -} |