OPENGL: Add support for shaders with GL contexts.
This commit is contained in:
parent
19abd8ccbb
commit
fee1aa5502
9 changed files with 360 additions and 56 deletions
|
@ -74,14 +74,35 @@ void OpenGLGraphicsManager::initializeGLContext() {
|
|||
|
||||
const char *extString = (const char *)g_context.glGetString(GL_EXTENSIONS);
|
||||
|
||||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
bool ARBShaderObjects = false;
|
||||
bool ARBShadingLanguage100 = false;
|
||||
bool ARBVertexShader = false;
|
||||
bool ARBFragmentShader = false;
|
||||
#endif
|
||||
|
||||
Common::StringTokenizer tokenizer(extString, " ");
|
||||
while (!tokenizer.empty()) {
|
||||
Common::String token = tokenizer.nextToken();
|
||||
|
||||
if (token == "GL_ARB_texture_non_power_of_two") {
|
||||
g_context.NPOTSupported = true;
|
||||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
} 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;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
g_context.shadersSupported = ARBShaderObjects & ARBShadingLanguage100 & ARBVertexShader & ARBFragmentShader;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // End of namespace OpenGL
|
||||
|
|
|
@ -76,6 +76,12 @@ typedef float GLclampf; /* single precision float in [0,1] */
|
|||
typedef double GLdouble; /* double precision float */
|
||||
typedef double GLclampd; /* double precision float in [0,1] */
|
||||
typedef char GLchar;
|
||||
typedef GLchar GLcharARB;
|
||||
#if defined(__APPLE__) || defined(MACOSX)
|
||||
typedef void *GLhandleARB;
|
||||
#else
|
||||
typedef uint GLhandleARB;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Constants
|
||||
|
@ -223,13 +229,20 @@ typedef char GLchar;
|
|||
|
||||
/* Shaders */
|
||||
#define GL_FRAGMENT_SHADER 0x8B30
|
||||
#define GL_FRAGMENT_SHADER_ARB 0x8B30
|
||||
|
||||
#define GL_VERTEX_SHADER 0x8B31
|
||||
#define GL_VERTEX_SHADER_ARB 0x8B31
|
||||
|
||||
/* Programs */
|
||||
#define GL_COMPILE_STATUS 0x8B81
|
||||
#define GL_LINK_STATUS 0x8B82
|
||||
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||
|
||||
#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81
|
||||
#define GL_OBJECT_LINK_STATUS_ARB 0x8B82
|
||||
#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84
|
||||
|
||||
/* Textures */
|
||||
#define GL_TEXTURE0 0x84C0
|
||||
|
||||
|
|
|
@ -116,3 +116,24 @@ GL_FUNC_DEF(void, glGetShaderInfoLog, (GLuint shader, GLsizei bufSize, GLsizei *
|
|||
GL_FUNC_DEF(void, glEnableVertexAttribArray, (GLuint index));
|
||||
GL_FUNC_DEF(void, glActiveTexture, (GLenum texture));
|
||||
#endif
|
||||
|
||||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
GL_EXT_FUNC_DEF(void, glDeleteObjectARB, (GLhandleARB obj));
|
||||
GL_EXT_FUNC_DEF(GLhandleARB, glCreateProgramObjectARB, ());
|
||||
GL_EXT_FUNC_DEF(void, glAttachObjectARB, (GLhandleARB containerObj, GLhandleARB obj));
|
||||
GL_EXT_FUNC_DEF(void, glBindAttribLocationARB, (GLhandleARB programObj, GLuint index, const GLcharARB *name));
|
||||
GL_EXT_FUNC_DEF(void, glLinkProgramARB, (GLhandleARB programObj));
|
||||
GL_EXT_FUNC_DEF(void, glDetachObjectARB, (GLhandleARB containerObj, GLhandleARB attachedObj));
|
||||
GL_EXT_FUNC_DEF(void, glGetObjectParameterivARB, (GLhandleARB obj, GLenum pname, GLint *params));
|
||||
GL_EXT_FUNC_DEF(GLint, glGetUniformLocationARB, (GLhandleARB programObj, const GLcharARB *name));
|
||||
GL_EXT_FUNC_DEF(void, glGetInfoLogARB, (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog));
|
||||
GL_EXT_FUNC_DEF(void, glUseProgramObjectARB, (GLhandleARB programObj));
|
||||
GL_EXT_FUNC_DEF(void, glUniformMatrix4fvARB, (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value));
|
||||
GL_EXT_FUNC_DEF(void, glUniform1iARB, (GLint location, GLint v0));
|
||||
GL_EXT_FUNC_DEF(GLhandleARB, glCreateShaderObjectARB, (GLenum shaderType));
|
||||
GL_EXT_FUNC_DEF(void, glShaderSourceARB, (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length));
|
||||
GL_EXT_FUNC_DEF(void, glCompileShaderARB, (GLhandleARB shaderObj));
|
||||
GL_EXT_FUNC_DEF(void, glVertexAttribPointerARB, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer));
|
||||
GL_EXT_FUNC_DEF(void, glVertexAttrib4fARB, (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w));
|
||||
GL_EXT_FUNC_DEF(void, glEnableVertexAttribArrayARB, (GLuint index));
|
||||
#endif
|
||||
|
|
|
@ -55,7 +55,7 @@ OpenGLGraphicsManager::OpenGLGraphicsManager()
|
|||
#ifdef USE_OSD
|
||||
, _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
#if !USE_FORCED_GLES
|
||||
, _shader(nullptr), _projectionMatrix()
|
||||
#endif
|
||||
{
|
||||
|
@ -70,7 +70,7 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
|
|||
#ifdef USE_OSD
|
||||
delete _osd;
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
#if !USE_FORCED_GLES
|
||||
delete _shader;
|
||||
#endif
|
||||
}
|
||||
|
@ -773,7 +773,8 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
|
|||
};
|
||||
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
if (g_context.type != kContextGLES2) {
|
||||
if (g_context.type == kContextGLES
|
||||
|| (g_context.type == kContextGL && !g_context.shadersSupported)) {
|
||||
#endif
|
||||
#if !USE_FORCED_GLES2
|
||||
GL_CALL(glMatrixMode(GL_PROJECTION));
|
||||
|
@ -785,7 +786,7 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
|
|||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
} else {
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
#if !USE_FORCED_GLES
|
||||
assert(sizeof(_projectionMatrix) == sizeof(orthoProjection));
|
||||
memcpy(_projectionMatrix, orthoProjection, sizeof(_projectionMatrix));
|
||||
if (_shader) {
|
||||
|
@ -894,17 +895,7 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
|
|||
GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
if (g_context.type != kContextGLES2) {
|
||||
#endif
|
||||
#if !USE_FORCED_GLES2
|
||||
// Enable rendering with vertex and coord arrays.
|
||||
GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
|
||||
GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
|
||||
GL_CALL(glEnable(GL_TEXTURE_2D));
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
} else {
|
||||
if (g_context.type == kContextGLES2) {
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
|
||||
|
@ -912,6 +903,25 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
|
|||
|
||||
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
} else {
|
||||
#endif
|
||||
#if !USE_FORCED_GLES2
|
||||
#if !USE_FORCED_GLES
|
||||
if (g_context.shadersSupported) {
|
||||
GL_CALL(glEnableVertexAttribArrayARB(kPositionAttribLocation));
|
||||
GL_CALL(glEnableVertexAttribArrayARB(kTexCoordAttribLocation));
|
||||
} else {
|
||||
#endif
|
||||
// Enable rendering with vertex and coord arrays.
|
||||
GL_CALL(glEnableClientState(GL_VERTEX_ARRAY));
|
||||
GL_CALL(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
|
||||
#if !USE_FORCED_GLES
|
||||
}
|
||||
#endif
|
||||
|
||||
GL_CALL(glEnable(GL_TEXTURE_2D));
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
}
|
||||
#endif
|
||||
|
@ -934,19 +944,33 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
|
|||
// Query information needed by textures.
|
||||
Texture::queryTextureInformation();
|
||||
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
#if !USE_FORCED_GLES
|
||||
if (!_shader) {
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES2
|
||||
if (g_context.type == kContextGLES2) {
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
if (!_shader) {
|
||||
_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
|
||||
#if !USE_FORCED_GL
|
||||
_shader = new ShaderGLES2(g_defaultVertexShader, g_defaultFragmentShaderGLES2);
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES2
|
||||
} else {
|
||||
#endif
|
||||
#if !USE_FORCED_GLES2
|
||||
if (g_context.shadersSupported) {
|
||||
_shader = new ShaderARB(g_defaultVertexShader, g_defaultFragmentShaderGL);
|
||||
}
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES2
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !USE_FORCED_GLES
|
||||
if (_shader) {
|
||||
// TODO: What do we do on failure?
|
||||
_shader->recreate();
|
||||
_shader->activate(_projectionMatrix);
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -999,7 +1023,7 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
#if !USE_FORCED_GLES
|
||||
if (_shader) {
|
||||
_shader->destroy();
|
||||
}
|
||||
|
@ -1080,16 +1104,24 @@ Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &forma
|
|||
|
||||
void OpenGLGraphicsManager::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
if (g_context.type != kContextGLES2) {
|
||||
if (g_context.type == kContextGLES2) {
|
||||
#endif
|
||||
#if !USE_FORCED_GLES2
|
||||
GL_CALL(glColor4f(r, g, b, a));
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
} else {
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
|
||||
#if !USE_FORCED_GLES2
|
||||
#if !USE_FORCED_GLES
|
||||
if (g_context.shadersSupported) {
|
||||
GL_CALL(glVertexAttrib4fARB(kColorAttribLocation, r, g, b, a));
|
||||
} else {
|
||||
#endif
|
||||
GL_CALL(glColor4f(r, g, b, a));
|
||||
#if !USE_FORCED_GLES
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace OpenGL {
|
|||
#define USE_OSD 1
|
||||
|
||||
class Texture;
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
#if !USE_FORCED_GLES
|
||||
class Shader;
|
||||
#endif
|
||||
|
||||
|
@ -529,7 +529,7 @@ private:
|
|||
*/
|
||||
uint _scissorOverride;
|
||||
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
#if !USE_FORCED_GLES
|
||||
//
|
||||
// Shaders
|
||||
//
|
||||
|
|
|
@ -92,6 +92,11 @@ struct Context {
|
|||
/** Whether GL_ARB_texture_non_power_of_two is available or not. */
|
||||
bool NPOTSupported;
|
||||
|
||||
#if !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
/** Whether shader support is available or not. */
|
||||
bool shadersSupported;
|
||||
#endif
|
||||
|
||||
#define GL_FUNC_DEF(ret, name, param) ret (GL_CALL_CONV *name)param
|
||||
#define GL_EXT_FUNC_DEF GL_FUNC_DEF
|
||||
#include "backends/graphics/opengl/opengl-func.h"
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "backends/graphics/opengl/shader.h"
|
||||
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
#if !USE_FORCED_GLES
|
||||
|
||||
#include "common/textconsole.h"
|
||||
|
||||
|
@ -44,7 +44,20 @@ const char *const g_defaultVertexShader =
|
|||
"\tgl_Position = projection * position;\n"
|
||||
"}\n";
|
||||
|
||||
const char *const g_defaultFragmentShader =
|
||||
#if !USE_FORCED_GLES2
|
||||
const char *const g_defaultFragmentShaderGL =
|
||||
"varying vec2 texCoord;\n"
|
||||
"varying vec4 blendColor;\n"
|
||||
"\n"
|
||||
"uniform sampler2D texture;\n"
|
||||
"\n"
|
||||
"void main(void) {\n"
|
||||
"\tgl_FragColor = blendColor * texture2D(texture, texCoord);\n"
|
||||
"}\n";
|
||||
#endif
|
||||
|
||||
#if !USE_FORCED_GL
|
||||
const char *const g_defaultFragmentShaderGLES2 =
|
||||
"varying lowp vec2 texCoord;\n"
|
||||
"varying lowp vec4 blendColor;\n"
|
||||
"\n"
|
||||
|
@ -53,17 +66,146 @@ const char *const g_defaultFragmentShader =
|
|||
"void main(void) {\n"
|
||||
"\tgl_FragColor = blendColor * texture2D(texture, texCoord);\n"
|
||||
"}\n";
|
||||
#endif
|
||||
|
||||
Shader::Shader(const Common::String &vertex, const Common::String &fragment)
|
||||
: _vertex(vertex), _fragment(fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
|
||||
#if !USE_FORCED_GLES2
|
||||
|
||||
ShaderARB::ShaderARB(const Common::String &vertex, const Common::String &fragment)
|
||||
: Shader(vertex, fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
|
||||
}
|
||||
|
||||
void Shader::destroy() {
|
||||
void ShaderARB::destroy() {
|
||||
// According to extension specification glDeleteObjectARB silently ignores
|
||||
// 0. However, with nVidia drivers this can cause GL_INVALID_VALUE, thus
|
||||
// we do not call it with 0 as parameter to avoid warnings.
|
||||
if (_program) {
|
||||
GL_CALL(glDeleteObjectARB(_program));
|
||||
}
|
||||
_program = 0;
|
||||
}
|
||||
|
||||
bool ShaderARB::recreate() {
|
||||
// Make sure any old programs are destroyed properly.
|
||||
destroy();
|
||||
|
||||
GLhandleARB vertexShader = compileShader(_vertex.c_str(), GL_VERTEX_SHADER_ARB);
|
||||
if (!vertexShader) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GLhandleARB fragmentShader = compileShader(_fragment.c_str(), GL_FRAGMENT_SHADER_ARB);
|
||||
if (!fragmentShader) {
|
||||
GL_CALL(glDeleteObjectARB(vertexShader));
|
||||
return false;
|
||||
}
|
||||
|
||||
GL_ASSIGN(_program, glCreateProgramObjectARB());
|
||||
if (!_program) {
|
||||
GL_CALL(glDeleteObjectARB(vertexShader));
|
||||
GL_CALL(glDeleteObjectARB(fragmentShader));
|
||||
return false;
|
||||
}
|
||||
|
||||
GL_CALL(glAttachObjectARB(_program, vertexShader));
|
||||
GL_CALL(glAttachObjectARB(_program, fragmentShader));
|
||||
|
||||
GL_CALL(glBindAttribLocationARB(_program, kPositionAttribLocation, "position"));
|
||||
GL_CALL(glBindAttribLocationARB(_program, kTexCoordAttribLocation, "texCoordIn"));
|
||||
GL_CALL(glBindAttribLocationARB(_program, kColorAttribLocation, "blendColorIn"));
|
||||
|
||||
GL_CALL(glLinkProgramARB(_program));
|
||||
|
||||
GL_CALL(glDetachObjectARB(_program, fragmentShader));
|
||||
GL_CALL(glDeleteObjectARB(fragmentShader));
|
||||
|
||||
GL_CALL(glDetachObjectARB(_program, vertexShader));
|
||||
GL_CALL(glDeleteObjectARB(vertexShader));
|
||||
|
||||
GLint result;
|
||||
GL_CALL(glGetObjectParameterivARB(_program, GL_OBJECT_LINK_STATUS_ARB, &result));
|
||||
if (result == GL_FALSE) {
|
||||
GLint logSize;
|
||||
GL_CALL(glGetObjectParameterivARB(_program, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logSize));
|
||||
|
||||
GLchar *log = new GLchar[logSize];
|
||||
GL_CALL(glGetInfoLogARB(_program, logSize, nullptr, log));
|
||||
warning("Could not link shader: \"%s\"", log);
|
||||
delete[] log;
|
||||
|
||||
destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
GL_ASSIGN(_projectionLocation, glGetUniformLocationARB(_program, "projection"));
|
||||
if (_projectionLocation == -1) {
|
||||
warning("Shader misses \"projection\" uniform.");
|
||||
destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
GL_ASSIGN(_textureLocation, glGetUniformLocationARB(_program, "texture"));
|
||||
if (_textureLocation == -1) {
|
||||
warning("Shader misses \"texture\" uniform.");
|
||||
destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShaderARB::activate(const GLfloat *projectionMatrix) {
|
||||
// Activate program.
|
||||
GL_CALL(glUseProgramObjectARB(_program));
|
||||
|
||||
// Set projection matrix.
|
||||
GL_CALL(glUniformMatrix4fvARB(_projectionLocation, 1, GL_FALSE, projectionMatrix));
|
||||
|
||||
// We always use texture unit 0.
|
||||
GL_CALL(glUniform1iARB(_textureLocation, 0));
|
||||
}
|
||||
|
||||
GLhandleARB ShaderARB::compileShader(const char *source, GLenum shaderType) {
|
||||
GLuint handle;
|
||||
GL_ASSIGN(handle, glCreateShaderObjectARB(shaderType));
|
||||
if (!handle) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
GL_CALL(glShaderSourceARB(handle, 1, &source, nullptr));
|
||||
GL_CALL(glCompileShaderARB(handle));
|
||||
|
||||
GLint result;
|
||||
GL_CALL(glGetObjectParameterivARB(handle, GL_OBJECT_COMPILE_STATUS_ARB, &result));
|
||||
if (result == GL_FALSE) {
|
||||
GLint logSize;
|
||||
GL_CALL(glGetObjectParameterivARB(handle, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logSize));
|
||||
|
||||
GLchar *log = new GLchar[logSize];
|
||||
GL_CALL(glGetInfoLogARB(handle, logSize, nullptr, log));
|
||||
warning("Could not compile shader \"%s\": \"%s\"", source, log);
|
||||
delete[] log;
|
||||
|
||||
GL_CALL(glDeleteObjectARB(handle));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
#endif // !USE_FORCED_GLES2
|
||||
|
||||
#if !USE_FORCED_GL
|
||||
|
||||
ShaderGLES2::ShaderGLES2(const Common::String &vertex, const Common::String &fragment)
|
||||
: Shader(vertex, fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
|
||||
}
|
||||
|
||||
void ShaderGLES2::destroy() {
|
||||
GL_CALL(glDeleteProgram(_program));
|
||||
_program = 0;
|
||||
}
|
||||
|
||||
bool Shader::recreate() {
|
||||
bool ShaderGLES2::recreate() {
|
||||
// Make sure any old programs are destroyed properly.
|
||||
destroy();
|
||||
|
||||
|
@ -132,7 +274,7 @@ bool Shader::recreate() {
|
|||
return true;
|
||||
}
|
||||
|
||||
void Shader::activate(const GLfloat *projectionMatrix) {
|
||||
void ShaderGLES2::activate(const GLfloat *projectionMatrix) {
|
||||
// Activate program.
|
||||
GL_CALL(glUseProgram(_program));
|
||||
|
||||
|
@ -143,7 +285,7 @@ void Shader::activate(const GLfloat *projectionMatrix) {
|
|||
GL_CALL(glUniform1i(_textureLocation, 0));
|
||||
}
|
||||
|
||||
GLuint Shader::compileShader(const char *source, GLenum shaderType) {
|
||||
GLuint ShaderGLES2::compileShader(const char *source, GLenum shaderType) {
|
||||
GLuint handle;
|
||||
GL_ASSIGN(handle, glCreateShader(shaderType));
|
||||
if (!handle) {
|
||||
|
@ -171,6 +313,8 @@ GLuint Shader::compileShader(const char *source, GLenum shaderType) {
|
|||
return handle;
|
||||
}
|
||||
|
||||
#endif // !!USE_FORCED_GL
|
||||
|
||||
} // End of namespace OpenGL
|
||||
|
||||
#endif // !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
#endif // !USE_FORCED_GLES
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "backends/graphics/opengl/opengl-sys.h"
|
||||
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
#if !USE_FORCED_GLES
|
||||
|
||||
#include "common/str.h"
|
||||
|
||||
|
@ -38,12 +38,18 @@ enum {
|
|||
};
|
||||
|
||||
extern const char *const g_defaultVertexShader;
|
||||
extern const char *const g_defaultFragmentShader;
|
||||
#if !USE_FORCED_GLES2
|
||||
extern const char *const g_defaultFragmentShaderGL;
|
||||
#endif
|
||||
#if !USE_FORCED_GL
|
||||
extern const char *const g_defaultFragmentShaderGLES2;
|
||||
#endif
|
||||
|
||||
class Shader {
|
||||
public:
|
||||
Shader(const Common::String &vertex, const Common::String &fragment);
|
||||
~Shader() { destroy(); }
|
||||
Shader(const Common::String &vertex, const Common::String &fragment)
|
||||
: _vertex(vertex), _fragment(fragment) {}
|
||||
virtual ~Shader() {}
|
||||
|
||||
/**
|
||||
* Destroy the shader program.
|
||||
|
@ -51,22 +57,22 @@ public:
|
|||
* This keeps the vertex and fragment shader sources around and thus
|
||||
* allows for recreating the shader on context recreation.
|
||||
*/
|
||||
void destroy();
|
||||
virtual void destroy() = 0;
|
||||
|
||||
/**
|
||||
* Recreate shader program.
|
||||
*
|
||||
* @return true on success, false on failure.
|
||||
*/
|
||||
bool recreate();
|
||||
virtual bool recreate() = 0;
|
||||
|
||||
/**
|
||||
* Make shader active.
|
||||
*
|
||||
* @param projectionMatrix Projection matrix to use.
|
||||
*/
|
||||
void activate(const GLfloat *projectionMatrix);
|
||||
private:
|
||||
virtual void activate(const GLfloat *projectionMatrix) = 0;
|
||||
protected:
|
||||
/**
|
||||
* Vertex shader sources.
|
||||
*/
|
||||
|
@ -76,7 +82,59 @@ private:
|
|||
* Fragment shader sources.
|
||||
*/
|
||||
const Common::String _fragment;
|
||||
};
|
||||
|
||||
#if !USE_FORCED_GLES2
|
||||
class ShaderARB : public Shader {
|
||||
public:
|
||||
ShaderARB(const Common::String &vertex, const Common::String &fragment);
|
||||
virtual ~ShaderARB() { destroy(); }
|
||||
|
||||
virtual void destroy();
|
||||
|
||||
virtual bool recreate();
|
||||
|
||||
virtual void activate(const GLfloat *projectionMatrix);
|
||||
private:
|
||||
/**
|
||||
* Shader program handle.
|
||||
*/
|
||||
GLhandleARB _program;
|
||||
|
||||
/**
|
||||
* Location of the matrix uniform in the shader program.
|
||||
*/
|
||||
GLint _projectionLocation;
|
||||
|
||||
/**
|
||||
* Location of the texture sampler location in the shader program.
|
||||
*/
|
||||
GLint _textureLocation;
|
||||
|
||||
/**
|
||||
* Compile a vertex or fragment shader.
|
||||
*
|
||||
* @param source Sources to the shader.
|
||||
* @param shaderType Type of shader to compile (GL_FRAGMENT_SHADER_ARB or
|
||||
* GL_VERTEX_SHADER_ARB)
|
||||
* @return The shader object or 0 on failure.
|
||||
*/
|
||||
static GLhandleARB compileShader(const char *source, GLenum shaderType);
|
||||
};
|
||||
#endif // !USE_FORCED_GLES2
|
||||
|
||||
#if !USE_FORCED_GL
|
||||
class ShaderGLES2 : public Shader {
|
||||
public:
|
||||
ShaderGLES2(const Common::String &vertex, const Common::String &fragment);
|
||||
virtual ~ShaderGLES2() { destroy(); }
|
||||
|
||||
virtual void destroy();
|
||||
|
||||
virtual bool recreate();
|
||||
|
||||
virtual void activate(const GLfloat *projectionMatrix);
|
||||
private:
|
||||
/**
|
||||
* Shader program handle.
|
||||
*/
|
||||
|
@ -102,9 +160,10 @@ private:
|
|||
*/
|
||||
static GLuint compileShader(const char *source, GLenum shaderType);
|
||||
};
|
||||
#endif
|
||||
|
||||
} // End of namespace OpenGL
|
||||
|
||||
#endif // !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
#endif // !USE_FORCED_GLES
|
||||
|
||||
#endif
|
||||
|
|
|
@ -196,19 +196,28 @@ void Texture::draw(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
|
|||
};
|
||||
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
if (g_context.type != kContextGLES2) {
|
||||
#endif
|
||||
#if !USE_FORCED_GLES2
|
||||
GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
|
||||
GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
} else {
|
||||
if (g_context.type == kContextGLES2) {
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||
GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
|
||||
GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
} else {
|
||||
#endif
|
||||
#if !USE_FORCED_GLES2
|
||||
#if !USE_FORCED_GLES
|
||||
if (g_context.shadersSupported) {
|
||||
GL_CALL(glVertexAttribPointerARB(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
|
||||
GL_CALL(glVertexAttribPointerARB(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
|
||||
} else {
|
||||
#endif
|
||||
GL_CALL(glTexCoordPointer(2, GL_FLOAT, 0, texcoords));
|
||||
GL_CALL(glVertexPointer(2, GL_FLOAT, 0, vertices));
|
||||
#if !USE_FORCED_GLES
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue