mirror of https://github.com/mgba-emu/mgba.git
OpenGL: Revamp shader backend
This commit is contained in:
parent
8c6a57f7d9
commit
4a502c2c03
|
@ -21,7 +21,7 @@ static const char* const _nullVertexShader =
|
|||
"varying vec2 texCoord;\n"
|
||||
|
||||
"void main() {\n"
|
||||
" gl_Position = position * vec4(1.0, 1.0, 1.0, 1.0);\n"
|
||||
" gl_Position = position;\n"
|
||||
" texCoord = (position.st + vec2(1.0, 1.0)) * vec2(0.5, 0.5);\n"
|
||||
"}";
|
||||
|
||||
|
@ -36,7 +36,17 @@ static const char* const _fragmentShader =
|
|||
" vec4 color = texture2D(tex, texCoord);\n"
|
||||
" color.a = 1.;\n"
|
||||
" color.rgb = scale * pow(color.rgb, vec3(gamma, gamma, gamma)) + bias;\n"
|
||||
" gl_FragColor = color;"
|
||||
" gl_FragColor = color;\n"
|
||||
"}";
|
||||
|
||||
static const char* const _nullFragmentShader =
|
||||
"varying vec2 texCoord;\n"
|
||||
"uniform sampler2D tex;\n"
|
||||
|
||||
"void main() {\n"
|
||||
" vec4 color = texture2D(tex, texCoord);\n"
|
||||
" color.a = 1.;\n"
|
||||
" gl_FragColor = color;\n"
|
||||
"}";
|
||||
|
||||
static const GLfloat _vertices[] = {
|
||||
|
@ -46,6 +56,7 @@ static const GLfloat _vertices[] = {
|
|||
1.f, -1.f,
|
||||
};
|
||||
|
||||
|
||||
static void GBAGLES2ContextInit(struct VideoBackend* v, WHandle handle) {
|
||||
UNUSED(handle);
|
||||
struct GBAGLES2Context* context = (struct GBAGLES2Context*) v;
|
||||
|
@ -64,44 +75,34 @@ static void GBAGLES2ContextInit(struct VideoBackend* v, WHandle handle) {
|
|||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, VIDEO_HORIZONTAL_PIXELS, VIDEO_VERTICAL_PIXELS, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
#endif
|
||||
|
||||
context->program = glCreateProgram();
|
||||
context->fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
context->vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
context->nullVertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
|
||||
glShaderSource(context->fragmentShader, 1, (const GLchar**) &_fragmentShader, 0);
|
||||
glShaderSource(context->vertexShader, 1, (const GLchar**) &_vertexShader, 0);
|
||||
glShaderSource(context->nullVertexShader, 1, (const GLchar**) &_nullVertexShader, 0);
|
||||
glAttachShader(context->program, context->vertexShader);
|
||||
glAttachShader(context->program, context->fragmentShader);
|
||||
char log[1024];
|
||||
glCompileShader(context->fragmentShader);
|
||||
glCompileShader(context->vertexShader);
|
||||
glCompileShader(context->nullVertexShader);
|
||||
glGetShaderInfoLog(context->fragmentShader, 1024, 0, log);
|
||||
printf("%s\n", log);
|
||||
glGetShaderInfoLog(context->vertexShader, 1024, 0, log);
|
||||
printf("%s\n", log);
|
||||
glGetShaderInfoLog(context->nullVertexShader, 1024, 0, log);
|
||||
printf("%s\n", log);
|
||||
glLinkProgram(context->program);
|
||||
glGetProgramInfoLog(context->program, 1024, 0, log);
|
||||
printf("%s\n", log);
|
||||
context->texLocation = glGetUniformLocation(context->program, "tex");
|
||||
context->gammaLocation = glGetUniformLocation(context->program, "gamma");
|
||||
context->biasLocation = glGetUniformLocation(context->program, "bias");
|
||||
context->scaleLocation = glGetUniformLocation(context->program, "scale");
|
||||
context->positionLocation = glGetAttribLocation(context->program, "position");
|
||||
glClearColor(0.f, 0.f, 0.f, 1.f);
|
||||
|
||||
struct GBAGLES2Uniform* uniforms = malloc(sizeof(struct GBAGLES2Uniform) * 3);
|
||||
uniforms[0].name = "gamma";
|
||||
uniforms[0].type = GL_FLOAT;
|
||||
uniforms[0].value.f = 1.0f;
|
||||
uniforms[1].name = "scale";
|
||||
uniforms[1].type = GL_FLOAT_VEC3;
|
||||
uniforms[1].value.fvec3[0] = 1.0f;
|
||||
uniforms[1].value.fvec3[1] = 1.0f;
|
||||
uniforms[1].value.fvec3[2] = 1.0f;
|
||||
uniforms[2].name = "bias";
|
||||
uniforms[2].type = GL_FLOAT_VEC3;
|
||||
uniforms[2].value.fvec3[0] = 0.0f;
|
||||
uniforms[2].value.fvec3[1] = 0.0f;
|
||||
uniforms[2].value.fvec3[2] = 0.0f;
|
||||
GBAGLES2ShaderInit(&context->initialShader, _vertexShader, _fragmentShader, -1, -1, uniforms, 3);
|
||||
GBAGLES2ShaderInit(&context->finalShader, 0, 0, 0, 0, 0, 0);
|
||||
glDeleteFramebuffers(1, &context->finalShader.fbo);
|
||||
context->finalShader.fbo = 0;
|
||||
}
|
||||
|
||||
static void GBAGLES2ContextDeinit(struct VideoBackend* v) {
|
||||
struct GBAGLES2Context* context = (struct GBAGLES2Context*) v;
|
||||
glDeleteTextures(1, &context->tex);
|
||||
glDeleteShader(context->fragmentShader);
|
||||
glDeleteShader(context->vertexShader);
|
||||
glDeleteShader(context->nullVertexShader);
|
||||
glDeleteProgram(context->program);
|
||||
GBAGLES2ShaderDeinit(&context->initialShader);
|
||||
GBAGLES2ShaderDeinit(&context->finalShader);
|
||||
free(context->initialShader.uniforms);
|
||||
}
|
||||
|
||||
static void GBAGLES2ContextResized(struct VideoBackend* v, int w, int h) {
|
||||
|
@ -126,46 +127,118 @@ static void GBAGLES2ContextClear(struct VideoBackend* v) {
|
|||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
void _drawShader(struct GBAGLES2Shader* shader) {
|
||||
GLint viewport[4];
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, shader->fbo);
|
||||
if (shader->blend) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
} else {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
glViewport(0, 0, shader->width ? shader->width : viewport[2], shader->height ? shader->height : viewport[3]);
|
||||
if (!shader->width || !shader->height) {
|
||||
GLint oldTex;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldTex);
|
||||
glBindTexture(GL_TEXTURE_2D, shader->tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, shader->width ? shader->width : viewport[2], shader->height ? shader->height : viewport[3], 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, oldTex);
|
||||
}
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, shader->filter ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, shader->filter ? GL_LINEAR : GL_NEAREST);
|
||||
glUseProgram(shader->program);
|
||||
glUniform1i(shader->texLocation, 0);
|
||||
glVertexAttribPointer(shader->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, _vertices);
|
||||
glEnableVertexAttribArray(shader->positionLocation);
|
||||
size_t u;
|
||||
for (u = 0; u < shader->nUniforms; ++u) {
|
||||
struct GBAGLES2Uniform* uniform = &shader->uniforms[u];
|
||||
switch (uniform->type) {
|
||||
case GL_FLOAT:
|
||||
glUniform1f(uniform->location, uniform->value.f);
|
||||
break;
|
||||
case GL_INT:
|
||||
glUniform1f(uniform->location, uniform->value.i);
|
||||
break;
|
||||
case GL_UNSIGNED_INT:
|
||||
glUniform1f(uniform->location, uniform->value.ui);
|
||||
break;
|
||||
case GL_FLOAT_VEC2:
|
||||
glUniform2fv(uniform->location, 1, uniform->value.fvec2);
|
||||
break;
|
||||
case GL_FLOAT_VEC3:
|
||||
glUniform3fv(uniform->location, 1, uniform->value.fvec3);
|
||||
break;
|
||||
case GL_FLOAT_VEC4:
|
||||
glUniform4fv(uniform->location, 1, uniform->value.fvec4);
|
||||
break;
|
||||
case GL_INT_VEC2:
|
||||
glUniform2iv(uniform->location, 1, uniform->value.ivec2);
|
||||
break;
|
||||
case GL_INT_VEC3:
|
||||
glUniform3iv(uniform->location, 1, uniform->value.ivec3);
|
||||
break;
|
||||
case GL_INT_VEC4:
|
||||
glUniform4iv(uniform->location, 1, uniform->value.ivec4);
|
||||
break;
|
||||
case GL_UNSIGNED_INT_VEC2:
|
||||
glUniform2uiv(uniform->location, 1, uniform->value.uivec2);
|
||||
break;
|
||||
case GL_UNSIGNED_INT_VEC3:
|
||||
glUniform3uiv(uniform->location, 1, uniform->value.uivec3);
|
||||
break;
|
||||
case GL_UNSIGNED_INT_VEC4:
|
||||
glUniform4uiv(uniform->location, 1, uniform->value.uivec4);
|
||||
break;
|
||||
case GL_FLOAT_MAT2:
|
||||
glUniformMatrix2fv(uniform->location, 1, GL_FALSE, uniform->value.fmat2x2);
|
||||
break;
|
||||
case GL_FLOAT_MAT2x3:
|
||||
glUniformMatrix2x3fv(uniform->location, 1, GL_FALSE, uniform->value.fmat2x3);
|
||||
break;
|
||||
case GL_FLOAT_MAT2x4:
|
||||
glUniformMatrix2x4fv(uniform->location, 1, GL_FALSE, uniform->value.fmat2x4);
|
||||
break;
|
||||
case GL_FLOAT_MAT3x2:
|
||||
glUniformMatrix3x2fv(uniform->location, 1, GL_FALSE, uniform->value.fmat3x2);
|
||||
break;
|
||||
case GL_FLOAT_MAT3:
|
||||
glUniformMatrix3fv(uniform->location, 1, GL_FALSE, uniform->value.fmat3x3);
|
||||
break;
|
||||
case GL_FLOAT_MAT3x4:
|
||||
glUniformMatrix3x4fv(uniform->location, 1, GL_FALSE, uniform->value.fmat3x4);
|
||||
break;
|
||||
case GL_FLOAT_MAT4x2:
|
||||
glUniformMatrix2fv(uniform->location, 1, GL_FALSE, uniform->value.fmat4x2);
|
||||
break;
|
||||
case GL_FLOAT_MAT4x3:
|
||||
glUniformMatrix2x3fv(uniform->location, 1, GL_FALSE, uniform->value.fmat4x3);
|
||||
break;
|
||||
case GL_FLOAT_MAT4:
|
||||
glUniformMatrix2x4fv(uniform->location, 1, GL_FALSE, uniform->value.fmat4x4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, shader->tex);
|
||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
}
|
||||
|
||||
void GBAGLES2ContextDrawFrame(struct VideoBackend* v) {
|
||||
struct GBAGLES2Context* context = (struct GBAGLES2Context*) v;
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, context->tex);
|
||||
|
||||
if (context->shader) {
|
||||
GLint viewport[4];
|
||||
if (context->shader->blend) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
} else {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
glGetIntegerv(GL_VIEWPORT, viewport);
|
||||
glViewport(0, 0, context->shader->width, context->shader->height);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, context->shader->filter ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, context->shader->filter ? GL_LINEAR : GL_NEAREST);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, context->shader->fbo);
|
||||
glUseProgram(context->shader->program);
|
||||
glUniform1i(context->shader->texLocation, 0);
|
||||
glVertexAttribPointer(context->shader->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, _vertices);
|
||||
glEnableVertexAttribArray(context->shader->positionLocation);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, context->shader->tex);
|
||||
glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);
|
||||
context->finalShader.filter = v->filter;
|
||||
_drawShader(&context->initialShader);
|
||||
size_t n;
|
||||
for (n = 0; n < context->nShaders; ++n) {
|
||||
_drawShader(&context->shaders[n]);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, v->filter ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, v->filter ? GL_LINEAR : GL_NEAREST);
|
||||
glUseProgram(context->program);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glUniform1i(context->texLocation, 0);
|
||||
glUniform1f(context->gammaLocation, context->gamma);
|
||||
glUniform3f(context->biasLocation, context->bias[0], context->bias[1], context->bias[2]);
|
||||
glUniform3f(context->scaleLocation, context->scale[0], context->scale[1], context->scale[2]);
|
||||
glVertexAttribPointer(context->positionLocation, 2, GL_FLOAT, GL_FALSE, 0, _vertices);
|
||||
glEnableVertexAttribArray(context->positionLocation);
|
||||
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
glDisable(GL_BLEND);
|
||||
_drawShader(&context->finalShader);
|
||||
glUseProgram(0);
|
||||
}
|
||||
|
||||
|
@ -195,21 +268,17 @@ void GBAGLES2ContextCreate(struct GBAGLES2Context* context) {
|
|||
context->d.drawFrame = GBAGLES2ContextDrawFrame;
|
||||
context->d.setMessage = 0;
|
||||
context->d.clearMessage = 0;
|
||||
context->shader = 0;
|
||||
context->gamma = 1.0f;
|
||||
context->bias[0] = 0.0f;
|
||||
context->bias[1] = 0.0f;
|
||||
context->bias[2] = 0.0f;
|
||||
context->scale[0] = 1.0f;
|
||||
context->scale[1] = 1.0f;
|
||||
context->scale[2] = 1.0f;
|
||||
context->shaders = 0;
|
||||
context->nShaders = 0;
|
||||
}
|
||||
|
||||
void GBAGLES2ShaderInit(struct GBAGLES2Shader* shader, const char* src, int width, int height) {
|
||||
shader->width = width > 0 ? width : VIDEO_HORIZONTAL_PIXELS;
|
||||
shader->height = height > 0 ? height : VIDEO_VERTICAL_PIXELS;
|
||||
void GBAGLES2ShaderInit(struct GBAGLES2Shader* shader, const char* vs, const char* fs, int width, int height, struct GBAGLES2Uniform* uniforms, size_t nUniforms) {
|
||||
shader->width = width >= 0 ? width : VIDEO_HORIZONTAL_PIXELS;
|
||||
shader->height = height >= 0 ? height : VIDEO_VERTICAL_PIXELS;
|
||||
shader->filter = false;
|
||||
shader->blend = false;
|
||||
shader->uniforms = uniforms;
|
||||
shader->nUniforms = nUniforms;
|
||||
glGenFramebuffers(1, &shader->fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, shader->fbo);
|
||||
|
||||
|
@ -219,16 +288,43 @@ void GBAGLES2ShaderInit(struct GBAGLES2Shader* shader, const char* src, int widt
|
|||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, shader->width, shader->height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||
if (shader->width && shader->height) {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, shader->width, shader->height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
|
||||
}
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, shader->tex, 0);
|
||||
shader->program = glCreateProgram();
|
||||
shader->vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
shader->fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(shader->fragmentShader, 1, (const GLchar**) &src, 0);
|
||||
if (vs) {
|
||||
glShaderSource(shader->vertexShader, 1, (const GLchar**) &vs, 0);
|
||||
} else {
|
||||
glShaderSource(shader->vertexShader, 1, (const GLchar**) &_nullVertexShader, 0);
|
||||
}
|
||||
if (fs) {
|
||||
glShaderSource(shader->fragmentShader, 1, (const GLchar**) &fs, 0);
|
||||
} else {
|
||||
glShaderSource(shader->fragmentShader, 1, (const GLchar**) &_nullFragmentShader, 0);
|
||||
}
|
||||
glAttachShader(shader->program, shader->vertexShader);
|
||||
glAttachShader(shader->program, shader->fragmentShader);
|
||||
glCompileShader(shader->fragmentShader);
|
||||
char log[1024];
|
||||
glCompileShader(shader->fragmentShader);
|
||||
glGetShaderInfoLog(shader->fragmentShader, 1024, 0, log);
|
||||
printf("%s\n", log);
|
||||
glCompileShader(shader->vertexShader);
|
||||
glGetShaderInfoLog(shader->vertexShader, 1024, 0, log);
|
||||
printf("%s\n", log);
|
||||
glLinkProgram(shader->program);
|
||||
glGetProgramInfoLog(shader->program, 1024, 0, log);
|
||||
printf("%s\n", log);
|
||||
|
||||
shader->texLocation = glGetUniformLocation(shader->program, "tex");
|
||||
shader->positionLocation = glGetAttribLocation(shader->program, "position");
|
||||
size_t i;
|
||||
for (i = 0; i < shader->nUniforms; ++i) {
|
||||
shader->uniforms[i].location = glGetUniformLocation(shader->program, shader->uniforms[i].name);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
|
@ -236,30 +332,23 @@ void GBAGLES2ShaderDeinit(struct GBAGLES2Shader* shader) {
|
|||
glDeleteTextures(1, &shader->tex);
|
||||
glDeleteShader(shader->fragmentShader);
|
||||
glDeleteProgram(shader->program);
|
||||
glDeleteFramebuffers(1, &shader->fbo);
|
||||
}
|
||||
|
||||
void GBAGLES2ShaderAttach(struct GBAGLES2Context* context, struct GBAGLES2Shader* shader) {
|
||||
if (context->shader) {
|
||||
if (context->shader == shader) {
|
||||
void GBAGLES2ShaderAttach(struct GBAGLES2Context* context, struct GBAGLES2Shader* shaders, size_t nShaders) {
|
||||
if (context->shaders) {
|
||||
if (context->shaders == shaders && context->nShaders == nShaders) {
|
||||
return;
|
||||
}
|
||||
GBAGLES2ShaderDetach(context);
|
||||
}
|
||||
context->shader = shader;
|
||||
glAttachShader(shader->program, context->nullVertexShader);
|
||||
|
||||
char log[1024];
|
||||
glLinkProgram(shader->program);
|
||||
glGetProgramInfoLog(shader->program, 1024, 0, log);
|
||||
printf("%s\n", log);
|
||||
shader->texLocation = glGetUniformLocation(shader->program, "tex");
|
||||
shader->positionLocation = glGetAttribLocation(shader->program, "position");
|
||||
context->shaders = shaders;
|
||||
context->nShaders = nShaders;
|
||||
}
|
||||
|
||||
void GBAGLES2ShaderDetach(struct GBAGLES2Context* context) {
|
||||
if (!context->shader) {
|
||||
if (!context->shaders) {
|
||||
return;
|
||||
}
|
||||
glDetachShader(context->shader->program, context->nullVertexShader);
|
||||
context->shader = 0;
|
||||
context->shaders = 0;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
#ifdef BUILD_GL
|
||||
#ifdef __APPLE__
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/gl3.h>
|
||||
#else
|
||||
#include <GL/gl.h>
|
||||
#endif
|
||||
|
@ -18,6 +18,37 @@
|
|||
|
||||
#include "platform/video-backend.h"
|
||||
|
||||
union GBAGLES2UniformValue {
|
||||
GLfloat f;
|
||||
GLint i;
|
||||
GLuint ui;
|
||||
GLfloat fvec2[2];
|
||||
GLfloat fvec3[3];
|
||||
GLfloat fvec4[4];
|
||||
GLint ivec2[2];
|
||||
GLint ivec3[3];
|
||||
GLint ivec4[4];
|
||||
GLuint uivec2[2];
|
||||
GLuint uivec3[3];
|
||||
GLuint uivec4[4];
|
||||
GLfloat fmat2x2[4];
|
||||
GLfloat fmat2x3[6];
|
||||
GLfloat fmat2x4[8];
|
||||
GLfloat fmat3x2[6];
|
||||
GLfloat fmat3x3[9];
|
||||
GLfloat fmat3x4[12];
|
||||
GLfloat fmat4x2[8];
|
||||
GLfloat fmat4x3[12];
|
||||
GLfloat fmat4x4[16];
|
||||
};
|
||||
|
||||
struct GBAGLES2Uniform {
|
||||
const char* name;
|
||||
GLenum type;
|
||||
union GBAGLES2UniformValue value;
|
||||
GLuint location;
|
||||
};
|
||||
|
||||
struct GBAGLES2Shader {
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
|
@ -26,38 +57,34 @@ struct GBAGLES2Shader {
|
|||
GLuint tex;
|
||||
GLuint fbo;
|
||||
GLuint fragmentShader;
|
||||
GLuint vertexShader;
|
||||
GLuint program;
|
||||
GLuint texLocation;
|
||||
GLuint positionLocation;
|
||||
|
||||
struct GBAGLES2Uniform* uniforms;
|
||||
size_t nUniforms;
|
||||
};
|
||||
|
||||
struct GBAGLES2Context {
|
||||
struct VideoBackend d;
|
||||
|
||||
GLuint tex;
|
||||
GLuint fragmentShader;
|
||||
GLuint vertexShader;
|
||||
GLuint nullVertexShader;
|
||||
GLuint program;
|
||||
GLuint bufferObject;
|
||||
GLuint texLocation;
|
||||
GLuint positionLocation;
|
||||
GLuint gammaLocation;
|
||||
GLuint biasLocation;
|
||||
GLuint scaleLocation;
|
||||
|
||||
GLfloat gamma;
|
||||
GLfloat bias[3];
|
||||
GLfloat scale[3];
|
||||
struct GBAGLES2Shader initialShader;
|
||||
struct GBAGLES2Shader finalShader;
|
||||
|
||||
struct GBAGLES2Shader* shader;
|
||||
struct GBAGLES2Shader* shaders;
|
||||
size_t nShaders;
|
||||
};
|
||||
|
||||
void GBAGLES2ContextCreate(struct GBAGLES2Context*);
|
||||
|
||||
void GBAGLES2ShaderInit(struct GBAGLES2Shader*, const char*, int width, int height);
|
||||
void GBAGLES2ShaderInit(struct GBAGLES2Shader*, const char* vs, const char* fs, int width, int height, struct GBAGLES2Uniform* uniforms, size_t nUniforms);
|
||||
void GBAGLES2ShaderDeinit(struct GBAGLES2Shader*);
|
||||
void GBAGLES2ShaderAttach(struct GBAGLES2Context*, struct GBAGLES2Shader*);
|
||||
void GBAGLES2ShaderAttach(struct GBAGLES2Context*, struct GBAGLES2Shader*, size_t nShaders);
|
||||
void GBAGLES2ShaderDetach(struct GBAGLES2Context*);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue