OPENGL: Merge both OpenGL contexts
This commit is contained in:
parent
9aef2f7b98
commit
4ab044a254
39 changed files with 392 additions and 593 deletions
|
@ -93,19 +93,22 @@ void AndroidGraphicsManager::initSurface() {
|
||||||
assert(!JNI::haveSurface());
|
assert(!JNI::haveSurface());
|
||||||
JNI::initSurface();
|
JNI::initSurface();
|
||||||
|
|
||||||
// Notify the OpenGL code about our context.
|
|
||||||
setContextType(OpenGL::kContextGLES2);
|
|
||||||
|
|
||||||
if (JNI::egl_bits_per_pixel == 16) {
|
if (JNI::egl_bits_per_pixel == 16) {
|
||||||
// We default to RGB565 and RGBA5551 which is closest to what we setup in Java side
|
// We default to RGB565 and RGBA5551 which is closest to what we setup in Java side
|
||||||
notifyContextCreate(Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0), Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
|
notifyContextCreate(OpenGL::kContextGLES2,
|
||||||
|
Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0),
|
||||||
|
Graphics::PixelFormat(2, 5, 5, 5, 1, 11, 6, 1, 0));
|
||||||
} else {
|
} else {
|
||||||
// If not 16, this must be 24 or 32 bpp so make use of them
|
// If not 16, this must be 24 or 32 bpp so make use of them
|
||||||
|
notifyContextCreate(OpenGL::kContextGLES2,
|
||||||
#ifdef SCUMM_BIG_ENDIAN
|
#ifdef SCUMM_BIG_ENDIAN
|
||||||
notifyContextCreate(Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0), Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0));
|
Graphics::PixelFormat(3, 8, 8, 8, 0, 16, 8, 0, 0),
|
||||||
|
Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0)
|
||||||
#else
|
#else
|
||||||
notifyContextCreate(Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0), Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24));
|
Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 8, 16, 0),
|
||||||
|
Graphics::PixelFormat(4, 8, 8, 8, 8, 0, 8, 16, 24)
|
||||||
#endif
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_touchcontrols) {
|
if (_touchcontrols) {
|
||||||
|
@ -203,8 +206,8 @@ void AndroidGraphicsManager::refreshScreen() {
|
||||||
|
|
||||||
void AndroidGraphicsManager::touchControlDraw(int16 x, int16 y, int16 w, int16 h, const Common::Rect &clip) {
|
void AndroidGraphicsManager::touchControlDraw(int16 x, int16 y, int16 w, int16 h, const Common::Rect &clip) {
|
||||||
_backBuffer.enableBlend(OpenGL::Framebuffer::kBlendModeTraditionalTransparency);
|
_backBuffer.enableBlend(OpenGL::Framebuffer::kBlendModeTraditionalTransparency);
|
||||||
OpenGL::g_context.getActivePipeline()->drawTexture(_touchcontrols->getGLTexture(),
|
OpenGL::Pipeline::getActivePipeline()->drawTexture(_touchcontrols->getGLTexture(),
|
||||||
x, y, w, h, clip);
|
x, y, w, h, clip);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AndroidGraphicsManager::touchControlNotifyChanged() {
|
void AndroidGraphicsManager::touchControlNotifyChanged() {
|
||||||
|
@ -212,12 +215,6 @@ void AndroidGraphicsManager::touchControlNotifyChanged() {
|
||||||
_forceRedraw = true;
|
_forceRedraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *AndroidGraphicsManager::getProcAddress(const char *name) const {
|
|
||||||
ENTER("%s", name);
|
|
||||||
|
|
||||||
return androidGLgetProcAddress(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AndroidGraphicsManager::notifyMousePosition(Common::Point &mouse) {
|
bool AndroidGraphicsManager::notifyMousePosition(Common::Point &mouse) {
|
||||||
mouse.x = CLIP<int16>(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right);
|
mouse.x = CLIP<int16>(mouse.x, _activeArea.drawRect.left, _activeArea.drawRect.right);
|
||||||
mouse.y = CLIP<int16>(mouse.y, _activeArea.drawRect.top, _activeArea.drawRect.bottom);
|
mouse.y = CLIP<int16>(mouse.y, _activeArea.drawRect.top, _activeArea.drawRect.bottom);
|
||||||
|
|
|
@ -98,8 +98,6 @@ protected:
|
||||||
|
|
||||||
void refreshScreen() override;
|
void refreshScreen() override;
|
||||||
|
|
||||||
void *getProcAddress(const char *name) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OpenGL::Surface *_touchcontrols;
|
OpenGL::Surface *_touchcontrols;
|
||||||
int _old_touch_mode;
|
int _old_touch_mode;
|
||||||
|
|
|
@ -1,240 +0,0 @@
|
||||||
/* ScummVM - Graphic Adventure Engine
|
|
||||||
*
|
|
||||||
* ScummVM is the legal property of its developers, whose names
|
|
||||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
||||||
* file distributed with this source distribution.
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define GLAD_GL_IMPLEMENTATION
|
|
||||||
|
|
||||||
#include "backends/graphics/opengl/opengl-sys.h"
|
|
||||||
#include "backends/graphics/opengl/opengl-graphics.h"
|
|
||||||
#include "backends/graphics/opengl/shader.h"
|
|
||||||
#include "backends/graphics/opengl/pipelines/pipeline.h"
|
|
||||||
#include "backends/graphics/opengl/framebuffer.h"
|
|
||||||
|
|
||||||
#include "common/tokenizer.h"
|
|
||||||
#include "common/debug.h"
|
|
||||||
|
|
||||||
namespace OpenGL {
|
|
||||||
|
|
||||||
void Context::reset() {
|
|
||||||
maxTextureSize = 0;
|
|
||||||
|
|
||||||
majorVersion = 0;
|
|
||||||
minorVersion = 0;
|
|
||||||
|
|
||||||
NPOTSupported = false;
|
|
||||||
shadersSupported = false;
|
|
||||||
multitextureSupported = false;
|
|
||||||
framebufferObjectSupported = false;
|
|
||||||
packedPixelsSupported = false;
|
|
||||||
textureEdgeClampSupported = false;
|
|
||||||
|
|
||||||
isInitialized = false;
|
|
||||||
|
|
||||||
activePipeline = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pipeline *Context::setPipeline(Pipeline *pipeline) {
|
|
||||||
Pipeline *oldPipeline = activePipeline;
|
|
||||||
if (oldPipeline) {
|
|
||||||
oldPipeline->deactivate();
|
|
||||||
}
|
|
||||||
|
|
||||||
activePipeline = pipeline;
|
|
||||||
if (activePipeline) {
|
|
||||||
activePipeline->activate();
|
|
||||||
}
|
|
||||||
|
|
||||||
return oldPipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
Context g_context;
|
|
||||||
|
|
||||||
void OpenGLGraphicsManager::setContextType(ContextType type) {
|
|
||||||
#if USE_FORCED_GL
|
|
||||||
type = kContextGL;
|
|
||||||
#elif USE_FORCED_GLES
|
|
||||||
type = kContextGLES;
|
|
||||||
#elif USE_FORCED_GLES2
|
|
||||||
type = kContextGLES2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_context.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_GLAD
|
|
||||||
static GLADapiproc loadFunc(void *userptr, const char *name) {
|
|
||||||
OpenGLGraphicsManager *openglGraphicsManager = (OpenGLGraphicsManager *)userptr;
|
|
||||||
return (GLADapiproc)openglGraphicsManager->getProcAddress(name);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void OpenGLGraphicsManager::initializeGLContext() {
|
|
||||||
// Initialize default state.
|
|
||||||
g_context.reset();
|
|
||||||
|
|
||||||
#ifdef USE_GLAD
|
|
||||||
switch (g_context.type) {
|
|
||||||
case kContextGL:
|
|
||||||
gladLoadGLUserPtr(loadFunc, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kContextGLES:
|
|
||||||
gladLoadGLES1UserPtr(loadFunc, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kContextGLES2:
|
|
||||||
gladLoadGLES2UserPtr(loadFunc, this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
g_context.isInitialized = true;
|
|
||||||
|
|
||||||
// Obtain maximum texture size.
|
|
||||||
GL_CALL(glGetIntegerv(GL_MAX_TEXTURE_SIZE, &g_context.maxTextureSize));
|
|
||||||
debug(5, "OpenGL maximum texture size: %d", g_context.maxTextureSize);
|
|
||||||
|
|
||||||
const char *verString = (const char *)glGetString(GL_VERSION);
|
|
||||||
debug(5, "OpenGL version: %s", verString);
|
|
||||||
|
|
||||||
if (g_context.type == kContextGL) {
|
|
||||||
// OpenGL version number is either of the form major.minor or major.minor.release,
|
|
||||||
// where the numbers all have one or more digits
|
|
||||||
if (sscanf(verString, "%d.%d", &g_context.majorVersion, &g_context.minorVersion) != 2) {
|
|
||||||
g_context.majorVersion = g_context.minorVersion = 0;
|
|
||||||
warning("Could not parse GL version '%s'", verString);
|
|
||||||
}
|
|
||||||
} else if (g_context.type == kContextGLES) {
|
|
||||||
// The form of the string is "OpenGL ES-<profile> <major>.<minor>",
|
|
||||||
// where <profile> is either "CM" (Common) or "CL" (Common-Lite),
|
|
||||||
// and <major> and <minor> are integers.
|
|
||||||
char profile[3];
|
|
||||||
if (sscanf(verString, "OpenGL ES-%2s %d.%d", profile,
|
|
||||||
&g_context.majorVersion, &g_context.minorVersion) != 3) {
|
|
||||||
g_context.majorVersion = g_context.minorVersion = 0;
|
|
||||||
warning("Could not parse GL ES version '%s'", verString);
|
|
||||||
}
|
|
||||||
} else if (g_context.type == kContextGLES2) {
|
|
||||||
// The version is of the form
|
|
||||||
// OpenGL<space>ES<space><version number><space><vendor-specific information>
|
|
||||||
// version number format is not defined
|
|
||||||
// There is only OpenGL ES 2.0 anyway
|
|
||||||
if (sscanf(verString, "OpenGL ES %d.%d", &g_context.majorVersion, &g_context.minorVersion) != 2) {
|
|
||||||
g_context.minorVersion = 0;
|
|
||||||
if (sscanf(verString, "OpenGL ES %d ", &g_context.majorVersion) != 1) {
|
|
||||||
g_context.majorVersion = 0;
|
|
||||||
warning("Could not parse GL ES 2 version '%s'", verString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *extString = (const char *)glGetString(GL_EXTENSIONS);
|
|
||||||
debug(5, "OpenGL extensions: %s", extString);
|
|
||||||
|
|
||||||
bool ARBShaderObjects = false;
|
|
||||||
bool ARBShadingLanguage100 = false;
|
|
||||||
bool ARBVertexShader = false;
|
|
||||||
bool ARBFragmentShader = false;
|
|
||||||
|
|
||||||
Common::StringTokenizer tokenizer(extString, " ");
|
|
||||||
while (!tokenizer.empty()) {
|
|
||||||
Common::String token = tokenizer.nextToken();
|
|
||||||
|
|
||||||
if (token == "GL_ARB_texture_non_power_of_two" || token == "GL_OES_texture_npot") {
|
|
||||||
g_context.NPOTSupported = true;
|
|
||||||
} else if (token == "GL_ARB_shader_objects") {
|
|
||||||
ARBShaderObjects = true;
|
|
||||||
} else if (token == "GL_ARB_shading_language_100") {
|
|
||||||
ARBShadingLanguage100 = true;
|
|
||||||
} else if (token == "GL_ARB_vertex_shader") {
|
|
||||||
ARBVertexShader = true;
|
|
||||||
} else if (token == "GL_ARB_fragment_shader") {
|
|
||||||
ARBFragmentShader = true;
|
|
||||||
} else if (token == "GL_ARB_multitexture") {
|
|
||||||
g_context.multitextureSupported = true;
|
|
||||||
} else if (token == "GL_ARB_framebuffer_object") {
|
|
||||||
g_context.framebufferObjectSupported = true;
|
|
||||||
} else if (token == "GL_EXT_packed_pixels" || token == "GL_APPLE_packed_pixels") {
|
|
||||||
g_context.packedPixelsSupported = true;
|
|
||||||
} else if (token == "GL_SGIS_texture_edge_clamp") {
|
|
||||||
g_context.textureEdgeClampSupported = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_context.type == kContextGLES2) {
|
|
||||||
// GLES2 always has (limited) NPOT support.
|
|
||||||
g_context.NPOTSupported = true;
|
|
||||||
|
|
||||||
// GLES2 always has shader support.
|
|
||||||
g_context.shadersSupported = true;
|
|
||||||
|
|
||||||
// GLES2 always has multi texture support.
|
|
||||||
g_context.multitextureSupported = true;
|
|
||||||
|
|
||||||
// GLES2 always has FBO support.
|
|
||||||
g_context.framebufferObjectSupported = true;
|
|
||||||
} else {
|
|
||||||
g_context.shadersSupported = ARBShaderObjects & ARBShadingLanguage100 & ARBVertexShader & ARBFragmentShader;
|
|
||||||
}
|
|
||||||
|
|
||||||
// OpenGL 1.2 and later always has packed pixels and texture edge clamp support
|
|
||||||
if (g_context.type != kContextGL || g_context.isGLVersionOrHigher(1, 2)) {
|
|
||||||
g_context.packedPixelsSupported = true;
|
|
||||||
g_context.textureEdgeClampSupported = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log context type.
|
|
||||||
switch (g_context.type) {
|
|
||||||
case kContextGL:
|
|
||||||
debug(5, "OpenGL: GL context initialized");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kContextGLES:
|
|
||||||
debug(5, "OpenGL: GLES context initialized");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case kContextGLES2:
|
|
||||||
debug(5, "OpenGL: GLES2 context initialized");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
warning("OpenGL: Unknown context initialized");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log features supported by GL context.
|
|
||||||
#if !USE_FORCED_GLES
|
|
||||||
if (g_context.shadersSupported)
|
|
||||||
debug(5, "GLSL version: %s", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
|
||||||
#endif
|
|
||||||
debug(5, "OpenGL vendor: %s", glGetString(GL_VENDOR));
|
|
||||||
debug(5, "OpenGL renderer: %s", glGetString(GL_RENDERER));
|
|
||||||
debug(5, "OpenGL: NPOT texture support: %d", g_context.NPOTSupported);
|
|
||||||
debug(5, "OpenGL: Shader support: %d", g_context.shadersSupported);
|
|
||||||
debug(5, "OpenGL: Multitexture support: %d", g_context.multitextureSupported);
|
|
||||||
debug(5, "OpenGL: FBO support: %d", g_context.framebufferObjectSupported);
|
|
||||||
debug(5, "OpenGL: Packed pixels support: %d", g_context.packedPixelsSupported);
|
|
||||||
debug(5, "OpenGL: Texture edge clamping support: %d", g_context.textureEdgeClampSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End of namespace OpenGL
|
|
|
@ -20,11 +20,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "backends/graphics/opengl/debug.h"
|
#include "backends/graphics/opengl/debug.h"
|
||||||
#include "backends/graphics/opengl/opengl-sys.h"
|
|
||||||
|
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
|
#include "graphics/opengl/system_headers.h"
|
||||||
|
|
||||||
#ifdef OPENGL_DEBUG
|
#ifdef OPENGL_DEBUG
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#ifndef BACKENDS_GRAPHICS_OPENGL_DEBUG_H
|
#ifndef BACKENDS_GRAPHICS_OPENGL_DEBUG_H
|
||||||
#define BACKENDS_GRAPHICS_OPENGL_DEBUG_H
|
#define BACKENDS_GRAPHICS_OPENGL_DEBUG_H
|
||||||
|
|
||||||
|
#include "graphics/opengl/context.h"
|
||||||
|
|
||||||
#define OPENGL_DEBUG
|
#define OPENGL_DEBUG
|
||||||
|
|
||||||
#ifdef OPENGL_DEBUG
|
#ifdef OPENGL_DEBUG
|
||||||
|
@ -35,4 +37,13 @@ void checkGLError(const char *expr, const char *file, int line);
|
||||||
#define GL_WRAP_DEBUG(call, name) do { (call); } while (false)
|
#define GL_WRAP_DEBUG(call, name) do { (call); } while (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define GL_CALL(x) GL_WRAP_DEBUG(x, x)
|
||||||
|
#define GL_CALL_SAFE(func, params) \
|
||||||
|
do { \
|
||||||
|
if (OpenGLContext.type != kContextNone) { \
|
||||||
|
GL_CALL(func params); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#define GL_ASSIGN(var, x) GL_WRAP_DEBUG(var = x, x)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "backends/graphics/opengl/debug.h"
|
||||||
#include "backends/graphics/opengl/framebuffer.h"
|
#include "backends/graphics/opengl/framebuffer.h"
|
||||||
#include "backends/graphics/opengl/texture.h"
|
#include "backends/graphics/opengl/texture.h"
|
||||||
#include "backends/graphics/opengl/pipelines/pipeline.h"
|
#include "backends/graphics/opengl/pipelines/pipeline.h"
|
||||||
|
@ -96,7 +97,7 @@ void Framebuffer::applyViewport() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::applyProjectionMatrix() {
|
void Framebuffer::applyProjectionMatrix() {
|
||||||
g_context.getActivePipeline()->setProjectionMatrix(_projectionMatrix);
|
Pipeline::getActivePipeline()->setProjectionMatrix(_projectionMatrix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Framebuffer::applyClearColor() {
|
void Framebuffer::applyClearColor() {
|
||||||
|
@ -139,7 +140,7 @@ void Framebuffer::applyScissorBox() {
|
||||||
|
|
||||||
void Backbuffer::activateInternal() {
|
void Backbuffer::activateInternal() {
|
||||||
#if !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
if (g_context.framebufferObjectSupported) {
|
if (OpenGLContext.framebufferObjectSupported) {
|
||||||
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
GL_CALL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#ifndef BACKENDS_GRAPHICS_OPENGL_FRAMEBUFFER_H
|
#ifndef BACKENDS_GRAPHICS_OPENGL_FRAMEBUFFER_H
|
||||||
#define BACKENDS_GRAPHICS_OPENGL_FRAMEBUFFER_H
|
#define BACKENDS_GRAPHICS_OPENGL_FRAMEBUFFER_H
|
||||||
|
|
||||||
#include "backends/graphics/opengl/opengl-sys.h"
|
#include "graphics/opengl/system_headers.h"
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
|
|
||||||
#include "backends/graphics/opengl/opengl-graphics.h"
|
#include "backends/graphics/opengl/opengl-graphics.h"
|
||||||
|
#include "backends/graphics/opengl/debug.h"
|
||||||
#include "backends/graphics/opengl/texture.h"
|
#include "backends/graphics/opengl/texture.h"
|
||||||
#include "backends/graphics/opengl/pipelines/pipeline.h"
|
#include "backends/graphics/opengl/pipelines/pipeline.h"
|
||||||
#include "backends/graphics/opengl/pipelines/fixed.h"
|
#include "backends/graphics/opengl/pipelines/fixed.h"
|
||||||
|
@ -79,7 +80,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
memset(_gamePalette, 0, sizeof(_gamePalette));
|
memset(_gamePalette, 0, sizeof(_gamePalette));
|
||||||
g_context.reset();
|
OpenGLContext.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLGraphicsManager::~OpenGLGraphicsManager() {
|
OpenGLGraphicsManager::~OpenGLGraphicsManager() {
|
||||||
|
@ -391,8 +392,8 @@ OSystem::TransactionError OpenGLGraphicsManager::endGFXTransaction() {
|
||||||
// a context existing before, which means we don't know the maximum
|
// a context existing before, which means we don't know the maximum
|
||||||
// supported texture size before this. Thus, we check whether the
|
// supported texture size before this. Thus, we check whether the
|
||||||
// requested game resolution is supported over here.
|
// requested game resolution is supported over here.
|
||||||
|| ( _currentState.gameWidth > (uint)g_context.maxTextureSize
|
|| ( _currentState.gameWidth > (uint)OpenGLContext.maxTextureSize
|
||||||
|| _currentState.gameHeight > (uint)g_context.maxTextureSize)) {
|
|| _currentState.gameHeight > (uint)OpenGLContext.maxTextureSize)) {
|
||||||
if (_transactionMode == kTransactionActive) {
|
if (_transactionMode == kTransactionActive) {
|
||||||
// Try to setup the old state in case its valid and is
|
// Try to setup the old state in case its valid and is
|
||||||
// actually different from the new one.
|
// actually different from the new one.
|
||||||
|
@ -587,21 +588,21 @@ void OpenGLGraphicsManager::updateScreen() {
|
||||||
_backBuffer.enableBlend(Framebuffer::kBlendModeDisabled);
|
_backBuffer.enableBlend(Framebuffer::kBlendModeDisabled);
|
||||||
|
|
||||||
// First step: Draw the (virtual) game screen.
|
// First step: Draw the (virtual) game screen.
|
||||||
g_context.getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
|
Pipeline::getActivePipeline()->drawTexture(_gameScreen->getGLTexture(), _gameDrawRect.left, _gameDrawRect.top, _gameDrawRect.width(), _gameDrawRect.height());
|
||||||
|
|
||||||
// Second step: Draw the overlay if visible.
|
// Second step: Draw the overlay if visible.
|
||||||
if (_overlayVisible) {
|
if (_overlayVisible) {
|
||||||
int dstX = (_windowWidth - _overlayDrawRect.width()) / 2;
|
int dstX = (_windowWidth - _overlayDrawRect.width()) / 2;
|
||||||
int dstY = (_windowHeight - _overlayDrawRect.height()) / 2;
|
int dstY = (_windowHeight - _overlayDrawRect.height()) / 2;
|
||||||
_backBuffer.enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
|
_backBuffer.enableBlend(Framebuffer::kBlendModeTraditionalTransparency);
|
||||||
g_context.getActivePipeline()->drawTexture(_overlay->getGLTexture(), dstX, dstY, _overlayDrawRect.width(), _overlayDrawRect.height());
|
Pipeline::getActivePipeline()->drawTexture(_overlay->getGLTexture(), dstX, dstY, _overlayDrawRect.width(), _overlayDrawRect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Third step: Draw the cursor if visible.
|
// Third step: Draw the cursor if visible.
|
||||||
if (_cursorVisible && _cursor) {
|
if (_cursorVisible && _cursor) {
|
||||||
_backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
|
_backBuffer.enableBlend(Framebuffer::kBlendModePremultipliedTransparency);
|
||||||
|
|
||||||
g_context.getActivePipeline()->drawTexture(_cursor->getGLTexture(),
|
Pipeline::getActivePipeline()->drawTexture(_cursor->getGLTexture(),
|
||||||
_cursorX - _cursorHotspotXScaled + _shakeOffsetScaled.x,
|
_cursorX - _cursorHotspotXScaled + _shakeOffsetScaled.x,
|
||||||
_cursorY - _cursorHotspotYScaled + _shakeOffsetScaled.y,
|
_cursorY - _cursorHotspotYScaled + _shakeOffsetScaled.y,
|
||||||
_cursorWidthScaled, _cursorHeightScaled);
|
_cursorWidthScaled, _cursorHeightScaled);
|
||||||
|
@ -631,17 +632,17 @@ void OpenGLGraphicsManager::updateScreen() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the OSD transparency.
|
// Set the OSD transparency.
|
||||||
g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, _osdMessageAlpha / 100.0f);
|
Pipeline::getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, _osdMessageAlpha / 100.0f);
|
||||||
|
|
||||||
int dstX = (_windowWidth - _osdMessageSurface->getWidth()) / 2;
|
int dstX = (_windowWidth - _osdMessageSurface->getWidth()) / 2;
|
||||||
int dstY = (_windowHeight - _osdMessageSurface->getHeight()) / 2;
|
int dstY = (_windowHeight - _osdMessageSurface->getHeight()) / 2;
|
||||||
|
|
||||||
// Draw the OSD texture.
|
// Draw the OSD texture.
|
||||||
g_context.getActivePipeline()->drawTexture(_osdMessageSurface->getGLTexture(),
|
Pipeline::getActivePipeline()->drawTexture(_osdMessageSurface->getGLTexture(),
|
||||||
dstX, dstY, _osdMessageSurface->getWidth(), _osdMessageSurface->getHeight());
|
dstX, dstY, _osdMessageSurface->getWidth(), _osdMessageSurface->getHeight());
|
||||||
|
|
||||||
// Reset color.
|
// Reset color.
|
||||||
g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
Pipeline::getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
if (_osdMessageAlpha <= 0) {
|
if (_osdMessageAlpha <= 0) {
|
||||||
delete _osdMessageSurface;
|
delete _osdMessageSurface;
|
||||||
|
@ -658,7 +659,7 @@ void OpenGLGraphicsManager::updateScreen() {
|
||||||
int dstY = kOSDIconTopMargin;
|
int dstY = kOSDIconTopMargin;
|
||||||
|
|
||||||
// Draw the OSD icon texture.
|
// Draw the OSD icon texture.
|
||||||
g_context.getActivePipeline()->drawTexture(_osdIconSurface->getGLTexture(),
|
Pipeline::getActivePipeline()->drawTexture(_osdIconSurface->getGLTexture(),
|
||||||
dstX, dstY, _osdIconSurface->getWidth(), _osdIconSurface->getHeight());
|
dstX, dstY, _osdIconSurface->getWidth(), _osdIconSurface->getHeight());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1019,15 +1020,15 @@ void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height)
|
||||||
// possible and then scale it to the physical display size. This sounds
|
// possible and then scale it to the physical display size. This sounds
|
||||||
// bad but actually all recent chips should support full HD resolution
|
// bad but actually all recent chips should support full HD resolution
|
||||||
// anyway. Thus, it should not be a real issue for modern hardware.
|
// anyway. Thus, it should not be a real issue for modern hardware.
|
||||||
if ( overlayWidth > (uint)g_context.maxTextureSize
|
if ( overlayWidth > (uint)OpenGLContext.maxTextureSize
|
||||||
|| overlayHeight > (uint)g_context.maxTextureSize) {
|
|| overlayHeight > (uint)OpenGLContext.maxTextureSize) {
|
||||||
const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
|
const frac_t outputAspect = intToFrac(_windowWidth) / _windowHeight;
|
||||||
|
|
||||||
if (outputAspect > (frac_t)FRAC_ONE) {
|
if (outputAspect > (frac_t)FRAC_ONE) {
|
||||||
overlayWidth = g_context.maxTextureSize;
|
overlayWidth = OpenGLContext.maxTextureSize;
|
||||||
overlayHeight = intToFrac(overlayWidth) / outputAspect;
|
overlayHeight = intToFrac(overlayWidth) / outputAspect;
|
||||||
} else {
|
} else {
|
||||||
overlayHeight = g_context.maxTextureSize;
|
overlayHeight = OpenGLContext.maxTextureSize;
|
||||||
overlayWidth = fracToInt(overlayHeight * outputAspect);
|
overlayWidth = fracToInt(overlayHeight * outputAspect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1065,16 +1066,17 @@ void OpenGLGraphicsManager::handleResizeImpl(const int width, const int height)
|
||||||
++_screenChangeID;
|
++_screenChangeID;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha) {
|
void OpenGLGraphicsManager::notifyContextCreate(ContextType type,
|
||||||
// Initialize context for use.
|
const Graphics::PixelFormat &defaultFormat,
|
||||||
initializeGLContext();
|
const Graphics::PixelFormat &defaultFormatAlpha) {
|
||||||
|
|
||||||
// Initialize pipeline.
|
// Initialize pipeline.
|
||||||
delete _pipeline;
|
delete _pipeline;
|
||||||
_pipeline = nullptr;
|
_pipeline = nullptr;
|
||||||
|
|
||||||
|
OpenGLContext.initialize(type);
|
||||||
|
|
||||||
#if !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
if (g_context.shadersSupported) {
|
if (OpenGLContext.shadersSupported) {
|
||||||
ShaderMan.notifyCreate();
|
ShaderMan.notifyCreate();
|
||||||
_pipeline = new ShaderPipeline(ShaderMan.query(ShaderManager::kDefault));
|
_pipeline = new ShaderPipeline(ShaderMan.query(ShaderManager::kDefault));
|
||||||
}
|
}
|
||||||
|
@ -1086,21 +1088,21 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
g_context.setPipeline(_pipeline);
|
Pipeline::setPipeline(_pipeline);
|
||||||
|
|
||||||
// Disable 3D properties.
|
// Disable 3D properties.
|
||||||
GL_CALL(glDisable(GL_CULL_FACE));
|
GL_CALL(glDisable(GL_CULL_FACE));
|
||||||
GL_CALL(glDisable(GL_DEPTH_TEST));
|
GL_CALL(glDisable(GL_DEPTH_TEST));
|
||||||
GL_CALL(glDisable(GL_DITHER));
|
GL_CALL(glDisable(GL_DITHER));
|
||||||
|
|
||||||
g_context.getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
Pipeline::getActivePipeline()->setColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
// Setup backbuffer state.
|
// Setup backbuffer state.
|
||||||
|
|
||||||
// Default to black as clear color.
|
// Default to black as clear color.
|
||||||
_backBuffer.setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
_backBuffer.setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
g_context.getActivePipeline()->setFramebuffer(&_backBuffer);
|
Pipeline::getActivePipeline()->setFramebuffer(&_backBuffer);
|
||||||
|
|
||||||
// We use a "pack" alignment (when reading from textures) to 4 here,
|
// We use a "pack" alignment (when reading from textures) to 4 here,
|
||||||
// since the only place where we really use it is the BMP screenshot
|
// since the only place where we really use it is the BMP screenshot
|
||||||
|
@ -1165,18 +1167,18 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
if (g_context.shadersSupported) {
|
if (OpenGLContext.shadersSupported) {
|
||||||
ShaderMan.notifyDestroy();
|
ShaderMan.notifyDestroy();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Destroy rendering pipeline.
|
// Destroy rendering pipeline.
|
||||||
g_context.setPipeline(nullptr);
|
Pipeline::setPipeline(nullptr);
|
||||||
delete _pipeline;
|
delete _pipeline;
|
||||||
_pipeline = nullptr;
|
_pipeline = nullptr;
|
||||||
|
|
||||||
// Rest our context description since the context is gone soon.
|
// Rest our context description since the context is gone soon.
|
||||||
g_context.reset();
|
OpenGLContext.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha, bool wantScaler) {
|
Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &format, bool wantAlpha, bool wantScaler) {
|
||||||
|
@ -1213,7 +1215,7 @@ Surface *OpenGLGraphicsManager::createSurface(const Graphics::PixelFormat &forma
|
||||||
}
|
}
|
||||||
} else if (getGLPixelFormat(format, glIntFormat, glFormat, glType)) {
|
} else if (getGLPixelFormat(format, glIntFormat, glFormat, glType)) {
|
||||||
return new Texture(glIntFormat, glFormat, glType, format);
|
return new Texture(glIntFormat, glFormat, glType, format);
|
||||||
} else if (g_context.packedPixelsSupported && format == Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)) {
|
} else if (OpenGLContext.packedPixelsSupported && format == Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0)) {
|
||||||
// OpenGL ES does not support a texture format usable for RGB555.
|
// OpenGL ES does not support a texture format usable for RGB555.
|
||||||
// Since SCUMM uses this pixel format for some games (and there is no
|
// Since SCUMM uses this pixel format for some games (and there is no
|
||||||
// hope for this to change anytime soon) we use pixel format
|
// hope for this to change anytime soon) we use pixel format
|
||||||
|
@ -1244,7 +1246,7 @@ bool OpenGLGraphicsManager::getGLPixelFormat(const Graphics::PixelFormat &pixelF
|
||||||
glFormat = GL_RGBA;
|
glFormat = GL_RGBA;
|
||||||
glType = GL_UNSIGNED_BYTE;
|
glType = GL_UNSIGNED_BYTE;
|
||||||
return true;
|
return true;
|
||||||
} else if (!g_context.packedPixelsSupported) {
|
} else if (!OpenGLContext.packedPixelsSupported) {
|
||||||
return false;
|
return false;
|
||||||
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)) { // RGB565
|
} else if (pixelFormat == Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)) { // RGB565
|
||||||
glIntFormat = GL_RGB;
|
glIntFormat = GL_RGB;
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
#ifndef BACKENDS_GRAPHICS_OPENGL_OPENGL_GRAPHICS_H
|
#ifndef BACKENDS_GRAPHICS_OPENGL_OPENGL_GRAPHICS_H
|
||||||
#define BACKENDS_GRAPHICS_OPENGL_OPENGL_GRAPHICS_H
|
#define BACKENDS_GRAPHICS_OPENGL_OPENGL_GRAPHICS_H
|
||||||
|
|
||||||
#include "backends/graphics/opengl/opengl-sys.h"
|
|
||||||
#include "backends/graphics/opengl/framebuffer.h"
|
#include "backends/graphics/opengl/framebuffer.h"
|
||||||
#include "backends/graphics/windowed.h"
|
#include "backends/graphics/windowed.h"
|
||||||
|
|
||||||
|
@ -130,28 +129,22 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Whether an GLES or GLES2 context is active.
|
* Whether an GLES or GLES2 context is active.
|
||||||
*/
|
*/
|
||||||
bool isGLESContext() const { return g_context.type == kContextGLES || g_context.type == kContextGLES2; }
|
bool isGLESContext() const { return OpenGLContext.type == kContextGLES || OpenGLContext.type == kContextGLES2; }
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the OpenGL (ES) type the graphics manager shall work with.
|
|
||||||
*
|
|
||||||
* This needs to be called at least once (and before ever calling
|
|
||||||
* notifyContextCreate).
|
|
||||||
*
|
|
||||||
* @param type Type of the OpenGL (ES) contexts to be created.
|
|
||||||
*/
|
|
||||||
void setContextType(ContextType type);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the manager of a OpenGL context change. This should be the first
|
* Notify the manager of a OpenGL context change. This should be the first
|
||||||
* thing to call after you created an OpenGL (ES) context!
|
* thing to call after you created an OpenGL (ES) context!
|
||||||
*
|
*
|
||||||
|
* @param type Type of the OpenGL (ES) contexts created.
|
||||||
* @param defaultFormat The new default format for the game screen
|
* @param defaultFormat The new default format for the game screen
|
||||||
* (this is used for the CLUT8 game screens).
|
* (this is used for the CLUT8 game screens).
|
||||||
* @param defaultFormatAlpha The new default format with an alpha channel
|
* @param defaultFormatAlpha The new default format with an alpha channel
|
||||||
* (this is used for the overlay and cursor).
|
* (this is used for the overlay and cursor).
|
||||||
*/
|
*/
|
||||||
void notifyContextCreate(const Graphics::PixelFormat &defaultFormat, const Graphics::PixelFormat &defaultFormatAlpha);
|
void notifyContextCreate(
|
||||||
|
ContextType type,
|
||||||
|
const Graphics::PixelFormat &defaultFormat,
|
||||||
|
const Graphics::PixelFormat &defaultFormatAlpha);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the manager that the OpenGL context is about to be destroyed.
|
* Notify the manager that the OpenGL context is about to be destroyed.
|
||||||
|
@ -300,20 +293,6 @@ private:
|
||||||
*/
|
*/
|
||||||
Pipeline *_pipeline;
|
Pipeline *_pipeline;
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Query the address of an OpenGL function by name.
|
|
||||||
*
|
|
||||||
* This can only be used after a context has been created.
|
|
||||||
* Please note that this function can return valid addresses even if the
|
|
||||||
* OpenGL context does not support the function.
|
|
||||||
*
|
|
||||||
* @param name The name of the OpenGL function.
|
|
||||||
* @return An function pointer for the requested OpenGL function or
|
|
||||||
* nullptr in case of failure.
|
|
||||||
*/
|
|
||||||
virtual void *getProcAddress(const char *name) const = 0;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Try to determine the internal parameters for a given pixel format.
|
* Try to determine the internal parameters for a given pixel format.
|
||||||
|
|
|
@ -1,136 +0,0 @@
|
||||||
/* ScummVM - Graphic Adventure Engine
|
|
||||||
*
|
|
||||||
* ScummVM is the legal property of its developers, whose names
|
|
||||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
||||||
* file distributed with this source distribution.
|
|
||||||
*
|
|
||||||
* 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/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef BACKENDS_GRAPHICS_OPENGL_OPENGL_SYS_H
|
|
||||||
#define BACKENDS_GRAPHICS_OPENGL_OPENGL_SYS_H
|
|
||||||
|
|
||||||
#include "common/scummsys.h"
|
|
||||||
#include "graphics/opengl/system_headers.h"
|
|
||||||
|
|
||||||
#include "backends/graphics/opengl/debug.h"
|
|
||||||
|
|
||||||
// This is an addition from us to alias ARB shader object extensions to
|
|
||||||
// OpenGL (ES) 2.0 style functions. It only works when GLhandleARB and GLuint
|
|
||||||
// are type compatible.
|
|
||||||
typedef GLuint GLprogram;
|
|
||||||
typedef GLuint GLshader;
|
|
||||||
|
|
||||||
namespace OpenGL {
|
|
||||||
|
|
||||||
enum ContextType {
|
|
||||||
kContextGL,
|
|
||||||
kContextGLES,
|
|
||||||
kContextGLES2
|
|
||||||
};
|
|
||||||
|
|
||||||
class Pipeline;
|
|
||||||
class Framebuffer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Description structure of the OpenGL (ES) context.
|
|
||||||
*/
|
|
||||||
struct Context {
|
|
||||||
/** The type of the active context. */
|
|
||||||
ContextType type;
|
|
||||||
|
|
||||||
/** Whether the context is initialized or not. */
|
|
||||||
bool isInitialized;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset context.
|
|
||||||
*
|
|
||||||
* This marks all extensions as unavailable and clears all function
|
|
||||||
* pointers.
|
|
||||||
*/
|
|
||||||
void reset();
|
|
||||||
|
|
||||||
/** Helper function for checking the GL version supported by the context. */
|
|
||||||
inline bool isGLVersionOrHigher(int major, int minor) {
|
|
||||||
return ((majorVersion > major) || ((majorVersion == major) && (minorVersion >= minor)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/** The GL version supported by the context. */
|
|
||||||
int majorVersion, minorVersion;
|
|
||||||
|
|
||||||
/** The maximum texture size supported by the context. */
|
|
||||||
GLint maxTextureSize;
|
|
||||||
|
|
||||||
/** Whether GL_ARB_texture_non_power_of_two is available or not. */
|
|
||||||
bool NPOTSupported;
|
|
||||||
|
|
||||||
/** Whether shader support is available or not. */
|
|
||||||
bool shadersSupported;
|
|
||||||
|
|
||||||
/** Whether multi texture support is available or not. */
|
|
||||||
bool multitextureSupported;
|
|
||||||
|
|
||||||
/** Whether FBO support is available or not. */
|
|
||||||
bool framebufferObjectSupported;
|
|
||||||
|
|
||||||
/** Whether packed pixels support is available or not. */
|
|
||||||
bool packedPixelsSupported;
|
|
||||||
|
|
||||||
/** Whether texture coordinate edge clamping is available or not. */
|
|
||||||
bool textureEdgeClampSupported;
|
|
||||||
|
|
||||||
//
|
|
||||||
// Wrapper functionality to handle fixed-function pipelines and
|
|
||||||
// programmable pipelines in the same fashion.
|
|
||||||
//
|
|
||||||
|
|
||||||
private:
|
|
||||||
/** Currently active rendering pipeline. */
|
|
||||||
Pipeline *activePipeline;
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Set new pipeline.
|
|
||||||
*
|
|
||||||
* Client is responsible for any memory management related to pipelines.
|
|
||||||
*
|
|
||||||
* @param pipeline Pipeline to activate.
|
|
||||||
* @return Formerly active pipeline.
|
|
||||||
*/
|
|
||||||
Pipeline *setPipeline(Pipeline *pipeline);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Query the currently active rendering pipeline.
|
|
||||||
*/
|
|
||||||
Pipeline *getActivePipeline() const { return activePipeline; }
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The (active) OpenGL context.
|
|
||||||
*/
|
|
||||||
extern Context g_context;
|
|
||||||
|
|
||||||
} // End of namespace OpenGL
|
|
||||||
|
|
||||||
#define GL_CALL(x) GL_WRAP_DEBUG(x, x)
|
|
||||||
#define GL_CALL_SAFE(func, params) \
|
|
||||||
do { \
|
|
||||||
if (g_context.isInitialized) { \
|
|
||||||
GL_CALL(func params); \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
#define GL_ASSIGN(var, x) GL_WRAP_DEBUG(var = x, x)
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "backends/graphics/opengl/pipelines/clut8.h"
|
#include "backends/graphics/opengl/pipelines/clut8.h"
|
||||||
|
#include "backends/graphics/opengl/debug.h"
|
||||||
#include "backends/graphics/opengl/shader.h"
|
#include "backends/graphics/opengl/shader.h"
|
||||||
#include "backends/graphics/opengl/framebuffer.h"
|
#include "backends/graphics/opengl/framebuffer.h"
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "backends/graphics/opengl/pipelines/fixed.h"
|
#include "backends/graphics/opengl/pipelines/fixed.h"
|
||||||
|
#include "backends/graphics/opengl/debug.h"
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ void FixedPipeline::activateInternal() {
|
||||||
GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||||
|
|
||||||
#if !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
if (g_context.multitextureSupported) {
|
if (OpenGLContext.multitextureSupported) {
|
||||||
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
|
Pipeline *Pipeline::activePipeline = nullptr;
|
||||||
|
|
||||||
Pipeline::Pipeline()
|
Pipeline::Pipeline()
|
||||||
: _activeFramebuffer(nullptr), _isActive(false) {
|
: _activeFramebuffer(nullptr), _isActive(false) {
|
||||||
}
|
}
|
||||||
|
@ -62,4 +64,18 @@ Framebuffer *Pipeline::setFramebuffer(Framebuffer *framebuffer) {
|
||||||
return oldFramebuffer;
|
return oldFramebuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pipeline *Pipeline::setPipeline(Pipeline *pipeline) {
|
||||||
|
Pipeline *oldPipeline = activePipeline;
|
||||||
|
if (oldPipeline) {
|
||||||
|
oldPipeline->deactivate();
|
||||||
|
}
|
||||||
|
|
||||||
|
activePipeline = pipeline;
|
||||||
|
if (activePipeline) {
|
||||||
|
activePipeline->activate();
|
||||||
|
}
|
||||||
|
|
||||||
|
return oldPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace OpenGL
|
} // End of namespace OpenGL
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_PIPELINE_H
|
#ifndef BACKENDS_GRAPHICS_OPENGL_PIPELINES_PIPELINE_H
|
||||||
#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_PIPELINE_H
|
#define BACKENDS_GRAPHICS_OPENGL_PIPELINES_PIPELINE_H
|
||||||
|
|
||||||
#include "backends/graphics/opengl/opengl-sys.h"
|
#include "graphics/opengl/system_headers.h"
|
||||||
|
|
||||||
#include "backends/graphics/opengl/texture.h"
|
#include "backends/graphics/opengl/texture.h"
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
@ -148,6 +149,25 @@ protected:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _isActive;
|
bool _isActive;
|
||||||
|
|
||||||
|
/** Currently active rendering pipeline. */
|
||||||
|
static Pipeline *activePipeline;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Set new pipeline.
|
||||||
|
*
|
||||||
|
* Client is responsible for any memory management related to pipelines.
|
||||||
|
*
|
||||||
|
* @param pipeline Pipeline to activate.
|
||||||
|
* @return Formerly active pipeline.
|
||||||
|
*/
|
||||||
|
static Pipeline *setPipeline(Pipeline *pipeline);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query the currently active rendering pipeline.
|
||||||
|
*/
|
||||||
|
static Pipeline *getActivePipeline() { return activePipeline; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace OpenGL
|
} // End of namespace OpenGL
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "backends/graphics/opengl/pipelines/shader.h"
|
#include "backends/graphics/opengl/pipelines/shader.h"
|
||||||
|
#include "backends/graphics/opengl/debug.h"
|
||||||
#include "backends/graphics/opengl/shader.h"
|
#include "backends/graphics/opengl/shader.h"
|
||||||
#include "backends/graphics/opengl/framebuffer.h"
|
#include "backends/graphics/opengl/framebuffer.h"
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ void ShaderPipeline::activateInternal() {
|
||||||
GL_CALL(glEnableVertexAttribArray(_texCoordAttribLocation));
|
GL_CALL(glEnableVertexAttribArray(_texCoordAttribLocation));
|
||||||
GL_CALL(glEnableVertexAttribArray(_colorAttribLocation));
|
GL_CALL(glEnableVertexAttribArray(_colorAttribLocation));
|
||||||
|
|
||||||
if (g_context.multitextureSupported) {
|
if (OpenGLContext.multitextureSupported) {
|
||||||
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,9 +20,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "backends/graphics/opengl/shader.h"
|
#include "backends/graphics/opengl/shader.h"
|
||||||
|
#include "backends/graphics/opengl/debug.h"
|
||||||
|
|
||||||
#if !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
|
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ bool Shader::setUniform(const Common::String &name, ShaderUniformValue *value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
GLshader Shader::compileShader(const char *source, GLenum shaderType) {
|
GLshader Shader::compileShader(const char *source, GLenum shaderType) {
|
||||||
const GLchar *versionSource = g_context.type == kContextGLES2 ? "#version 100\n" : "#version 110\n";
|
const GLchar *versionSource = OpenGLContext.type == kContextGLES2 ? "#version 100\n" : "#version 110\n";
|
||||||
const GLchar *compatSource = shaderType == GL_VERTEX_SHADER ? "" : g_precisionDefines;
|
const GLchar *compatSource = shaderType == GL_VERTEX_SHADER ? "" : g_precisionDefines;
|
||||||
|
|
||||||
GLshader handle;
|
GLshader handle;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#ifndef BACKENDS_GRAPHICS_OPENGL_SHADER_H
|
#ifndef BACKENDS_GRAPHICS_OPENGL_SHADER_H
|
||||||
#define BACKENDS_GRAPHICS_OPENGL_SHADER_H
|
#define BACKENDS_GRAPHICS_OPENGL_SHADER_H
|
||||||
|
|
||||||
#include "backends/graphics/opengl/opengl-sys.h"
|
#include "graphics/opengl/system_headers.h"
|
||||||
|
|
||||||
#if !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
|
|
||||||
|
@ -30,6 +30,12 @@
|
||||||
#include "common/hash-str.h"
|
#include "common/hash-str.h"
|
||||||
#include "common/ptr.h"
|
#include "common/ptr.h"
|
||||||
|
|
||||||
|
// This is an addition from us to alias ARB shader object extensions to
|
||||||
|
// OpenGL (ES) 2.0 style functions. It only works when GLhandleARB and GLuint
|
||||||
|
// are type compatible.
|
||||||
|
typedef GLuint GLprogram;
|
||||||
|
typedef GLuint GLshader;
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "backends/graphics/opengl/texture.h"
|
#include "backends/graphics/opengl/texture.h"
|
||||||
|
#include "backends/graphics/opengl/debug.h"
|
||||||
#include "backends/graphics/opengl/shader.h"
|
#include "backends/graphics/opengl/shader.h"
|
||||||
#include "backends/graphics/opengl/pipelines/pipeline.h"
|
#include "backends/graphics/opengl/pipelines/pipeline.h"
|
||||||
#include "backends/graphics/opengl/pipelines/clut8.h"
|
#include "backends/graphics/opengl/pipelines/clut8.h"
|
||||||
|
@ -80,7 +81,7 @@ void GLTexture::create() {
|
||||||
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, _glFilter));
|
||||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, _glFilter));
|
||||||
if (g_context.textureEdgeClampSupported) {
|
if (OpenGLContext.textureEdgeClampSupported) {
|
||||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
|
||||||
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
GL_CALL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
|
||||||
} else {
|
} else {
|
||||||
|
@ -106,7 +107,7 @@ void GLTexture::setSize(uint width, uint height) {
|
||||||
const uint oldWidth = _width;
|
const uint oldWidth = _width;
|
||||||
const uint oldHeight = _height;
|
const uint oldHeight = _height;
|
||||||
|
|
||||||
if (!g_context.NPOTSupported) {
|
if (!OpenGLContext.NPOTSupported) {
|
||||||
_width = Common::nextHigher2(width);
|
_width = Common::nextHigher2(width);
|
||||||
_height = Common::nextHigher2(height);
|
_height = Common::nextHigher2(height);
|
||||||
} else {
|
} else {
|
||||||
|
@ -734,13 +735,13 @@ void TextureCLUT8GPU::updateGLTexture() {
|
||||||
|
|
||||||
void TextureCLUT8GPU::lookUpColors() {
|
void TextureCLUT8GPU::lookUpColors() {
|
||||||
// Setup pipeline to do color look up.
|
// Setup pipeline to do color look up.
|
||||||
Pipeline *oldPipeline = g_context.setPipeline(_clut8Pipeline);
|
Pipeline *oldPipeline = Pipeline::setPipeline(_clut8Pipeline);
|
||||||
|
|
||||||
// Do color look up.
|
// Do color look up.
|
||||||
g_context.getActivePipeline()->drawTexture(_clut8Texture, _clut8Vertices);
|
Pipeline::getActivePipeline()->drawTexture(_clut8Texture, _clut8Vertices);
|
||||||
|
|
||||||
// Restore old state.
|
// Restore old state.
|
||||||
g_context.setPipeline(oldPipeline);
|
Pipeline::setPipeline(oldPipeline);
|
||||||
}
|
}
|
||||||
#endif // !USE_FORCED_GLES
|
#endif // !USE_FORCED_GLES
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,8 @@
|
||||||
#ifndef BACKENDS_GRAPHICS_OPENGL_TEXTURE_H
|
#ifndef BACKENDS_GRAPHICS_OPENGL_TEXTURE_H
|
||||||
#define BACKENDS_GRAPHICS_OPENGL_TEXTURE_H
|
#define BACKENDS_GRAPHICS_OPENGL_TEXTURE_H
|
||||||
|
|
||||||
#include "backends/graphics/opengl/opengl-sys.h"
|
#include "graphics/opengl/system_headers.h"
|
||||||
|
#include "graphics/opengl/context.h"
|
||||||
|
|
||||||
#include "graphics/pixelformat.h"
|
#include "graphics/pixelformat.h"
|
||||||
#include "graphics/surface.h"
|
#include "graphics/surface.h"
|
||||||
|
@ -405,9 +406,9 @@ public:
|
||||||
virtual const GLTexture &getGLTexture() const;
|
virtual const GLTexture &getGLTexture() const;
|
||||||
|
|
||||||
static bool isSupportedByContext() {
|
static bool isSupportedByContext() {
|
||||||
return g_context.shadersSupported
|
return OpenGLContext.shadersSupported
|
||||||
&& g_context.multitextureSupported
|
&& OpenGLContext.multitextureSupported
|
||||||
&& g_context.framebufferObjectSupported;
|
&& OpenGLContext.framebufferObjectSupported;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void lookUpColors();
|
void lookUpColors();
|
||||||
|
|
|
@ -49,8 +49,6 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(SdlEventSource *eventSource,
|
||||||
|
|
||||||
// Set up proper SDL OpenGL context creation.
|
// Set up proper SDL OpenGL context creation.
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
OpenGL::ContextType glContextType;
|
|
||||||
|
|
||||||
// Context version 1.4 is choosen arbitrarily based on what most shader
|
// Context version 1.4 is choosen arbitrarily based on what most shader
|
||||||
// extensions were written against.
|
// extensions were written against.
|
||||||
enum {
|
enum {
|
||||||
|
@ -65,17 +63,17 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(SdlEventSource *eventSource,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if USE_FORCED_GL
|
#if USE_FORCED_GL
|
||||||
glContextType = OpenGL::kContextGL;
|
_glContextType = OpenGL::kContextGL;
|
||||||
_glContextProfileMask = 0;
|
_glContextProfileMask = 0;
|
||||||
_glContextMajor = DEFAULT_GL_MAJOR;
|
_glContextMajor = DEFAULT_GL_MAJOR;
|
||||||
_glContextMinor = DEFAULT_GL_MINOR;
|
_glContextMinor = DEFAULT_GL_MINOR;
|
||||||
#elif USE_FORCED_GLES
|
#elif USE_FORCED_GLES
|
||||||
glContextType = OpenGL::kContextGLES;
|
_glContextType = OpenGL::kContextGLES;
|
||||||
_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
|
_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
|
||||||
_glContextMajor = DEFAULT_GLES_MAJOR;
|
_glContextMajor = DEFAULT_GLES_MAJOR;
|
||||||
_glContextMinor = DEFAULT_GLES_MINOR;
|
_glContextMinor = DEFAULT_GLES_MINOR;
|
||||||
#elif USE_FORCED_GLES2
|
#elif USE_FORCED_GLES2
|
||||||
glContextType = OpenGL::kContextGLES2;
|
_glContextType = OpenGL::kContextGLES2;
|
||||||
_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
|
_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
|
||||||
_glContextMajor = DEFAULT_GLES2_MAJOR;
|
_glContextMajor = DEFAULT_GLES2_MAJOR;
|
||||||
_glContextMinor = DEFAULT_GLES2_MINOR;
|
_glContextMinor = DEFAULT_GLES2_MINOR;
|
||||||
|
@ -115,12 +113,12 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(SdlEventSource *eventSource,
|
||||||
|
|
||||||
if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
|
if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
|
||||||
if (_glContextMajor >= 2) {
|
if (_glContextMajor >= 2) {
|
||||||
glContextType = OpenGL::kContextGLES2;
|
_glContextType = OpenGL::kContextGLES2;
|
||||||
} else {
|
} else {
|
||||||
glContextType = OpenGL::kContextGLES;
|
_glContextType = OpenGL::kContextGLES;
|
||||||
}
|
}
|
||||||
} else if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_CORE) {
|
} else if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_CORE) {
|
||||||
glContextType = OpenGL::kContextGL;
|
_glContextType = OpenGL::kContextGL;
|
||||||
|
|
||||||
// Core profile does not allow legacy functionality, which we use.
|
// Core profile does not allow legacy functionality, which we use.
|
||||||
// Thus we request a standard OpenGL context.
|
// Thus we request a standard OpenGL context.
|
||||||
|
@ -128,13 +126,11 @@ OpenGLSdlGraphicsManager::OpenGLSdlGraphicsManager(SdlEventSource *eventSource,
|
||||||
_glContextMajor = DEFAULT_GL_MAJOR;
|
_glContextMajor = DEFAULT_GL_MAJOR;
|
||||||
_glContextMinor = DEFAULT_GL_MINOR;
|
_glContextMinor = DEFAULT_GL_MINOR;
|
||||||
} else {
|
} else {
|
||||||
glContextType = OpenGL::kContextGL;
|
_glContextType = OpenGL::kContextGL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
setContextType(glContextType);
|
|
||||||
#else
|
#else
|
||||||
setContextType(OpenGL::kContextGL);
|
_glContextType = OpenGL::kContextGL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Retrieve a list of working fullscreen modes
|
// Retrieve a list of working fullscreen modes
|
||||||
|
@ -426,10 +422,6 @@ void OpenGLSdlGraphicsManager::refreshScreen() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void *OpenGLSdlGraphicsManager::getProcAddress(const char *name) const {
|
|
||||||
return SDL_GL_GetProcAddress(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLSdlGraphicsManager::handleResizeImpl(const int width, const int height) {
|
void OpenGLSdlGraphicsManager::handleResizeImpl(const int width, const int height) {
|
||||||
OpenGLGraphicsManager::handleResizeImpl(width, height);
|
OpenGLGraphicsManager::handleResizeImpl(width, height);
|
||||||
SdlGraphicsManager::handleResizeImpl(width, height);
|
SdlGraphicsManager::handleResizeImpl(width, height);
|
||||||
|
@ -550,7 +542,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
notifyContextCreate(rgba8888, rgba8888);
|
notifyContextCreate(_glContextType, rgba8888, rgba8888);
|
||||||
int actualWidth, actualHeight;
|
int actualWidth, actualHeight;
|
||||||
getWindowSizeFromSdl(&actualWidth, &actualHeight);
|
getWindowSizeFromSdl(&actualWidth, &actualHeight);
|
||||||
|
|
||||||
|
@ -617,7 +609,7 @@ bool OpenGLSdlGraphicsManager::setupMode(uint width, uint height) {
|
||||||
_lastVideoModeLoad = SDL_GetTicks();
|
_lastVideoModeLoad = SDL_GetTicks();
|
||||||
|
|
||||||
if (_hwScreen) {
|
if (_hwScreen) {
|
||||||
notifyContextCreate(rgba8888, rgba8888);
|
notifyContextCreate(_glContextType, rgba8888, rgba8888);
|
||||||
handleResize(_hwScreen->w, _hwScreen->h);
|
handleResize(_hwScreen->w, _hwScreen->h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,8 +55,6 @@ protected:
|
||||||
|
|
||||||
void refreshScreen() override;
|
void refreshScreen() override;
|
||||||
|
|
||||||
void *getProcAddress(const char *name) const override;
|
|
||||||
|
|
||||||
void handleResizeImpl(const int width, const int height) override;
|
void handleResizeImpl(const int width, const int height) override;
|
||||||
|
|
||||||
bool saveScreenshot(const Common::String &filename) const override;
|
bool saveScreenshot(const Common::String &filename) const override;
|
||||||
|
@ -66,10 +64,12 @@ private:
|
||||||
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
#if SDL_VERSION_ATLEAST(2, 0, 0)
|
||||||
int _glContextProfileMask, _glContextMajor, _glContextMinor;
|
int _glContextProfileMask, _glContextMajor, _glContextMinor;
|
||||||
|
|
||||||
SDL_GLContext _glContext;
|
SDL_GLContext _glContext;
|
||||||
#else
|
#else
|
||||||
uint32 _lastVideoModeLoad;
|
uint32 _lastVideoModeLoad;
|
||||||
#endif
|
#endif
|
||||||
|
OpenGL::ContextType _glContextType;
|
||||||
|
|
||||||
uint _lastRequestedWidth;
|
uint _lastRequestedWidth;
|
||||||
uint _lastRequestedHeight;
|
uint _lastRequestedHeight;
|
||||||
|
|
|
@ -171,7 +171,7 @@ void AndroidGraphics3dManager::initSurface() {
|
||||||
_screenChangeID = JNI::surface_changeid;
|
_screenChangeID = JNI::surface_changeid;
|
||||||
|
|
||||||
// Initialize OpenGLES context.
|
// Initialize OpenGLES context.
|
||||||
OpenGLContext.initialize(OpenGL::kOGLContextGLES2);
|
OpenGLContext.initialize(OpenGL::kContextGLES2);
|
||||||
logExtensions();
|
logExtensions();
|
||||||
GLESTexture::initGL();
|
GLESTexture::initGL();
|
||||||
|
|
||||||
|
@ -244,7 +244,7 @@ void AndroidGraphics3dManager::deinitSurface() {
|
||||||
_touchcontrols_texture->release();
|
_touchcontrols_texture->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGL::ContextGL::destroy();
|
OpenGLContext.reset();
|
||||||
|
|
||||||
JNI::deinitSurface();
|
JNI::deinitSurface();
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ OpenGLSdlGraphics3dManager::OpenGLSdlGraphics3dManager(SdlEventSource *eventSour
|
||||||
};
|
};
|
||||||
|
|
||||||
#if USE_FORCED_GLES2
|
#if USE_FORCED_GLES2
|
||||||
_glContextType = OpenGL::kOGLContextGLES2;
|
_glContextType = OpenGL::kContextGLES2;
|
||||||
_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
|
_glContextProfileMask = SDL_GL_CONTEXT_PROFILE_ES;
|
||||||
_glContextMajor = DEFAULT_GLES2_MAJOR;
|
_glContextMajor = DEFAULT_GLES2_MAJOR;
|
||||||
_glContextMinor = DEFAULT_GLES2_MINOR;
|
_glContextMinor = DEFAULT_GLES2_MINOR;
|
||||||
|
@ -123,9 +123,9 @@ OpenGLSdlGraphics3dManager::OpenGLSdlGraphics3dManager(SdlEventSource *eventSour
|
||||||
|
|
||||||
if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
|
if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_ES) {
|
||||||
// TODO: Support GLES1 for games
|
// TODO: Support GLES1 for games
|
||||||
_glContextType = OpenGL::kOGLContextGLES2;
|
_glContextType = OpenGL::kContextGLES2;
|
||||||
} else if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_CORE) {
|
} else if (_glContextProfileMask == SDL_GL_CONTEXT_PROFILE_CORE) {
|
||||||
_glContextType = OpenGL::kOGLContextGL;
|
_glContextType = OpenGL::kContextGL;
|
||||||
|
|
||||||
// Core profile does not allow legacy functionality, which we use.
|
// Core profile does not allow legacy functionality, which we use.
|
||||||
// Thus we request a standard OpenGL context.
|
// Thus we request a standard OpenGL context.
|
||||||
|
@ -133,11 +133,11 @@ OpenGLSdlGraphics3dManager::OpenGLSdlGraphics3dManager(SdlEventSource *eventSour
|
||||||
_glContextMajor = DEFAULT_GL_MAJOR;
|
_glContextMajor = DEFAULT_GL_MAJOR;
|
||||||
_glContextMinor = DEFAULT_GL_MINOR;
|
_glContextMinor = DEFAULT_GL_MINOR;
|
||||||
} else {
|
} else {
|
||||||
_glContextType = OpenGL::kOGLContextGL;
|
_glContextType = OpenGL::kContextGL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
_glContextType = OpenGL::kOGLContextGL;
|
_glContextType = OpenGL::kContextGL;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -718,7 +718,7 @@ void OpenGLSdlGraphics3dManager::closeOverlay() {
|
||||||
delete _frameBuffer;
|
delete _frameBuffer;
|
||||||
_frameBuffer = nullptr;
|
_frameBuffer = nullptr;
|
||||||
|
|
||||||
OpenGL::ContextGL::destroy();
|
OpenGLContext.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 OpenGLSdlGraphics3dManager::getOverlayHeight() const {
|
int16 OpenGLSdlGraphics3dManager::getOverlayHeight() const {
|
||||||
|
|
|
@ -121,7 +121,7 @@ protected:
|
||||||
void deinitializeRenderer();
|
void deinitializeRenderer();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OpenGL::ContextOGLType _glContextType;
|
OpenGL::ContextType _glContextType;
|
||||||
|
|
||||||
bool _supportsFrameBuffer;
|
bool _supportsFrameBuffer;
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,6 @@ endif
|
||||||
# OpenGL specific source files.
|
# OpenGL specific source files.
|
||||||
ifdef USE_OPENGL
|
ifdef USE_OPENGL
|
||||||
MODULE_OBJS += \
|
MODULE_OBJS += \
|
||||||
graphics/opengl/context.o \
|
|
||||||
graphics/opengl/debug.o \
|
graphics/opengl/debug.o \
|
||||||
graphics/opengl/framebuffer.o \
|
graphics/opengl/framebuffer.o \
|
||||||
graphics/opengl/opengl-graphics.o \
|
graphics/opengl/opengl-graphics.o \
|
||||||
|
|
|
@ -121,11 +121,6 @@ void checkGlError(const char *expr, const char *file, int line) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *androidGLgetProcAddress(const char *name) {
|
|
||||||
// This exists since Android 2.3 (API Level 9)
|
|
||||||
return (void *)eglGetProcAddress(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
|
OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
|
||||||
_audio_sample_rate(audio_sample_rate),
|
_audio_sample_rate(audio_sample_rate),
|
||||||
_audio_buffer_size(audio_buffer_size),
|
_audio_buffer_size(audio_buffer_size),
|
||||||
|
@ -793,4 +788,11 @@ int OSystem_Android::getGraphicsMode() const {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_OPENGL) && defined(USE_GLAD)
|
||||||
|
void *OSystem_Android::getOpenGLProcAddress(const char *name) const {
|
||||||
|
// This exists since Android 2.3 (API Level 9)
|
||||||
|
return (void *)eglGetProcAddress(name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -201,7 +201,10 @@ public:
|
||||||
bool setGraphicsMode(int mode, uint flags) override;
|
bool setGraphicsMode(int mode, uint flags) override;
|
||||||
int getGraphicsMode() const override;
|
int getGraphicsMode() const override;
|
||||||
|
|
||||||
OpenGL::ContextOGLType getOpenGLType() const override { return OpenGL::kOGLContextGLES2; }
|
OpenGL::ContextType getOpenGLType() const override { return OpenGL::kContextGLES2; }
|
||||||
|
#if defined(USE_OPENGL) && defined(USE_GLAD)
|
||||||
|
void *getOpenGLProcAddress(const char *name) const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ANDROID_DEBUG_GL_CALLS
|
#ifdef ANDROID_DEBUG_GL_CALLS
|
||||||
bool isRunningInMainThread() { return pthread_self() == _main_thread; }
|
bool isRunningInMainThread() { return pthread_self() == _main_thread; }
|
||||||
|
|
|
@ -112,7 +112,6 @@ bool iOS7_isBigDevice();
|
||||||
|
|
||||||
void iOS7_buildSharedOSystemInstance();
|
void iOS7_buildSharedOSystemInstance();
|
||||||
void iOS7_main(int argc, char **argv);
|
void iOS7_main(int argc, char **argv);
|
||||||
void *iOS7_getProcAddress(const char *name);
|
|
||||||
const char *iOS7_getDocumentsDir();
|
const char *iOS7_getDocumentsDir();
|
||||||
bool iOS7_touchpadModeEnabled();
|
bool iOS7_touchpadModeEnabled();
|
||||||
|
|
||||||
|
|
|
@ -124,6 +124,12 @@ bool OSystem_iOS7::touchpadModeEnabled() const {
|
||||||
return _touchpadModeEnabled;
|
return _touchpadModeEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_OPENGL) && defined(USE_GLAD)
|
||||||
|
void *OSystem_iOS7::getOpenGLProcAddress(const char *name) const {
|
||||||
|
return dlsym(RTLD_SELF, name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int OSystem_iOS7::timerHandler(int t) {
|
int OSystem_iOS7::timerHandler(int t) {
|
||||||
DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager();
|
DefaultTimerManager *tm = (DefaultTimerManager *)g_system->getTimerManager();
|
||||||
tm->handler();
|
tm->handler();
|
||||||
|
@ -413,7 +419,3 @@ void iOS7_main(int argc, char **argv) {
|
||||||
fclose(newfp);
|
fclose(newfp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *iOS7_getProcAddress(const char *name) {
|
|
||||||
return dlsym(RTLD_SELF, name);
|
|
||||||
}
|
|
||||||
|
|
|
@ -143,6 +143,9 @@ public:
|
||||||
Graphics::PixelFormat getScreenFormat() const override { return _framebuffer.format; }
|
Graphics::PixelFormat getScreenFormat() const override { return _framebuffer.format; }
|
||||||
Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
|
Common::List<Graphics::PixelFormat> getSupportedFormats() const override;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(USE_OPENGL) && defined(USE_GLAD)
|
||||||
|
void *getOpenGLProcAddress(const char *name) const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
PaletteManager *getPaletteManager() override { return this; }
|
PaletteManager *getPaletteManager() override { return this; }
|
||||||
|
|
||||||
|
|
|
@ -315,12 +315,12 @@ void OSystem_SDL::initBackend() {
|
||||||
|
|
||||||
#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
|
#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
|
||||||
void OSystem_SDL::detectOpenGLFeaturesSupport() {
|
void OSystem_SDL::detectOpenGLFeaturesSupport() {
|
||||||
_oglType = OpenGL::kOGLContextNone;
|
_oglType = OpenGL::kContextNone;
|
||||||
_supportsFrameBuffer = false;
|
_supportsFrameBuffer = false;
|
||||||
_supportsShaders = false;
|
_supportsShaders = false;
|
||||||
#if USE_FORCED_GLES2
|
#if USE_FORCED_GLES2
|
||||||
// Framebuffers and shaders are always available with GLES2
|
// Framebuffers and shaders are always available with GLES2
|
||||||
_oglType = OpenGL::kOGLContextGLES2;
|
_oglType = OpenGL::kContextGLES2;
|
||||||
_supportsFrameBuffer = true;
|
_supportsFrameBuffer = true;
|
||||||
_supportsShaders = true;
|
_supportsShaders = true;
|
||||||
#else
|
#else
|
||||||
|
@ -342,13 +342,13 @@ void OSystem_SDL::detectOpenGLFeaturesSupport() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (glContextMajor == 2) {
|
if (glContextMajor == 2) {
|
||||||
_oglType = OpenGL::kOGLContextGLES2;
|
_oglType = OpenGL::kContextGLES2;
|
||||||
} else {
|
} else {
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_oglType = OpenGL::kOGLContextGL;
|
_oglType = OpenGL::kContextGL;
|
||||||
}
|
}
|
||||||
SDL_GLContext glContext = SDL_GL_CreateContext(window);
|
SDL_GLContext glContext = SDL_GL_CreateContext(window);
|
||||||
if (!glContext) {
|
if (!glContext) {
|
||||||
|
@ -358,7 +358,7 @@ void OSystem_SDL::detectOpenGLFeaturesSupport() {
|
||||||
|
|
||||||
OpenGLContext.initialize(_oglType);
|
OpenGLContext.initialize(_oglType);
|
||||||
_supportsFrameBuffer = OpenGLContext.framebufferObjectSupported;
|
_supportsFrameBuffer = OpenGLContext.framebufferObjectSupported;
|
||||||
_supportsShaders = OpenGLContext.shadersSupported;
|
_supportsShaders = OpenGLContext.enginesShadersSupported;
|
||||||
OpenGLContext.reset();
|
OpenGLContext.reset();
|
||||||
SDL_GL_DeleteContext(glContext);
|
SDL_GL_DeleteContext(glContext);
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
|
@ -367,7 +367,7 @@ void OSystem_SDL::detectOpenGLFeaturesSupport() {
|
||||||
SDL_SetVideoMode(32, 32, 0, SDL_OPENGL);
|
SDL_SetVideoMode(32, 32, 0, SDL_OPENGL);
|
||||||
SDL_putenv(const_cast<char *>("SDL_VIDEO_WINDOW_POS=center"));
|
SDL_putenv(const_cast<char *>("SDL_VIDEO_WINDOW_POS=center"));
|
||||||
// SDL 1.2 only supports OpenGL
|
// SDL 1.2 only supports OpenGL
|
||||||
_oglType = OpenGL::kOGLContextGL;
|
_oglType = OpenGL::kContextGL;
|
||||||
OpenGLContext.initialize(_oglType);
|
OpenGLContext.initialize(_oglType);
|
||||||
_supportsFrameBuffer = OpenGLContext.framebufferObjectSupported;
|
_supportsFrameBuffer = OpenGLContext.framebufferObjectSupported;
|
||||||
_supportsShaders = OpenGLContext.shadersSupported;
|
_supportsShaders = OpenGLContext.shadersSupported;
|
||||||
|
@ -522,6 +522,12 @@ Common::Array<uint> OSystem_SDL::getSupportedAntiAliasingLevels() const {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_OPENGL) && defined(USE_GLAD)
|
||||||
|
void *OSystem_SDL::getOpenGLProcAddress(const char *name) const {
|
||||||
|
return SDL_GL_GetProcAddress(name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void OSystem_SDL::quit() {
|
void OSystem_SDL::quit() {
|
||||||
destroy();
|
destroy();
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
|
@ -95,7 +95,10 @@ public:
|
||||||
|
|
||||||
#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
|
#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
|
||||||
Common::Array<uint> getSupportedAntiAliasingLevels() const override;
|
Common::Array<uint> getSupportedAntiAliasingLevels() const override;
|
||||||
OpenGL::ContextOGLType getOpenGLType() const override { return _oglType; }
|
OpenGL::ContextType getOpenGLType() const override { return _oglType; }
|
||||||
|
#endif
|
||||||
|
#if defined(USE_OPENGL) && defined(USE_GLAD)
|
||||||
|
void *getOpenGLProcAddress(const char *name) const override;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -137,7 +140,7 @@ protected:
|
||||||
void detectOpenGLFeaturesSupport();
|
void detectOpenGLFeaturesSupport();
|
||||||
void detectAntiAliasingSupport();
|
void detectAntiAliasingSupport();
|
||||||
|
|
||||||
OpenGL::ContextOGLType _oglType;
|
OpenGL::ContextType _oglType;
|
||||||
bool _supportsFrameBuffer;
|
bool _supportsFrameBuffer;
|
||||||
bool _supportsShaders;
|
bool _supportsShaders;
|
||||||
Common::Array<uint> _antiAliasLevels;
|
Common::Array<uint> _antiAliasLevels;
|
||||||
|
|
|
@ -745,10 +745,25 @@ public:
|
||||||
*
|
*
|
||||||
* @return the OpenGL type of context which is supported.
|
* @return the OpenGL type of context which is supported.
|
||||||
*/
|
*/
|
||||||
virtual OpenGL::ContextOGLType getOpenGLType() const {
|
virtual OpenGL::ContextType getOpenGLType() const {
|
||||||
return OpenGL::kOGLContextNone;
|
return OpenGL::kContextNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_OPENGL) && defined(USE_GLAD)
|
||||||
|
/**
|
||||||
|
* Query the address of an OpenGL function by name.
|
||||||
|
*
|
||||||
|
* This can only be used after a context has been created.
|
||||||
|
* Please note that this function can return valid addresses even if the
|
||||||
|
* OpenGL context does not support the function.
|
||||||
|
*
|
||||||
|
* @param name The name of the OpenGL function.
|
||||||
|
* @return An function pointer for the requested OpenGL function or
|
||||||
|
* nullptr in case of failure.
|
||||||
|
*/
|
||||||
|
virtual void *getOpenGLProcAddress(const char *name) const { return nullptr; }
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a list of all hardware shaders supported by this backend.
|
* Retrieve a list of all hardware shaders supported by this backend.
|
||||||
*
|
*
|
||||||
|
|
|
@ -2215,7 +2215,7 @@ Bitmap *GfxOpenGLS::getScreenshot(int w, int h, bool useStored) {
|
||||||
Bitmap *bmp;
|
Bitmap *bmp;
|
||||||
|
|
||||||
if (useStored) {
|
if (useStored) {
|
||||||
if (OpenGLContext.type == OpenGL::kOGLContextGLES2) {
|
if (OpenGLContext.type == OpenGL::kContextGLES2) {
|
||||||
GLuint frameBuffer;
|
GLuint frameBuffer;
|
||||||
glGenFramebuffers(1, &frameBuffer);
|
glGenFramebuffers(1, &frameBuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
|
||||||
|
|
|
@ -106,7 +106,7 @@ void OpenGlTexture::setLevelCount(uint32 count) {
|
||||||
// GLES2 does not allow setting the max provided mipmap level.
|
// GLES2 does not allow setting the max provided mipmap level.
|
||||||
// It expects all the levels to be provided, which is not the case in TLJ.
|
// It expects all the levels to be provided, which is not the case in TLJ.
|
||||||
// FIXME: Enable mipmapping on GLES2
|
// FIXME: Enable mipmapping on GLES2
|
||||||
if (OpenGLContext.type != OpenGL::kOGLContextGLES2) {
|
if (OpenGLContext.type != OpenGL::kContextGLES2) {
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, count - 1);
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||||
|
@ -122,7 +122,7 @@ void OpenGlTexture::setLevelCount(uint32 count) {
|
||||||
void OpenGlTexture::addLevel(uint32 level, const Graphics::Surface *surface, const byte *palette) {
|
void OpenGlTexture::addLevel(uint32 level, const Graphics::Surface *surface, const byte *palette) {
|
||||||
assert(level < _levelCount);
|
assert(level < _levelCount);
|
||||||
|
|
||||||
if (level == 0 || OpenGLContext.type != OpenGL::kOGLContextGLES2) {
|
if (level == 0 || OpenGLContext.type != OpenGL::kContextGLES2) {
|
||||||
updateLevel(level, surface, palette);
|
updateLevel(level, surface, palette);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,75 +19,62 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define GLAD_GL_IMPLEMENTATION
|
||||||
|
|
||||||
#include "graphics/opengl/context.h"
|
#include "graphics/opengl/context.h"
|
||||||
|
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
|
#include "common/system.h"
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
#include "common/tokenizer.h"
|
#include "common/tokenizer.h"
|
||||||
|
|
||||||
#include "graphics/opengl/system_headers.h"
|
#include "graphics/opengl/system_headers.h"
|
||||||
|
|
||||||
#if defined(USE_OPENGL_GAME) || defined(USE_OPENGL_SHADERS)
|
#if defined(USE_OPENGL)
|
||||||
|
|
||||||
#ifdef USE_GLAD
|
#ifdef USE_GLAD
|
||||||
|
static GLADapiproc loadFunc(const char *name) {
|
||||||
#ifdef SDL_BACKEND
|
return (GLADapiproc)g_system->getOpenGLProcAddress(name);
|
||||||
#include "backends/platform/sdl/sdl-sys.h"
|
|
||||||
|
|
||||||
static GLADapiproc loadFunc(void *userptr, const char *name) {
|
|
||||||
return (GLADapiproc)SDL_GL_GetProcAddress(name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__ANDROID__)
|
|
||||||
// To keep includes light, don't include EGL here and don't include Android headers
|
|
||||||
void *androidGLgetProcAddress(const char *name);
|
|
||||||
|
|
||||||
static GLADapiproc loadFunc(void *userptr, const char *name) {
|
|
||||||
return (GLADapiproc)androidGLgetProcAddress(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif defined(IPHONE_IOS7)
|
|
||||||
#include "backends/platform/ios7/ios7_common.h"
|
|
||||||
|
|
||||||
static GLADapiproc loadFunc(void *userptr, const char *name) {
|
|
||||||
return (GLADapiproc)iOS7_getProcAddress(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
#error Not implemented
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
DECLARE_SINGLETON(OpenGL::ContextGL);
|
DECLARE_SINGLETON(OpenGL::Context);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
ContextGL::ContextGL() {
|
Context::Context() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContextGL::reset() {
|
void Context::reset() {
|
||||||
type = kOGLContextNone;
|
type = kContextNone;
|
||||||
maxTextureSize = 0;
|
maxTextureSize = 0;
|
||||||
|
|
||||||
|
majorVersion = 0;
|
||||||
|
minorVersion = 0;
|
||||||
|
glslVersion = 0;
|
||||||
|
|
||||||
NPOTSupported = false;
|
NPOTSupported = false;
|
||||||
shadersSupported = false;
|
shadersSupported = false;
|
||||||
|
enginesShadersSupported = false;
|
||||||
|
multitextureSupported = false;
|
||||||
framebufferObjectSupported = false;
|
framebufferObjectSupported = false;
|
||||||
|
framebufferObjectMultisampleSupported = false;
|
||||||
|
multisampleMaxSamples = -1;
|
||||||
|
packedPixelsSupported = false;
|
||||||
packedDepthStencilSupported = false;
|
packedDepthStencilSupported = false;
|
||||||
unpackSubImageSupported = false;
|
unpackSubImageSupported = false;
|
||||||
framebufferObjectMultisampleSupported = false;
|
|
||||||
OESDepth24 = false;
|
OESDepth24 = false;
|
||||||
multisampleMaxSamples = -1;
|
textureEdgeClampSupported = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContextGL::initialize(ContextOGLType contextType) {
|
void Context::initialize(ContextType contextType) {
|
||||||
// Initialize default state.
|
// Initialize default state.
|
||||||
reset();
|
reset();
|
||||||
if (contextType == kOGLContextNone) {
|
if (contextType == kContextNone) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,12 +82,16 @@ void ContextGL::initialize(ContextOGLType contextType) {
|
||||||
|
|
||||||
#ifdef USE_GLAD
|
#ifdef USE_GLAD
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case kOGLContextGL:
|
case kContextGL:
|
||||||
gladLoadGLUserPtr(loadFunc, this);
|
gladLoadGL(loadFunc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case kOGLContextGLES2:
|
case kContextGLES:
|
||||||
gladLoadGLES2UserPtr(loadFunc, this);
|
gladLoadGLES1(loadFunc);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kContextGLES2:
|
||||||
|
gladLoadGLES2(loadFunc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -108,6 +99,42 @@ void ContextGL::initialize(ContextOGLType contextType) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
const char *verString = (const char *)glGetString(GL_VERSION);
|
||||||
|
debug(5, "OpenGL version: %s", verString);
|
||||||
|
|
||||||
|
if (type == kContextGL) {
|
||||||
|
// OpenGL version number is either of the form major.minor or major.minor.release,
|
||||||
|
// where the numbers all have one or more digits
|
||||||
|
if (sscanf(verString, "%d.%d", &majorVersion, &minorVersion) != 2) {
|
||||||
|
majorVersion = minorVersion = 0;
|
||||||
|
warning("Could not parse GL version '%s'", verString);
|
||||||
|
}
|
||||||
|
} else if (type == kContextGLES) {
|
||||||
|
// The form of the string is "OpenGL ES-<profile> <major>.<minor>",
|
||||||
|
// where <profile> is either "CM" (Common) or "CL" (Common-Lite),
|
||||||
|
// and <major> and <minor> are integers.
|
||||||
|
char profile[3];
|
||||||
|
if (sscanf(verString, "OpenGL ES-%2s %d.%d", profile,
|
||||||
|
&majorVersion, &minorVersion) != 3) {
|
||||||
|
majorVersion = minorVersion = 0;
|
||||||
|
warning("Could not parse GL ES version '%s'", verString);
|
||||||
|
}
|
||||||
|
} else if (type == kContextGLES2) {
|
||||||
|
// The version is of the form
|
||||||
|
// OpenGL<space>ES<space><version number><space><vendor-specific information>
|
||||||
|
// version number format is not defined
|
||||||
|
// There is only OpenGL ES 2.0 anyway
|
||||||
|
if (sscanf(verString, "OpenGL ES %d.%d", &majorVersion, &minorVersion) != 2) {
|
||||||
|
minorVersion = 0;
|
||||||
|
if (sscanf(verString, "OpenGL ES %d ", &majorVersion) != 1) {
|
||||||
|
majorVersion = 0;
|
||||||
|
warning("Could not parse GL ES 2 version '%s'", verString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glslVersion = getGLSLVersion();
|
||||||
|
|
||||||
// Obtain maximum texture size.
|
// Obtain maximum texture size.
|
||||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&maxTextureSize);
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint *)&maxTextureSize);
|
||||||
debug(5, "OpenGL maximum texture size: %d", maxTextureSize);
|
debug(5, "OpenGL maximum texture size: %d", maxTextureSize);
|
||||||
|
@ -135,8 +162,12 @@ void ContextGL::initialize(ContextOGLType contextType) {
|
||||||
ARBVertexShader = true;
|
ARBVertexShader = true;
|
||||||
} else if (token == "GL_ARB_fragment_shader") {
|
} else if (token == "GL_ARB_fragment_shader") {
|
||||||
ARBFragmentShader = true;
|
ARBFragmentShader = true;
|
||||||
|
} else if (token == "GL_ARB_multitexture") {
|
||||||
|
multitextureSupported = true;
|
||||||
} else if (token == "GL_ARB_framebuffer_object") {
|
} else if (token == "GL_ARB_framebuffer_object") {
|
||||||
framebufferObjectSupported = true;
|
framebufferObjectSupported = true;
|
||||||
|
} else if (token == "GL_EXT_packed_pixels" || token == "GL_APPLE_packed_pixels") {
|
||||||
|
packedPixelsSupported = true;
|
||||||
} else if (token == "GL_EXT_packed_depth_stencil" || token == "GL_OES_packed_depth_stencil") {
|
} else if (token == "GL_EXT_packed_depth_stencil" || token == "GL_OES_packed_depth_stencil") {
|
||||||
packedDepthStencilSupported = true;
|
packedDepthStencilSupported = true;
|
||||||
} else if (token == "GL_EXT_unpack_subimage") {
|
} else if (token == "GL_EXT_unpack_subimage") {
|
||||||
|
@ -147,19 +178,22 @@ void ContextGL::initialize(ContextOGLType contextType) {
|
||||||
EXTFramebufferBlit = true;
|
EXTFramebufferBlit = true;
|
||||||
} else if (token == "GL_OES_depth24") {
|
} else if (token == "GL_OES_depth24") {
|
||||||
OESDepth24 = true;
|
OESDepth24 = true;
|
||||||
|
} else if (token == "GL_SGIS_texture_edge_clamp") {
|
||||||
|
textureEdgeClampSupported = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int glslVersion = getGLSLVersion();
|
if (type == kContextGLES2) {
|
||||||
debug(5, "OpenGL GLSL version: %d", glslVersion);
|
|
||||||
|
|
||||||
if (type == kOGLContextGLES2) {
|
|
||||||
// GLES2 always has (limited) NPOT support.
|
// GLES2 always has (limited) NPOT support.
|
||||||
NPOTSupported = true;
|
NPOTSupported = true;
|
||||||
|
|
||||||
// GLES2 always has shader support.
|
// GLES2 always has shader support.
|
||||||
shadersSupported = true;
|
shadersSupported = true;
|
||||||
|
// GLES2 should always have GLSL ES 1.00 support but let's make sure
|
||||||
|
enginesShadersSupported = (glslVersion >= 100);
|
||||||
|
|
||||||
|
// GLES2 always has multi texture support.
|
||||||
|
multitextureSupported = true;
|
||||||
|
|
||||||
// GLES2 always has FBO support.
|
// GLES2 always has FBO support.
|
||||||
framebufferObjectSupported = true;
|
framebufferObjectSupported = true;
|
||||||
|
@ -167,8 +201,42 @@ void ContextGL::initialize(ContextOGLType contextType) {
|
||||||
// ScummVM does not support multisample FBOs with GLES2 for now
|
// ScummVM does not support multisample FBOs with GLES2 for now
|
||||||
framebufferObjectMultisampleSupported = false;
|
framebufferObjectMultisampleSupported = false;
|
||||||
multisampleMaxSamples = -1;
|
multisampleMaxSamples = -1;
|
||||||
} else {
|
|
||||||
shadersSupported = ARBShaderObjects && ARBShadingLanguage100 && ARBVertexShader && ARBFragmentShader && glslVersion >= 120;
|
packedPixelsSupported = true;
|
||||||
|
textureEdgeClampSupported = true;
|
||||||
|
debug(5, "OpenGL: GLES2 context initialized");
|
||||||
|
} else if (type == kContextGLES) {
|
||||||
|
// GLES doesn't support shaders natively
|
||||||
|
// We don't do any aliasing in our code and expect standard OpenGL functions but GLAD does it
|
||||||
|
// So if we use GLAD we can check for ARB extensions and expect a GLSL of 1.00
|
||||||
|
#ifdef USE_GLAD
|
||||||
|
shadersSupported = ARBShaderObjects && ARBShadingLanguage100 && ARBVertexShader && ARBFragmentShader;
|
||||||
|
glslVersion = 100;
|
||||||
|
#endif
|
||||||
|
// We don't expect GLES to support shaders recent enough for engines
|
||||||
|
|
||||||
|
// ScummVM does not support multisample FBOs with GLES for now
|
||||||
|
framebufferObjectMultisampleSupported = false;
|
||||||
|
multisampleMaxSamples = -1;
|
||||||
|
|
||||||
|
packedPixelsSupported = true;
|
||||||
|
textureEdgeClampSupported = true;
|
||||||
|
debug(5, "OpenGL: GLES context initialized");
|
||||||
|
} else if (type == kContextGL) {
|
||||||
|
shadersSupported = glslVersion >= 100;
|
||||||
|
|
||||||
|
// We don't do any aliasing in our code and expect standard OpenGL functions but GLAD does it
|
||||||
|
// So if we use GLAD we can check for ARB extensions and expect a GLSL of 1.00
|
||||||
|
#ifdef USE_GLAD
|
||||||
|
if (!shadersSupported) {
|
||||||
|
shadersSupported = ARBShaderObjects && ARBShadingLanguage100 && ARBVertexShader && ARBFragmentShader;
|
||||||
|
if (shadersSupported) {
|
||||||
|
glslVersion = 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// In GL mode engines need GLSL 1.20
|
||||||
|
enginesShadersSupported = glslVersion >= 120;
|
||||||
|
|
||||||
// Desktop GL always has unpack sub-image support
|
// Desktop GL always has unpack sub-image support
|
||||||
unpackSubImageSupported = true;
|
unpackSubImageSupported = true;
|
||||||
|
@ -178,31 +246,50 @@ void ContextGL::initialize(ContextOGLType contextType) {
|
||||||
if (framebufferObjectMultisampleSupported) {
|
if (framebufferObjectMultisampleSupported) {
|
||||||
glGetIntegerv(GL_MAX_SAMPLES, (GLint *)&multisampleMaxSamples);
|
glGetIntegerv(GL_MAX_SAMPLES, (GLint *)&multisampleMaxSamples);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Log context type.
|
// OpenGL 1.2 and later always has packed pixels and texture edge clamp support
|
||||||
switch (type) {
|
if (isGLVersionOrHigher(1, 2)) {
|
||||||
case kOGLContextNone:
|
packedPixelsSupported = true;
|
||||||
/* Shouldn't happen */
|
textureEdgeClampSupported = true;
|
||||||
break;
|
}
|
||||||
case kOGLContextGL:
|
debug(5, "OpenGL: GL context initialized");
|
||||||
debug(5, "OpenGL: GL context initialized");
|
} else {
|
||||||
break;
|
warning("OpenGL: Unknown context initialized");
|
||||||
|
|
||||||
case kOGLContextGLES2:
|
|
||||||
debug(5, "OpenGL: GLES2 context initialized");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log features supported by GL context.
|
// Log features supported by GL context.
|
||||||
|
debug(5, "OpenGL vendor: %s", glGetString(GL_VENDOR));
|
||||||
|
debug(5, "OpenGL renderer: %s", glGetString(GL_RENDERER));
|
||||||
|
debug(5, "OpenGL: version %d.%d", majorVersion, minorVersion);
|
||||||
|
debug(5, "OpenGL: GLSL version: %d", glslVersion);
|
||||||
|
debug(5, "OpenGL: Max texture size: %d", maxTextureSize);
|
||||||
debug(5, "OpenGL: NPOT texture support: %d", NPOTSupported);
|
debug(5, "OpenGL: NPOT texture support: %d", NPOTSupported);
|
||||||
debug(5, "OpenGL: Shader support: %d", shadersSupported);
|
debug(5, "OpenGL: Shader support: %d", shadersSupported);
|
||||||
|
debug(5, "OpenGL: Multitexture support: %d", multitextureSupported);
|
||||||
debug(5, "OpenGL: FBO support: %d", framebufferObjectSupported);
|
debug(5, "OpenGL: FBO support: %d", framebufferObjectSupported);
|
||||||
|
debug(5, "OpenGL: Multisample FBO support: %d", framebufferObjectMultisampleSupported);
|
||||||
|
debug(5, "OpenGL: Multisample max number: %d", multisampleMaxSamples);
|
||||||
|
debug(5, "OpenGL: Packed pixels support: %d", packedPixelsSupported);
|
||||||
debug(5, "OpenGL: Packed depth stencil support: %d", packedDepthStencilSupported);
|
debug(5, "OpenGL: Packed depth stencil support: %d", packedDepthStencilSupported);
|
||||||
debug(5, "OpenGL: Unpack subimage support: %d", unpackSubImageSupported);
|
debug(5, "OpenGL: Unpack subimage support: %d", unpackSubImageSupported);
|
||||||
|
debug(5, "OpenGL: OpenGL ES depth 24 support: %d", OESDepth24);
|
||||||
|
debug(5, "OpenGL: Texture edge clamping support: %d", textureEdgeClampSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ContextGL::getGLSLVersion() const {
|
int Context::getGLSLVersion() const {
|
||||||
|
#if USE_FORCED_GLES
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
// No shader support in GLES
|
||||||
|
if (type == kContextGLES) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No shader support in OpenGL 1.x
|
||||||
|
if (type == kContextGL && !isGLVersionOrHigher(2, 0)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const char *glslVersionString = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
|
const char *glslVersionString = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION);
|
||||||
if (!glslVersionString) {
|
if (!glslVersionString) {
|
||||||
warning("Could not get GLSL version");
|
warning("Could not get GLSL version");
|
||||||
|
@ -210,7 +297,7 @@ int ContextGL::getGLSLVersion() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *glslVersionFormat;
|
const char *glslVersionFormat;
|
||||||
if (type == kOGLContextGL) {
|
if (type == kContextGL) {
|
||||||
glslVersionFormat = "%d.%d";
|
glslVersionFormat = "%d.%d";
|
||||||
} else {
|
} else {
|
||||||
glslVersionFormat = "OpenGL ES GLSL ES %d.%d";
|
glslVersionFormat = "OpenGL ES GLSL ES %d.%d";
|
||||||
|
@ -223,6 +310,7 @@ int ContextGL::getGLSLVersion() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
return glslMajorVersion * 100 + glslMinorVersion;
|
return glslMajorVersion * 100 + glslMinorVersion;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace OpenGL
|
} // End of namespace OpenGL
|
||||||
|
|
|
@ -26,20 +26,19 @@
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
|
|
||||||
enum ContextOGLType {
|
enum ContextType {
|
||||||
kOGLContextNone,
|
kContextNone,
|
||||||
kOGLContextGL,
|
kContextGL,
|
||||||
kOGLContextGLES2
|
kContextGLES,
|
||||||
|
kContextGLES2
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description structure of the OpenGL (ES) context.
|
* Description structure of the OpenGL (ES) context.
|
||||||
*
|
|
||||||
* This class is based on LordHoto's OpenGL backend for ScummVM
|
|
||||||
*/
|
*/
|
||||||
class ContextGL : public Common::Singleton<ContextGL> {
|
class Context : public Common::Singleton<Context> {
|
||||||
public:
|
public:
|
||||||
ContextGL();
|
Context();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the context description from currently active context.
|
* Initialize the context description from currently active context.
|
||||||
|
@ -47,7 +46,7 @@ public:
|
||||||
* The extensions and features are marked as available according
|
* The extensions and features are marked as available according
|
||||||
* to the current context capabilities.
|
* to the current context capabilities.
|
||||||
*/
|
*/
|
||||||
void initialize(ContextOGLType contextType);
|
void initialize(ContextType contextType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset context.
|
* Reset context.
|
||||||
|
@ -57,7 +56,18 @@ public:
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
/** The type of the active context. */
|
/** The type of the active context. */
|
||||||
ContextOGLType type;
|
ContextType type;
|
||||||
|
|
||||||
|
/** Helper function for checking the GL version supported by the context. */
|
||||||
|
inline bool isGLVersionOrHigher(int major, int minor) const {
|
||||||
|
return ((majorVersion > major) || ((majorVersion == major) && (minorVersion >= minor)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** The GL version supported by the context. */
|
||||||
|
int majorVersion, minorVersion;
|
||||||
|
|
||||||
|
/** The GLSL version supported by the context */
|
||||||
|
int glslVersion;
|
||||||
|
|
||||||
/** The maximum texture size supported by the context. */
|
/** The maximum texture size supported by the context. */
|
||||||
int maxTextureSize;
|
int maxTextureSize;
|
||||||
|
@ -68,6 +78,12 @@ public:
|
||||||
/** Whether shader support is available or not. */
|
/** Whether shader support is available or not. */
|
||||||
bool shadersSupported;
|
bool shadersSupported;
|
||||||
|
|
||||||
|
/** Whether shader support is good enough for engines or not. */
|
||||||
|
bool enginesShadersSupported;
|
||||||
|
|
||||||
|
/** Whether multi texture support is available or not. */
|
||||||
|
bool multitextureSupported;
|
||||||
|
|
||||||
/** Whether FBO support is available or not. */
|
/** Whether FBO support is available or not. */
|
||||||
bool framebufferObjectSupported;
|
bool framebufferObjectSupported;
|
||||||
|
|
||||||
|
@ -80,6 +96,9 @@ public:
|
||||||
*/
|
*/
|
||||||
int multisampleMaxSamples;
|
int multisampleMaxSamples;
|
||||||
|
|
||||||
|
/** Whether packed pixels support is available or not. */
|
||||||
|
bool packedPixelsSupported;
|
||||||
|
|
||||||
/** Whether packing the depth and stencil buffers is possible or not. */
|
/** Whether packing the depth and stencil buffers is possible or not. */
|
||||||
bool packedDepthStencilSupported;
|
bool packedDepthStencilSupported;
|
||||||
|
|
||||||
|
@ -89,12 +108,20 @@ public:
|
||||||
/** Whether depth component 24 is supported or not */
|
/** Whether depth component 24 is supported or not */
|
||||||
bool OESDepth24;
|
bool OESDepth24;
|
||||||
|
|
||||||
|
/** Whether texture coordinate edge clamping is available or not. */
|
||||||
|
bool textureEdgeClampSupported;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Returns the native GLSL version supported by the driver.
|
||||||
|
* This does NOT take shaders ARB extensions into account.
|
||||||
|
*/
|
||||||
int getGLSLVersion() const;
|
int getGLSLVersion() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace OpenGL
|
} // End of namespace OpenGL
|
||||||
|
|
||||||
/** Shortcut for accessing the active OpenGL context. */
|
/** Shortcut for accessing the active OpenGL context. */
|
||||||
#define OpenGLContext OpenGL::ContextGL::instance()
|
#define OpenGLContext OpenGL::Context::instance()
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -133,7 +133,7 @@ static GLuint createDirectShader(const char *shaderSource, GLenum shaderType, co
|
||||||
}
|
}
|
||||||
|
|
||||||
static GLuint createCompatShader(const char *shaderSource, GLenum shaderType, const Common::String &name) {
|
static GLuint createCompatShader(const char *shaderSource, GLenum shaderType, const Common::String &name) {
|
||||||
const GLchar *versionSource = OpenGLContext.type == kOGLContextGLES2 ? "#version 100\n" : "#version 120\n";
|
const GLchar *versionSource = OpenGLContext.type == kContextGLES2 ? "#version 100\n" : "#version 120\n";
|
||||||
const GLchar *compatSource =
|
const GLchar *compatSource =
|
||||||
shaderType == GL_VERTEX_SHADER ? compatVertex : compatFragment;
|
shaderType == GL_VERTEX_SHADER ? compatVertex : compatFragment;
|
||||||
const GLchar *shaderSources[] = {
|
const GLchar *shaderSources[] = {
|
||||||
|
|
|
@ -93,7 +93,7 @@ uint32 Renderer::getAvailableTypes() {
|
||||||
/* Backend either support OpenGL or OpenGL ES(2) */
|
/* Backend either support OpenGL or OpenGL ES(2) */
|
||||||
#if defined(USE_OPENGL_GAME)
|
#if defined(USE_OPENGL_GAME)
|
||||||
/* OpenGL classic is compiled in, check if hardware supports it */
|
/* OpenGL classic is compiled in, check if hardware supports it */
|
||||||
if (g_system->getOpenGLType() == OpenGL::kOGLContextGL) {
|
if (g_system->getOpenGLType() == OpenGL::kContextGL) {
|
||||||
available |= kRendererTypeOpenGL;
|
available |= kRendererTypeOpenGL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue