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_SHARED ON CACHE BOOL "Build a shared library")
|
||||
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 GBA_SRC ${CMAKE_SOURCE_DIR}/src/gba/*.c)
|
||||
file(GLOB GBA_CHEATS_SRC ${CMAKE_SOURCE_DIR}/src/gba/cheats/*.c)
|
||||
|
@ -122,10 +123,11 @@ if(CMAKE_SYSTEM_NAME MATCHES .*BSD)
|
|||
else()
|
||||
find_feature(USE_CLI_DEBUGGER "libedit")
|
||||
endif()
|
||||
if(BUILD_GL)
|
||||
if(BUILD_GL OR BUILD_GLES2)
|
||||
find_package(OpenGL QUIET)
|
||||
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()
|
||||
find_feature(USE_FFMPEG "libavcodec;libavformat;libavresample;libavutil;libswscale")
|
||||
|
@ -176,6 +178,10 @@ if(BUILD_BBB OR BUILD_RASPI OR BUILD_PANDORA)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if(BUILD_RASPI)
|
||||
set(BUILD_GL OFF CACHE BOOL "OpenGL not supported" FORCE)
|
||||
endif()
|
||||
|
||||
if(BUILD_PANDORA)
|
||||
add_definitions(-DBUILD_PANDORA)
|
||||
endif()
|
||||
|
@ -398,6 +404,10 @@ if(BUILD_GL)
|
|||
add_definitions(-DBUILD_GL)
|
||||
endif()
|
||||
|
||||
if(BUILD_GLES2)
|
||||
add_definitions(-DBUILD_GLES2)
|
||||
endif()
|
||||
|
||||
if(BUILD_LIBRETRO)
|
||||
file(GLOB RETRO_SRC ${CMAKE_SOURCE_DIR}/src/platform/libretro/*.c)
|
||||
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);
|
||||
if (*frames == duration) {
|
||||
if (duration > 0 && *frames == duration) {
|
||||
_GBAPerfShutdown(0);
|
||||
}
|
||||
if (_dispatchExiting) {
|
||||
|
|
|
@ -51,12 +51,14 @@ set(MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/main.c)
|
|||
|
||||
if(BUILD_RASPI)
|
||||
add_definitions(-DBUILD_RASPI)
|
||||
set(EGL_MAIN_SRC ${CMAKE_SOURCE_DIR}/src/platform/sdl/egl-sdl.c)
|
||||
set(EGL_LIBRARY "-lEGL -lGLESv2 -lbcm_host")
|
||||
list(APPEND PLATFORM_SRC ${CMAKE_SOURCE_DIR}/src/platform/opengl/gles2.c)
|
||||
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")
|
||||
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}")
|
||||
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)
|
||||
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
|
||||
* 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 "main.h"
|
||||
|
||||
static const char* _vertexShader =
|
||||
"attribute vec4 position;\n"
|
||||
"varying vec2 texCoord;\n"
|
||||
static void _sdlSwap(struct VideoBackend* context) {
|
||||
UNUSED(context);
|
||||
SDL_GL_SwapBuffers();
|
||||
}
|
||||
|
||||
"void main() {\n"
|
||||
" gl_Position = position;\n"
|
||||
" texCoord = (position.st + vec2(1.0, -1.0)) * vec2(0.46875, -0.3125);\n"
|
||||
"}";
|
||||
static bool GBASDLGLES2Init(struct SDLSoftwareRenderer* renderer);
|
||||
static void GBASDLGLES2Runloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer);
|
||||
static void GBASDLGLES2Deinit(struct SDLSoftwareRenderer* renderer);
|
||||
|
||||
static const char* _fragmentShader =
|
||||
"varying vec2 texCoord;\n"
|
||||
"uniform sampler2D tex;\n"
|
||||
void GBASDLGLES2Create(struct SDLSoftwareRenderer* renderer) {
|
||||
renderer->init = GBASDLGLES2Init;
|
||||
renderer->deinit = GBASDLGLES2Deinit;
|
||||
renderer->runloop = GBASDLGLES2Runloop;
|
||||
}
|
||||
|
||||
"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,
|
||||
};
|
||||
|
||||
bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
|
||||
bool GBASDLGLES2Init(struct SDLSoftwareRenderer* renderer) {
|
||||
bcm_host_init();
|
||||
renderer->display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
int major, minor;
|
||||
|
@ -103,36 +92,19 @@ bool GBASDLInit(struct SDLSoftwareRenderer* renderer) {
|
|||
|
||||
renderer->d.outputBuffer = memalign(16, 256 * 256 * 4);
|
||||
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);
|
||||
glShaderSource(renderer->vertexShader, 1, (const GLchar**) &_vertexShader, 0);
|
||||
glAttachShader(renderer->program, renderer->vertexShader);
|
||||
glAttachShader(renderer->program, renderer->fragmentShader);
|
||||
char log[1024];
|
||||
glCompileShader(renderer->fragmentShader);
|
||||
glCompileShader(renderer->vertexShader);
|
||||
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);
|
||||
GBAGLES2ContextCreate(&renderer->gl);
|
||||
renderer->gl.d.user = renderer;
|
||||
renderer->gl.d.lockAspectRatio = renderer->lockAspectRatio;
|
||||
renderer->gl.d.filter = renderer->filter;
|
||||
renderer->gl.d.swap = _sdlSwap;
|
||||
renderer->gl.d.init(&renderer->gl.d, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
|
||||
void GBASDLGLES2Runloop(struct GBAThread* context, struct SDLSoftwareRenderer* renderer) {
|
||||
SDL_Event event;
|
||||
struct VideoBackend* v = &renderer->gl.d;
|
||||
|
||||
while (context->state < THREAD_EXITING) {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
|
@ -140,27 +112,22 @@ void GBASDLRunloop(struct GBAThread* context, struct SDLSoftwareRenderer* render
|
|||
}
|
||||
|
||||
if (GBASyncWaitFrameStart(&context->sync, context->frameskip)) {
|
||||
glViewport(0, 0, 240, 160);
|
||||
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->postFrame(v, renderer->d.outputBuffer);
|
||||
}
|
||||
v->drawFrame(v);
|
||||
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);
|
||||
eglDestroySurface(renderer->display, renderer->surface);
|
||||
eglDestroyContext(renderer->display, renderer->context);
|
||||
eglTerminate(renderer->display);
|
||||
free(renderer->d.outputBuffer);
|
||||
bcm_host_deinit();
|
||||
}
|
||||
|
|
|
@ -86,6 +86,8 @@ int main(int argc, char** argv) {
|
|||
|
||||
#ifdef BUILD_GL
|
||||
GBASDLGLCreate(&renderer);
|
||||
#elif defined(BUILD_GLES2)
|
||||
GBASDLGLES2Create(&renderer);
|
||||
#else
|
||||
GBASDLSWCreate(&renderer);
|
||||
#endif
|
||||
|
|
|
@ -20,13 +20,16 @@
|
|||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
|
||||
#include <SDL/SDL.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <EGL/egl.h>
|
||||
|
||||
#include <bcm_host.h>
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_GLES2
|
||||
#include "platform/opengl/gles2.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_PIXMAN
|
||||
#include <pixman.h>
|
||||
#endif
|
||||
|
@ -69,13 +72,7 @@ struct SDLSoftwareRenderer {
|
|||
EGLSurface surface;
|
||||
EGLContext context;
|
||||
EGL_DISPMANX_WINDOW_T window;
|
||||
GLuint tex;
|
||||
GLuint fragmentShader;
|
||||
GLuint vertexShader;
|
||||
GLuint program;
|
||||
GLuint bufferObject;
|
||||
GLuint texLocation;
|
||||
GLuint positionLocation;
|
||||
struct GBAGLES2Context gl;
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_PANDORA
|
||||
|
@ -90,4 +87,8 @@ void GBASDLSWCreate(struct SDLSoftwareRenderer* renderer);
|
|||
#ifdef BUILD_GL
|
||||
void GBASDLGLCreate(struct SDLSoftwareRenderer* renderer);
|
||||
#endif
|
||||
|
||||
#ifdef BUILD_GLES2
|
||||
void GBASDLGLES2Create(struct SDLSoftwareRenderer* renderer);
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue