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);
|
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, " ");
|
Common::StringTokenizer tokenizer(extString, " ");
|
||||||
while (!tokenizer.empty()) {
|
while (!tokenizer.empty()) {
|
||||||
Common::String token = tokenizer.nextToken();
|
Common::String token = tokenizer.nextToken();
|
||||||
|
|
||||||
if (token == "GL_ARB_texture_non_power_of_two") {
|
if (token == "GL_ARB_texture_non_power_of_two") {
|
||||||
g_context.NPOTSupported = true;
|
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
|
} // 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 GLdouble; /* double precision float */
|
||||||
typedef double GLclampd; /* double precision float in [0,1] */
|
typedef double GLclampd; /* double precision float in [0,1] */
|
||||||
typedef char GLchar;
|
typedef char GLchar;
|
||||||
|
typedef GLchar GLcharARB;
|
||||||
|
#if defined(__APPLE__) || defined(MACOSX)
|
||||||
|
typedef void *GLhandleARB;
|
||||||
|
#else
|
||||||
|
typedef uint GLhandleARB;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Constants
|
* Constants
|
||||||
|
@ -223,13 +229,20 @@ typedef char GLchar;
|
||||||
|
|
||||||
/* Shaders */
|
/* Shaders */
|
||||||
#define GL_FRAGMENT_SHADER 0x8B30
|
#define GL_FRAGMENT_SHADER 0x8B30
|
||||||
|
#define GL_FRAGMENT_SHADER_ARB 0x8B30
|
||||||
|
|
||||||
#define GL_VERTEX_SHADER 0x8B31
|
#define GL_VERTEX_SHADER 0x8B31
|
||||||
|
#define GL_VERTEX_SHADER_ARB 0x8B31
|
||||||
|
|
||||||
/* Programs */
|
/* Programs */
|
||||||
#define GL_COMPILE_STATUS 0x8B81
|
#define GL_COMPILE_STATUS 0x8B81
|
||||||
#define GL_LINK_STATUS 0x8B82
|
#define GL_LINK_STATUS 0x8B82
|
||||||
#define GL_INFO_LOG_LENGTH 0x8B84
|
#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 */
|
/* Textures */
|
||||||
#define GL_TEXTURE0 0x84C0
|
#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, glEnableVertexAttribArray, (GLuint index));
|
||||||
GL_FUNC_DEF(void, glActiveTexture, (GLenum texture));
|
GL_FUNC_DEF(void, glActiveTexture, (GLenum texture));
|
||||||
#endif
|
#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
|
#ifdef USE_OSD
|
||||||
, _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
|
, _osdAlpha(0), _osdFadeStartTime(0), _osd(nullptr)
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
, _shader(nullptr), _projectionMatrix()
|
, _shader(nullptr), _projectionMatrix()
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
@ -70,7 +70,7 @@ OpenGLGraphicsManager::~OpenGLGraphicsManager() {
|
||||||
#ifdef USE_OSD
|
#ifdef USE_OSD
|
||||||
delete _osd;
|
delete _osd;
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
delete _shader;
|
delete _shader;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -773,7 +773,8 @@ void OpenGLGraphicsManager::setActualScreenSize(uint width, uint height) {
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
#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
|
#endif
|
||||||
#if !USE_FORCED_GLES2
|
#if !USE_FORCED_GLES2
|
||||||
GL_CALL(glMatrixMode(GL_PROJECTION));
|
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
|
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
assert(sizeof(_projectionMatrix) == sizeof(orthoProjection));
|
assert(sizeof(_projectionMatrix) == sizeof(orthoProjection));
|
||||||
memcpy(_projectionMatrix, orthoProjection, sizeof(_projectionMatrix));
|
memcpy(_projectionMatrix, orthoProjection, sizeof(_projectionMatrix));
|
||||||
if (_shader) {
|
if (_shader) {
|
||||||
|
@ -894,17 +895,7 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
|
||||||
GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
GL_CALL(glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||||
|
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
#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
|
|
||||||
// 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 {
|
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||||
GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
|
GL_CALL(glEnableVertexAttribArray(kPositionAttribLocation));
|
||||||
|
@ -912,6 +903,25 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
|
||||||
|
|
||||||
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
||||||
#endif
|
#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
|
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -934,19 +944,33 @@ void OpenGLGraphicsManager::notifyContextCreate(const Graphics::PixelFormat &def
|
||||||
// Query information needed by textures.
|
// Query information needed by textures.
|
||||||
Texture::queryTextureInformation();
|
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) {
|
if (g_context.type == kContextGLES2) {
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GL
|
||||||
if (!_shader) {
|
_shader = new ShaderGLES2(g_defaultVertexShader, g_defaultFragmentShaderGLES2);
|
||||||
_shader = new Shader(g_defaultVertexShader, g_defaultFragmentShader);
|
#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?
|
// TODO: What do we do on failure?
|
||||||
_shader->recreate();
|
_shader->recreate();
|
||||||
_shader->activate(_projectionMatrix);
|
_shader->activate(_projectionMatrix);
|
||||||
#endif
|
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -999,7 +1023,7 @@ void OpenGLGraphicsManager::notifyContextDestroy() {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
if (_shader) {
|
if (_shader) {
|
||||||
_shader->destroy();
|
_shader->destroy();
|
||||||
}
|
}
|
||||||
|
@ -1080,16 +1104,24 @@ Texture *OpenGLGraphicsManager::createTexture(const Graphics::PixelFormat &forma
|
||||||
|
|
||||||
void OpenGLGraphicsManager::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
void OpenGLGraphicsManager::setColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||||
if (g_context.type != kContextGLES2) {
|
if (g_context.type == kContextGLES2) {
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GLES2
|
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||||
GL_CALL(glColor4f(r, g, b, a));
|
GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||||
} else {
|
} else {
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GLES2
|
||||||
GL_CALL(glVertexAttrib4f(kColorAttribLocation, r, g, b, a));
|
#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
|
#endif
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,7 +41,7 @@ namespace OpenGL {
|
||||||
#define USE_OSD 1
|
#define USE_OSD 1
|
||||||
|
|
||||||
class Texture;
|
class Texture;
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
class Shader;
|
class Shader;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -529,7 +529,7 @@ private:
|
||||||
*/
|
*/
|
||||||
uint _scissorOverride;
|
uint _scissorOverride;
|
||||||
|
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
//
|
//
|
||||||
// Shaders
|
// Shaders
|
||||||
//
|
//
|
||||||
|
|
|
@ -92,6 +92,11 @@ struct Context {
|
||||||
/** Whether GL_ARB_texture_non_power_of_two is available or not. */
|
/** Whether GL_ARB_texture_non_power_of_two is available or not. */
|
||||||
bool NPOTSupported;
|
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_FUNC_DEF(ret, name, param) ret (GL_CALL_CONV *name)param
|
||||||
#define GL_EXT_FUNC_DEF GL_FUNC_DEF
|
#define GL_EXT_FUNC_DEF GL_FUNC_DEF
|
||||||
#include "backends/graphics/opengl/opengl-func.h"
|
#include "backends/graphics/opengl/opengl-func.h"
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
|
|
||||||
#include "backends/graphics/opengl/shader.h"
|
#include "backends/graphics/opengl/shader.h"
|
||||||
|
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
|
|
||||||
#include "common/textconsole.h"
|
#include "common/textconsole.h"
|
||||||
|
|
||||||
|
@ -44,7 +44,20 @@ const char *const g_defaultVertexShader =
|
||||||
"\tgl_Position = projection * position;\n"
|
"\tgl_Position = projection * position;\n"
|
||||||
"}\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 vec2 texCoord;\n"
|
||||||
"varying lowp vec4 blendColor;\n"
|
"varying lowp vec4 blendColor;\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -53,17 +66,146 @@ const char *const g_defaultFragmentShader =
|
||||||
"void main(void) {\n"
|
"void main(void) {\n"
|
||||||
"\tgl_FragColor = blendColor * texture2D(texture, texCoord);\n"
|
"\tgl_FragColor = blendColor * texture2D(texture, texCoord);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
Shader::Shader(const Common::String &vertex, const Common::String &fragment)
|
#if !USE_FORCED_GLES2
|
||||||
: _vertex(vertex), _fragment(fragment), _program(0), _projectionLocation(-1), _textureLocation(-1) {
|
|
||||||
|
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));
|
GL_CALL(glDeleteProgram(_program));
|
||||||
_program = 0;
|
_program = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Shader::recreate() {
|
bool ShaderGLES2::recreate() {
|
||||||
// Make sure any old programs are destroyed properly.
|
// Make sure any old programs are destroyed properly.
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
|
@ -132,7 +274,7 @@ bool Shader::recreate() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::activate(const GLfloat *projectionMatrix) {
|
void ShaderGLES2::activate(const GLfloat *projectionMatrix) {
|
||||||
// Activate program.
|
// Activate program.
|
||||||
GL_CALL(glUseProgram(_program));
|
GL_CALL(glUseProgram(_program));
|
||||||
|
|
||||||
|
@ -143,7 +285,7 @@ void Shader::activate(const GLfloat *projectionMatrix) {
|
||||||
GL_CALL(glUniform1i(_textureLocation, 0));
|
GL_CALL(glUniform1i(_textureLocation, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint Shader::compileShader(const char *source, GLenum shaderType) {
|
GLuint ShaderGLES2::compileShader(const char *source, GLenum shaderType) {
|
||||||
GLuint handle;
|
GLuint handle;
|
||||||
GL_ASSIGN(handle, glCreateShader(shaderType));
|
GL_ASSIGN(handle, glCreateShader(shaderType));
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
|
@ -171,6 +313,8 @@ GLuint Shader::compileShader(const char *source, GLenum shaderType) {
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // !!USE_FORCED_GL
|
||||||
|
|
||||||
} // End of namespace OpenGL
|
} // 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"
|
#include "backends/graphics/opengl/opengl-sys.h"
|
||||||
|
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GLES
|
||||||
|
|
||||||
#include "common/str.h"
|
#include "common/str.h"
|
||||||
|
|
||||||
|
@ -38,12 +38,18 @@ enum {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char *const g_defaultVertexShader;
|
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 {
|
class Shader {
|
||||||
public:
|
public:
|
||||||
Shader(const Common::String &vertex, const Common::String &fragment);
|
Shader(const Common::String &vertex, const Common::String &fragment)
|
||||||
~Shader() { destroy(); }
|
: _vertex(vertex), _fragment(fragment) {}
|
||||||
|
virtual ~Shader() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy the shader program.
|
* Destroy the shader program.
|
||||||
|
@ -51,22 +57,22 @@ public:
|
||||||
* This keeps the vertex and fragment shader sources around and thus
|
* This keeps the vertex and fragment shader sources around and thus
|
||||||
* allows for recreating the shader on context recreation.
|
* allows for recreating the shader on context recreation.
|
||||||
*/
|
*/
|
||||||
void destroy();
|
virtual void destroy() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recreate shader program.
|
* Recreate shader program.
|
||||||
*
|
*
|
||||||
* @return true on success, false on failure.
|
* @return true on success, false on failure.
|
||||||
*/
|
*/
|
||||||
bool recreate();
|
virtual bool recreate() = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make shader active.
|
* Make shader active.
|
||||||
*
|
*
|
||||||
* @param projectionMatrix Projection matrix to use.
|
* @param projectionMatrix Projection matrix to use.
|
||||||
*/
|
*/
|
||||||
void activate(const GLfloat *projectionMatrix);
|
virtual void activate(const GLfloat *projectionMatrix) = 0;
|
||||||
private:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Vertex shader sources.
|
* Vertex shader sources.
|
||||||
*/
|
*/
|
||||||
|
@ -76,7 +82,59 @@ private:
|
||||||
* Fragment shader sources.
|
* Fragment shader sources.
|
||||||
*/
|
*/
|
||||||
const Common::String _fragment;
|
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.
|
* Shader program handle.
|
||||||
*/
|
*/
|
||||||
|
@ -102,9 +160,10 @@ private:
|
||||||
*/
|
*/
|
||||||
static GLuint compileShader(const char *source, GLenum shaderType);
|
static GLuint compileShader(const char *source, GLenum shaderType);
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
} // End of namespace OpenGL
|
} // End of namespace OpenGL
|
||||||
|
|
||||||
#endif // !USE_FORCED_GL && !USE_FORCED_GLES
|
#endif // !USE_FORCED_GLES
|
||||||
|
|
||||||
#endif
|
#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 !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(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 {
|
|
||||||
#endif
|
#endif
|
||||||
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
#if !USE_FORCED_GL && !USE_FORCED_GLES
|
||||||
GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
|
GL_CALL(glVertexAttribPointer(kTexCoordAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords));
|
||||||
GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
|
GL_CALL(glVertexAttribPointer(kPositionAttribLocation, 2, GL_FLOAT, GL_FALSE, 0, vertices));
|
||||||
#endif
|
#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
|
#if !USE_FORCED_GL && !USE_FORCED_GLES && !USE_FORCED_GLES2
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue