mirror of https://github.com/mgba-emu/mgba.git
OpenGL: Create video backend for GLES2, used on Raspberry Pi
This commit is contained in:
parent
657640c9d5
commit
46e24e84da
|
@ -21,6 +21,7 @@ set(BUILD_PERF OFF CACHE BOOL "Build performance profiling tool")
|
||||||
set(BUILD_STATIC OFF CACHE BOOL "Build a static library")
|
set(BUILD_STATIC OFF CACHE BOOL "Build a static library")
|
||||||
set(BUILD_SHARED ON CACHE BOOL "Build a shared library")
|
set(BUILD_SHARED ON CACHE BOOL "Build a shared library")
|
||||||
set(BUILD_GL ON CACHE STRING "Build with OpenGL")
|
set(BUILD_GL ON CACHE STRING "Build with OpenGL")
|
||||||
|
set(BUILD_GLES2 OFF CACHE STRING "Build with OpenGL|ES 2")
|
||||||
file(GLOB ARM_SRC ${CMAKE_SOURCE_DIR}/src/arm/*.c)
|
file(GLOB ARM_SRC ${CMAKE_SOURCE_DIR}/src/arm/*.c)
|
||||||
file(GLOB GBA_SRC ${CMAKE_SOURCE_DIR}/src/gba/*.c)
|
file(GLOB GBA_SRC ${CMAKE_SOURCE_DIR}/src/gba/*.c)
|
||||||
file(GLOB GBA_CHEATS_SRC ${CMAKE_SOURCE_DIR}/src/gba/cheats/*.c)
|
file(GLOB GBA_CHEATS_SRC ${CMAKE_SOURCE_DIR}/src/gba/cheats/*.c)
|
||||||
|
@ -122,10 +123,11 @@ if(CMAKE_SYSTEM_NAME MATCHES .*BSD)
|
||||||
else()
|
else()
|
||||||
find_feature(USE_CLI_DEBUGGER "libedit")
|
find_feature(USE_CLI_DEBUGGER "libedit")
|
||||||
endif()
|
endif()
|
||||||
if(BUILD_GL)
|
if(BUILD_GL OR BUILD_GLES2)
|
||||||
find_package(OpenGL QUIET)
|
find_package(OpenGL QUIET)
|
||||||
if(NOT OPENGL_FOUND)
|
if(NOT OPENGL_FOUND)
|
||||||
set(BUILD_GL OFF)
|
set(BUILD_GL OFF CACHE BOOL "OpenGL not found" FORCE)
|
||||||
|
set(BUILD_GLES2 OFF CACHE BOOL "OpenGL|ES 2 not found" FORCE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
find_feature(USE_FFMPEG "libavcodec;libavformat;libavresample;libavutil;libswscale")
|
find_feature(USE_FFMPEG "libavcodec;libavformat;libavresample;libavutil;libswscale")
|
||||||
|
@ -176,6 +178,10 @@ if(BUILD_BBB OR BUILD_RASPI OR BUILD_PANDORA)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_RASPI)
|
||||||
|
set(BUILD_GL OFF CACHE BOOL "OpenGL not supported" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(BUILD_PANDORA)
|
if(BUILD_PANDORA)
|
||||||
add_definitions(-DBUILD_PANDORA)
|
add_definitions(-DBUILD_PANDORA)
|
||||||
endif()
|
endif()
|
||||||
|
@ -398,6 +404,10 @@ if(BUILD_GL)
|
||||||
add_definitions(-DBUILD_GL)
|
add_definitions(-DBUILD_GL)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(BUILD_GLES2)
|
||||||
|
add_definitions(-DBUILD_GLES2)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(BUILD_LIBRETRO)
|
if(BUILD_LIBRETRO)
|
||||||
file(GLOB RETRO_SRC ${CMAKE_SOURCE_DIR}/src/platform/libretro/*.c)
|
file(GLOB RETRO_SRC ${CMAKE_SOURCE_DIR}/src/platform/libretro/*.c)
|
||||||
add_library(${BINARY_NAME}_libretro SHARED ${CORE_SRC} ${RETRO_SRC})
|
add_library(${BINARY_NAME}_libretro SHARED ${CORE_SRC} ${RETRO_SRC})
|
||||||
|
|
|
@ -0,0 +1,136 @@
|
||||||
|
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include "gles2.h"
|
||||||
|
|
||||||
|
#include "gba/video.h"
|
||||||
|
|
||||||
|
static const char* const _vertexShader =
|
||||||
|
"attribute vec4 position;\n"
|
||||||
|
"varying vec2 texCoord;\n"
|
||||||
|
|
||||||
|
"void main() {\n"
|
||||||
|
" gl_Position = position;\n"
|
||||||
|
" texCoord = (position.st + vec2(1.0, -1.0)) * vec2(0.46875, -0.3125);\n"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
static const char* const _fragmentShader =
|
||||||
|
"varying vec2 texCoord;\n"
|
||||||
|
"uniform sampler2D tex;\n"
|
||||||
|
|
||||||
|
"void main() {\n"
|
||||||
|
" vec4 color = texture2D(tex, texCoord);\n"
|
||||||
|
" color.a = 1.;\n"
|
||||||
|
" gl_FragColor = color;"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
static const GLfloat _vertices[] = {
|
||||||
|
-1.f, -1.f,
|
||||||
|
-1.f, 1.f,
|
||||||
|
1.f, 1.f,
|
||||||
|
1.f, -1.f,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void GBAGLES2ContextInit(struct VideoBackend* v, WHandle handle) {
|
||||||
|
UNUSED(handle);
|
||||||
|
struct GBAGLES2Context* context = (struct GBAGLES2Context*) v;
|
||||||
|
glGenTextures(1, &context->tex);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, context->tex);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
#ifdef COLOR_16_BIT
|
||||||
|
#ifdef COLOR_5_6_5
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
|
||||||
|
#else
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
glShaderSource(context->fragmentShader, 1, (const GLchar**) &_fragmentShader, 0);
|
||||||
|
glShaderSource(context->vertexShader, 1, (const GLchar**) &_vertexShader, 0);
|
||||||
|
glAttachShader(context->program, context->vertexShader);
|
||||||
|
glAttachShader(context->program, context->fragmentShader);
|
||||||
|
char log[1024];
|
||||||
|
glCompileShader(context->fragmentShader);
|
||||||
|
glCompileShader(context->vertexShader);
|
||||||
|
glGetShaderInfoLog(context->fragmentShader, 1024, 0, log);
|
||||||
|
glGetShaderInfoLog(context->vertexShader, 1024, 0, log);
|
||||||
|
glLinkProgram(context->program);
|
||||||
|
glGetProgramInfoLog(context->program, 1024, 0, log);
|
||||||
|
printf("%s\n", log);
|
||||||
|
context->texLocation = glGetUniformLocation(context->program, "tex");
|
||||||
|
context->positionLocation = glGetAttribLocation(context->program, "position");
|
||||||
|
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GBAGLES2ContextDeinit(struct VideoBackend* v) {
|
||||||
|
struct GBAGLES2Context* context = (struct GBAGLES2Context*) v;
|
||||||
|
glDeleteTextures(1, &context->tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GBAGLES2ContextResized(struct VideoBackend* v, int w, int h) {
|
||||||
|
int drawW = w;
|
||||||
|
int drawH = h;
|
||||||
|
if (v->lockAspectRatio) {
|
||||||
|
if (w * 2 > h * 3) {
|
||||||
|
drawW = h * 3 / 2;
|
||||||
|
} else if (w * 2 < h * 3) {
|
||||||
|
drawH = w * 2 / 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
glViewport(0, 0, 240, 160);
|
||||||
|
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
glViewport((w - drawW) / 2, (h - drawH) / 2, drawW, drawH);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GBAGLES2ContextClear(struct VideoBackend* v) {
|
||||||
|
UNUSED(v);
|
||||||
|
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GBAGLES2ContextDrawFrame(struct VideoBackend* v) {
|
||||||
|
struct GBAGLES2Context* context = (struct GBAGLES2Context*) v;
|
||||||
|
glUseProgram(context->program);
|
||||||
|
glUniform1i(context->texLocation, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, context->tex);
|
||||||
|
glVertexAttribPointer(context->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, _vertices);
|
||||||
|
glEnableVertexAttribArray(context->positionLocation);
|
||||||
|
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GBAGLES2ContextPostFrame(struct VideoBackend* v, const void* frame) {
|
||||||
|
struct GBAGLES2Context* context = (struct GBAGLES2Context*) v;
|
||||||
|
glBindTexture(GL_TEXTURE_2D, context->tex);
|
||||||
|
#ifdef COLOR_16_BIT
|
||||||
|
#ifdef COLOR_5_6_5
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, frame);
|
||||||
|
#else
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frame);
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GBAGLES2ContextCreate(struct GBAGLES2Context* context) {
|
||||||
|
context->d.init = GBAGLES2ContextInit;
|
||||||
|
context->d.deinit = GBAGLES2ContextDeinit;
|
||||||
|
context->d.resized = GBAGLES2ContextResized;
|
||||||
|
context->d.swap = 0;
|
||||||
|
context->d.clear = GBAGLES2ContextClear;
|
||||||
|
context->d.postFrame = GBAGLES2ContextPostFrame;
|
||||||
|
context->d.drawFrame = GBAGLES2ContextDrawFrame;
|
||||||
|
context->d.setMessage = 0;
|
||||||
|
context->d.clearMessage = 0;
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#ifndef GLES2_H
|
||||||
|
#define GLES2_H
|
||||||
|
|
||||||
|
#include <GLES2/gl2.h>
|
||||||
|
|
||||||
|
#include "platform/video-backend.h"
|
||||||
|
|
||||||
|
struct GBAGLES2Context {
|
||||||
|
struct VideoBackend d;
|
||||||
|
|
||||||
|
GLuint tex;
|
||||||
|
GLuint fragmentShader;
|
||||||
|
GLuint vertexShader;
|
||||||
|
GLuint program;
|
||||||
|
GLuint bufferObject;
|
||||||
|
GLuint texLocation;
|
||||||
|
GLuint positionLocation;
|
||||||
|
};
|
||||||
|
|
||||||
|
void GBAGLES2ContextCreate(struct GBAGLES2Context*);
|
||||||
|
|
||||||
|
#endif
|
|
@ -186,7 +186,7 @@ static void _GBAPerfRunloop(struct GBAThread* context, int* frames, bool quiet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GBASyncWaitFrameEnd(&context->sync);
|
GBASyncWaitFrameEnd(&context->sync);
|
||||||
if (*frames == duration) {
|
if (duration > 0 && *frames == duration) {
|
||||||
_GBAPerfShutdown(0);
|
_GBAPerfShutdown(0);
|
||||||
}
|
}
|
||||||
if (_dispatchExiting) {
|
if (_dispatchExiting) {
|
||||||
|
|
|
@ -51,12 +51,14 @@ set(MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/main.c)
|
||||||
|
|
||||||
if(BUILD_RASPI)
|
if(BUILD_RASPI)
|
||||||
add_definitions(-DBUILD_RASPI)
|
add_definitions(-DBUILD_RASPI)
|
||||||
set(EGL_MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/egl-sdl.c)
|
list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c)
|
||||||
set(EGL_LIBRARY "-lEGL -lGLESv2 -lbcm_host")
|
list(APPEND MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/egl-sdl.c)
|
||||||
|
list(APPEND OPENGL_LIBRARY "-lEGL -lGLESv2 -lbcm_host")
|
||||||
|
set(BUILD_GLES2 ON CACHE BOOL "Using OpenGL|ES 2" FORCE)
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fgnu89-inline")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fgnu89-inline")
|
||||||
add_executable(${BINARY_NAME}-rpi ${PLATFORM_SRC} ${MAIN_SRC} ${EGL_MAIN_SRC})
|
add_executable(${BINARY_NAME}-rpi ${PLATFORM_SRC} ${MAIN_SRC})
|
||||||
set_target_properties(${BINARY_NAME}-rpi PROPERTIES COMPILE_DEFINITIONS "${FEATURE_DEFINES}")
|
set_target_properties(${BINARY_NAME}-rpi PROPERTIES COMPILE_DEFINITIONS "${FEATURE_DEFINES}")
|
||||||
target_link_libraries(${BINARY_NAME}-rpi ${BINARY_NAME} ${PLATFORM_LIBRARY} ${EGL_LIBRARY})
|
target_link_libraries(${BINARY_NAME}-rpi ${BINARY_NAME} ${PLATFORM_LIBRARY} ${OPENGL_LIBRARY})
|
||||||
install(TARGETS ${BINARY_NAME}-rpi DESTINATION bin COMPONENT ${BINARY_NAME}-rpi)
|
install(TARGETS ${BINARY_NAME}-rpi DESTINATION bin COMPONENT ${BINARY_NAME}-rpi)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,26 @@
|
||||||
/* Copyright (c) 2013-2014 Jeffrey Pfau
|
/* Copyright (c) 2013-2015 Jeffrey Pfau
|
||||||
*
|
*
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
static const char* _vertexShader =
|
static void _sdlSwap(struct VideoBackend* context) {
|
||||||
"attribute vec4 position;\n"
|
UNUSED(context);
|
||||||
"varying vec2 texCoord;\n"
|
SDL_GL_SwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
"void main() {\n"
|
static bool GBASDLGLES2Init(struct SDLSoftwareRenderer* renderer);
|
||||||
" gl_Position = position;\n"
|
static void GBASDLGLES2Runloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer);
|
||||||
" texCoord = (position.st + vec2(1.0, -1.0)) * vec2(0.46875, -0.3125);\n"
|
static void GBASDLGLES2Deinit(struct SDLSoftwareRenderer* renderer);
|
||||||
"}";
|
|
||||||
|
|
||||||
static const char* _fragmentShader =
|
void GBASDLGLES2Create(struct SDLSoftwareRenderer* renderer) {
|
||||||
"varying vec2 texCoord;\n"
|
renderer->init = GBASDLGLES2Init;
|
||||||
"uniform sampler2D tex;\n"
|
renderer->deinit = GBASDLGLES2Deinit;
|
||||||
|
renderer->runloop = GBASDLGLES2Runloop;
|
||||||
|
}
|
||||||
|
|
||||||
"void main() {\n"
|
bool GBASDLGLES2Init(struct SDLSoftwareRenderer* renderer) {
|
||||||
" vec4 color = texture2D(tex, texCoord);\n"
|
|
||||||
" color.a = 1.;\n"
|
|
||||||
" gl_FragColor = color;"
|
|
||||||
"}";
|
|
||||||
|
|
||||||
static const GLfloat _vertices[] = {
|
|
||||||
-1.f, -1.f,
|
|
||||||
-1.f, 1.f,
|
|
||||||
1.f, 1.f,
|
|
||||||
1.f, -1.f,
|
|
||||||
};
|
|
||||||
|
|
||||||
bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
|
|
||||||
bcm_host_init();
|
bcm_host_init();
|
||||||
renderer->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
renderer->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||||
int major, minor;
|
int major, minor;
|
||||||
|
@ -103,36 +92,19 @@ bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
|
||||||
|
|
||||||
renderer->d.outputBuffer = memalign(16, 256 * 256 * 4);
|
renderer->d.outputBuffer = memalign(16, 256 * 256 * 4);
|
||||||
renderer->d.outputBufferStride = 256;
|
renderer->d.outputBufferStride = 256;
|
||||||
glGenTextures(1, &renderer->tex);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, renderer->tex);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
|
||||||
renderer->fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
|
||||||
renderer->vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
|
||||||
renderer->program = glCreateProgram();
|
|
||||||
|
|
||||||
glShaderSource(renderer->fragmentShader, 1, (const GLchar**) &_fragmentShader, 0);
|
GBAGLES2ContextCreate(&renderer->gl);
|
||||||
glShaderSource(renderer->vertexShader, 1, (const GLchar**) &_vertexShader, 0);
|
renderer->gl.d.user = renderer;
|
||||||
glAttachShader(renderer->program, renderer->vertexShader);
|
renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio;
|
||||||
glAttachShader(renderer->program, renderer->fragmentShader);
|
renderer->gl.d.filter = renderer->filter;
|
||||||
char log[1024];
|
renderer->gl.d.swap = _sdlSwap;
|
||||||
glCompileShader(renderer->fragmentShader);
|
renderer->gl.d.init(&renderer->gl.d, 0);
|
||||||
glCompileShader(renderer->vertexShader);
|
return true;
|
||||||
glGetShaderInfoLog(renderer->fragmentShader, 1024, 0, log);
|
|
||||||
glGetShaderInfoLog(renderer->vertexShader, 1024, 0, log);
|
|
||||||
glLinkProgram(renderer->program);
|
|
||||||
glGetProgramInfoLog(renderer->program, 1024, 0, log);
|
|
||||||
printf("%s\n", log);
|
|
||||||
renderer->texLocation = glGetUniformLocation(renderer->program, "tex");
|
|
||||||
renderer->positionLocation = glGetAttribLocation(renderer->program, "position");
|
|
||||||
glClearColor(1.f, 0.f, 0.f, 1.f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
|
void GBASDLGLES2Runloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
struct VideoBackend* v = &renderer->gl.d;
|
||||||
|
|
||||||
while (context->state < THREAD_EXITING) {
|
while (context->state < THREAD_EXITING) {
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
|
@ -140,27 +112,22 @@ void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* render
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
|
if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
|
||||||
glViewport(0, 0, 240, 160);
|
v->postFrame(v, renderer->d.outputBuffer);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
glUseProgram(renderer->program);
|
|
||||||
glUniform1i(renderer->texLocation, 0);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, renderer->tex);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, renderer->d.outputBuffer);
|
|
||||||
glVertexAttribPointer(renderer->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, _vertices);
|
|
||||||
glEnableVertexAttribArray(renderer->positionLocation);
|
|
||||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
|
||||||
glUseProgram(0);
|
|
||||||
eglSwapBuffers(renderer->display, renderer->surface);
|
|
||||||
}
|
}
|
||||||
|
v->drawFrame(v);
|
||||||
GBASyncWaitFrameEnd(&context->sync);
|
GBASyncWaitFrameEnd(&context->sync);
|
||||||
|
eglSwapBuffers(renderer->display, renderer->surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBASDLDeinit(struct SDLSoftwareRenderer* renderer) {
|
void GBASDLGLES2Deinit(struct SDLSoftwareRenderer* renderer) {
|
||||||
|
if (renderer->gl.d.deinit) {
|
||||||
|
renderer->gl.d.deinit(&renderer->gl.d);
|
||||||
|
}
|
||||||
eglMakeCurrent(renderer->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(renderer->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
eglDestroySurface(renderer->display, renderer->surface);
|
eglDestroySurface(renderer->display, renderer->surface);
|
||||||
eglDestroyContext(renderer->display, renderer->context);
|
eglDestroyContext(renderer->display, renderer->context);
|
||||||
eglTerminate(renderer->display);
|
eglTerminate(renderer->display);
|
||||||
|
free(renderer->d.outputBuffer);
|
||||||
bcm_host_deinit();
|
bcm_host_deinit();
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,8 @@ int main(int argc, char** argv) {
|
||||||
|
|
||||||
#ifdef BUILD_GL
|
#ifdef BUILD_GL
|
||||||
GBASDLGLCreate(&renderer);
|
GBASDLGLCreate(&renderer);
|
||||||
|
#elif defined(BUILD_GLES2)
|
||||||
|
GBASDLGLES2Create(&renderer);
|
||||||
#else
|
#else
|
||||||
GBASDLSWCreate(&renderer);
|
GBASDLSWCreate(&renderer);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,13 +20,16 @@
|
||||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
#include <GLES2/gl2.h>
|
|
||||||
#include <EGL/egl.h>
|
#include <EGL/egl.h>
|
||||||
|
|
||||||
#include <bcm_host.h>
|
#include <bcm_host.h>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BUILD_GLES2
|
||||||
|
#include "platform/opengl/gles2.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_PIXMAN
|
#ifdef USE_PIXMAN
|
||||||
#include <pixman.h>
|
#include <pixman.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -69,13 +72,7 @@ struct SDLSoftwareRenderer {
|
||||||
EGLSurface surface;
|
EGLSurface surface;
|
||||||
EGLContext context;
|
EGLContext context;
|
||||||
EGL_DISPMANX_WINDOW_T window;
|
EGL_DISPMANX_WINDOW_T window;
|
||||||
GLuint tex;
|
struct GBAGLES2Context gl;
|
||||||
GLuint fragmentShader;
|
|
||||||
GLuint vertexShader;
|
|
||||||
GLuint program;
|
|
||||||
GLuint bufferObject;
|
|
||||||
GLuint texLocation;
|
|
||||||
GLuint positionLocation;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BUILD_PANDORA
|
#ifdef BUILD_PANDORA
|
||||||
|
@ -90,4 +87,8 @@ void GBASDLSWCreate(struct SDLSoftwareRenderer* renderer);
|
||||||
#ifdef BUILD_GL
|
#ifdef BUILD_GL
|
||||||
void GBASDLGLCreate(struct SDLSoftwareRenderer* renderer);
|
void GBASDLGLCreate(struct SDLSoftwareRenderer* renderer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BUILD_GLES2
|
||||||
|
void GBASDLGLES2Create(struct SDLSoftwareRenderer* renderer);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue