mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 17:38:34 +02:00
Adding shader versioning and defines from GLBackendShader allowing for runtime defines injection to shaders and more
This commit is contained in:
parent
c6deff16d6
commit
cadb53b703
7 changed files with 334 additions and 272 deletions
|
@ -18,7 +18,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
const QString SHADER_COMMON = R"SHADER(#version 410 core
|
const QString SHADER_COMMON = R"SHADER(
|
||||||
layout(location = 0) out vec4 _fragColor0;
|
layout(location = 0) out vec4 _fragColor0;
|
||||||
layout(location = 1) out vec4 _fragColor1;
|
layout(location = 1) out vec4 _fragColor1;
|
||||||
layout(location = 2) out vec4 _fragColor2;
|
layout(location = 2) out vec4 _fragColor2;
|
||||||
|
|
|
@ -13,11 +13,11 @@
|
||||||
|
|
||||||
<@if GLPROFILE == PC_GL @>
|
<@if GLPROFILE == PC_GL @>
|
||||||
<@def GPU_FEATURE_PROFILE GPU_CORE@>
|
<@def GPU_FEATURE_PROFILE GPU_CORE@>
|
||||||
<@def VERSION_HEADER #version 410 core@>
|
<@def VERSION_HEADER //PC 410 core@>
|
||||||
<@elif GLPROFILE == MAC_GL @>
|
<@elif GLPROFILE == MAC_GL @>
|
||||||
<@def GPU_FEATURE_PROFILE GPU_CORE@>
|
<@def GPU_FEATURE_PROFILE GPU_CORE@>
|
||||||
<@def VERSION_HEADER #version 410 core@>
|
<@def VERSION_HEADER //MAC 410 core@>
|
||||||
<@else@>
|
<@else@>
|
||||||
<@def GPU_FEATURE_PROFILE GPU_CORE@>
|
<@def GPU_FEATURE_PROFILE GPU_CORE@>
|
||||||
<@def VERSION_HEADER #version 410 core@>
|
<@def VERSION_HEADER //410 core@>
|
||||||
<@endif@>
|
<@endif@>
|
||||||
|
|
|
@ -461,8 +461,7 @@ void GLBackend::resetStages() {
|
||||||
|
|
||||||
#define ADD_COMMAND_GL(call) _commands.push_back(COMMAND_##call); _commandOffsets.push_back(_params.size());
|
#define ADD_COMMAND_GL(call) _commands.push_back(COMMAND_##call); _commandOffsets.push_back(_params.size());
|
||||||
|
|
||||||
//#define DO_IT_NOW(call, offset) runLastCommand();
|
#define GET_UNIFORM_LOCATION(shaderUniformLoc) shaderUniformLoc
|
||||||
#define DO_IT_NOW(call, offset)
|
|
||||||
|
|
||||||
void Batch::_glActiveBindTexture(GLenum unit, GLenum target, GLuint texture) {
|
void Batch::_glActiveBindTexture(GLenum unit, GLenum target, GLuint texture) {
|
||||||
// clean the cache on the texture unit we are going to use so the next call to setResourceTexture() at the same slot works fine
|
// clean the cache on the texture unit we are going to use so the next call to setResourceTexture() at the same slot works fine
|
||||||
|
@ -472,14 +471,11 @@ void Batch::_glActiveBindTexture(GLenum unit, GLenum target, GLuint texture) {
|
||||||
_params.push_back(texture);
|
_params.push_back(texture);
|
||||||
_params.push_back(target);
|
_params.push_back(target);
|
||||||
_params.push_back(unit);
|
_params.push_back(unit);
|
||||||
|
|
||||||
|
|
||||||
DO_IT_NOW(_glActiveBindTexture, 3);
|
|
||||||
}
|
}
|
||||||
void GLBackend::do_glActiveBindTexture(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glActiveBindTexture(Batch& batch, size_t paramOffset) {
|
||||||
glActiveTexture(batch._params[paramOffset + 2]._uint);
|
glActiveTexture(batch._params[paramOffset + 2]._uint);
|
||||||
glBindTexture(
|
glBindTexture(
|
||||||
batch._params[paramOffset + 1]._uint,
|
GET_UNIFORM_LOCATION(batch._params[paramOffset + 1]._uint),
|
||||||
batch._params[paramOffset + 0]._uint);
|
batch._params[paramOffset + 0]._uint);
|
||||||
|
|
||||||
(void) CHECK_GL_ERROR();
|
(void) CHECK_GL_ERROR();
|
||||||
|
@ -492,8 +488,6 @@ void Batch::_glUniform1i(GLint location, GLint v0) {
|
||||||
ADD_COMMAND_GL(glUniform1i);
|
ADD_COMMAND_GL(glUniform1i);
|
||||||
_params.push_back(v0);
|
_params.push_back(v0);
|
||||||
_params.push_back(location);
|
_params.push_back(location);
|
||||||
|
|
||||||
DO_IT_NOW(_glUniform1i, 1);
|
|
||||||
}
|
}
|
||||||
void GLBackend::do_glUniform1i(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glUniform1i(Batch& batch, size_t paramOffset) {
|
||||||
if (_pipeline._program == 0) {
|
if (_pipeline._program == 0) {
|
||||||
|
@ -503,7 +497,7 @@ void GLBackend::do_glUniform1i(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
glUniform1f(
|
glUniform1f(
|
||||||
batch._params[paramOffset + 1]._int,
|
GET_UNIFORM_LOCATION(batch._params[paramOffset + 1]._int),
|
||||||
batch._params[paramOffset + 0]._int);
|
batch._params[paramOffset + 0]._int);
|
||||||
(void) CHECK_GL_ERROR();
|
(void) CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
@ -515,8 +509,6 @@ void Batch::_glUniform1f(GLint location, GLfloat v0) {
|
||||||
ADD_COMMAND_GL(glUniform1f);
|
ADD_COMMAND_GL(glUniform1f);
|
||||||
_params.push_back(v0);
|
_params.push_back(v0);
|
||||||
_params.push_back(location);
|
_params.push_back(location);
|
||||||
|
|
||||||
DO_IT_NOW(_glUniform1f, 1);
|
|
||||||
}
|
}
|
||||||
void GLBackend::do_glUniform1f(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glUniform1f(Batch& batch, size_t paramOffset) {
|
||||||
if (_pipeline._program == 0) {
|
if (_pipeline._program == 0) {
|
||||||
|
@ -527,7 +519,7 @@ void GLBackend::do_glUniform1f(Batch& batch, size_t paramOffset) {
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
|
|
||||||
glUniform1f(
|
glUniform1f(
|
||||||
batch._params[paramOffset + 1]._int,
|
GET_UNIFORM_LOCATION(batch._params[paramOffset + 1]._int),
|
||||||
batch._params[paramOffset + 0]._float);
|
batch._params[paramOffset + 0]._float);
|
||||||
(void) CHECK_GL_ERROR();
|
(void) CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
@ -538,8 +530,6 @@ void Batch::_glUniform2f(GLint location, GLfloat v0, GLfloat v1) {
|
||||||
_params.push_back(v1);
|
_params.push_back(v1);
|
||||||
_params.push_back(v0);
|
_params.push_back(v0);
|
||||||
_params.push_back(location);
|
_params.push_back(location);
|
||||||
|
|
||||||
DO_IT_NOW(_glUniform2f, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_glUniform2f(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glUniform2f(Batch& batch, size_t paramOffset) {
|
||||||
|
@ -550,7 +540,7 @@ void GLBackend::do_glUniform2f(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
glUniform2f(
|
glUniform2f(
|
||||||
batch._params[paramOffset + 2]._int,
|
GET_UNIFORM_LOCATION(batch._params[paramOffset + 2]._int),
|
||||||
batch._params[paramOffset + 1]._float,
|
batch._params[paramOffset + 1]._float,
|
||||||
batch._params[paramOffset + 0]._float);
|
batch._params[paramOffset + 0]._float);
|
||||||
(void) CHECK_GL_ERROR();
|
(void) CHECK_GL_ERROR();
|
||||||
|
@ -563,8 +553,6 @@ void Batch::_glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) {
|
||||||
_params.push_back(v1);
|
_params.push_back(v1);
|
||||||
_params.push_back(v0);
|
_params.push_back(v0);
|
||||||
_params.push_back(location);
|
_params.push_back(location);
|
||||||
|
|
||||||
DO_IT_NOW(_glUniform3f, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_glUniform3f(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glUniform3f(Batch& batch, size_t paramOffset) {
|
||||||
|
@ -575,7 +563,7 @@ void GLBackend::do_glUniform3f(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
glUniform3f(
|
glUniform3f(
|
||||||
batch._params[paramOffset + 3]._int,
|
GET_UNIFORM_LOCATION(batch._params[paramOffset + 3]._int),
|
||||||
batch._params[paramOffset + 2]._float,
|
batch._params[paramOffset + 2]._float,
|
||||||
batch._params[paramOffset + 1]._float,
|
batch._params[paramOffset + 1]._float,
|
||||||
batch._params[paramOffset + 0]._float);
|
batch._params[paramOffset + 0]._float);
|
||||||
|
@ -591,8 +579,6 @@ void Batch::_glUniform4f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLf
|
||||||
_params.push_back(v1);
|
_params.push_back(v1);
|
||||||
_params.push_back(v0);
|
_params.push_back(v0);
|
||||||
_params.push_back(location);
|
_params.push_back(location);
|
||||||
|
|
||||||
DO_IT_NOW(_glUniform4f, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -604,7 +590,7 @@ void GLBackend::do_glUniform4f(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
glUniform4f(
|
glUniform4f(
|
||||||
batch._params[paramOffset + 4]._int,
|
GET_UNIFORM_LOCATION(batch._params[paramOffset + 4]._int),
|
||||||
batch._params[paramOffset + 3]._float,
|
batch._params[paramOffset + 3]._float,
|
||||||
batch._params[paramOffset + 2]._float,
|
batch._params[paramOffset + 2]._float,
|
||||||
batch._params[paramOffset + 1]._float,
|
batch._params[paramOffset + 1]._float,
|
||||||
|
@ -619,8 +605,6 @@ void Batch::_glUniform3fv(GLint location, GLsizei count, const GLfloat* value) {
|
||||||
_params.push_back(cacheData(count * VEC3_SIZE, value));
|
_params.push_back(cacheData(count * VEC3_SIZE, value));
|
||||||
_params.push_back(count);
|
_params.push_back(count);
|
||||||
_params.push_back(location);
|
_params.push_back(location);
|
||||||
|
|
||||||
DO_IT_NOW(_glUniform3fv, 3);
|
|
||||||
}
|
}
|
||||||
void GLBackend::do_glUniform3fv(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glUniform3fv(Batch& batch, size_t paramOffset) {
|
||||||
if (_pipeline._program == 0) {
|
if (_pipeline._program == 0) {
|
||||||
|
@ -630,7 +614,7 @@ void GLBackend::do_glUniform3fv(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
glUniform3fv(
|
glUniform3fv(
|
||||||
batch._params[paramOffset + 2]._int,
|
GET_UNIFORM_LOCATION(batch._params[paramOffset + 2]._int),
|
||||||
batch._params[paramOffset + 1]._uint,
|
batch._params[paramOffset + 1]._uint,
|
||||||
(const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint));
|
(const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint));
|
||||||
|
|
||||||
|
@ -645,8 +629,6 @@ void Batch::_glUniform4fv(GLint location, GLsizei count, const GLfloat* value) {
|
||||||
_params.push_back(cacheData(count * VEC4_SIZE, value));
|
_params.push_back(cacheData(count * VEC4_SIZE, value));
|
||||||
_params.push_back(count);
|
_params.push_back(count);
|
||||||
_params.push_back(location);
|
_params.push_back(location);
|
||||||
|
|
||||||
DO_IT_NOW(_glUniform4fv, 3);
|
|
||||||
}
|
}
|
||||||
void GLBackend::do_glUniform4fv(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glUniform4fv(Batch& batch, size_t paramOffset) {
|
||||||
if (_pipeline._program == 0) {
|
if (_pipeline._program == 0) {
|
||||||
|
@ -656,7 +638,7 @@ void GLBackend::do_glUniform4fv(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
|
|
||||||
GLint location = batch._params[paramOffset + 2]._int;
|
GLint location = GET_UNIFORM_LOCATION(batch._params[paramOffset + 2]._int);
|
||||||
GLsizei count = batch._params[paramOffset + 1]._uint;
|
GLsizei count = batch._params[paramOffset + 1]._uint;
|
||||||
const GLfloat* value = (const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint);
|
const GLfloat* value = (const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint);
|
||||||
glUniform4fv(location, count, value);
|
glUniform4fv(location, count, value);
|
||||||
|
@ -671,8 +653,6 @@ void Batch::_glUniform4iv(GLint location, GLsizei count, const GLint* value) {
|
||||||
_params.push_back(cacheData(count * VEC4_SIZE, value));
|
_params.push_back(cacheData(count * VEC4_SIZE, value));
|
||||||
_params.push_back(count);
|
_params.push_back(count);
|
||||||
_params.push_back(location);
|
_params.push_back(location);
|
||||||
|
|
||||||
DO_IT_NOW(_glUniform4iv, 3);
|
|
||||||
}
|
}
|
||||||
void GLBackend::do_glUniform4iv(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glUniform4iv(Batch& batch, size_t paramOffset) {
|
||||||
if (_pipeline._program == 0) {
|
if (_pipeline._program == 0) {
|
||||||
|
@ -682,7 +662,7 @@ void GLBackend::do_glUniform4iv(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
glUniform4iv(
|
glUniform4iv(
|
||||||
batch._params[paramOffset + 2]._int,
|
GET_UNIFORM_LOCATION(batch._params[paramOffset + 2]._int),
|
||||||
batch._params[paramOffset + 1]._uint,
|
batch._params[paramOffset + 1]._uint,
|
||||||
(const GLint*)batch.editData(batch._params[paramOffset + 0]._uint));
|
(const GLint*)batch.editData(batch._params[paramOffset + 0]._uint));
|
||||||
|
|
||||||
|
@ -697,8 +677,6 @@ void Batch::_glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpo
|
||||||
_params.push_back(transpose);
|
_params.push_back(transpose);
|
||||||
_params.push_back(count);
|
_params.push_back(count);
|
||||||
_params.push_back(location);
|
_params.push_back(location);
|
||||||
|
|
||||||
DO_IT_NOW(_glUniformMatrix4fv, 4);
|
|
||||||
}
|
}
|
||||||
void GLBackend::do_glUniformMatrix4fv(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glUniformMatrix4fv(Batch& batch, size_t paramOffset) {
|
||||||
if (_pipeline._program == 0) {
|
if (_pipeline._program == 0) {
|
||||||
|
@ -708,7 +686,7 @@ void GLBackend::do_glUniformMatrix4fv(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
updatePipeline();
|
updatePipeline();
|
||||||
glUniformMatrix4fv(
|
glUniformMatrix4fv(
|
||||||
batch._params[paramOffset + 3]._int,
|
GET_UNIFORM_LOCATION(batch._params[paramOffset + 3]._int),
|
||||||
batch._params[paramOffset + 2]._uint,
|
batch._params[paramOffset + 2]._uint,
|
||||||
batch._params[paramOffset + 1]._uint,
|
batch._params[paramOffset + 1]._uint,
|
||||||
(const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint));
|
(const GLfloat*)batch.editData(batch._params[paramOffset + 0]._uint));
|
||||||
|
@ -722,8 +700,6 @@ void Batch::_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
|
||||||
_params.push_back(blue);
|
_params.push_back(blue);
|
||||||
_params.push_back(green);
|
_params.push_back(green);
|
||||||
_params.push_back(red);
|
_params.push_back(red);
|
||||||
|
|
||||||
DO_IT_NOW(_glColor4f, 4);
|
|
||||||
}
|
}
|
||||||
void GLBackend::do_glColor4f(Batch& batch, size_t paramOffset) {
|
void GLBackend::do_glColor4f(Batch& batch, size_t paramOffset) {
|
||||||
|
|
||||||
|
|
|
@ -153,17 +153,40 @@ public:
|
||||||
|
|
||||||
class GLShader : public GPUObject {
|
class GLShader : public GPUObject {
|
||||||
public:
|
public:
|
||||||
GLuint _shader;
|
enum Version {
|
||||||
GLuint _program;
|
Mono = 0,
|
||||||
|
|
||||||
|
NumVersions
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ShaderObject {
|
||||||
|
GLuint glshader{ 0 };
|
||||||
|
GLuint glprogram{ 0 };
|
||||||
|
GLint transformCameraSlot{ -1 };
|
||||||
|
GLint transformObjectSlot{ -1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
using ShaderObjects = std::array< ShaderObject, NumVersions >;
|
||||||
|
using UniformMapping = std::vector<GLint>;
|
||||||
|
using UniformMappingVersions = std::vector<UniformMapping>;
|
||||||
|
|
||||||
GLint _transformCameraSlot = -1;
|
|
||||||
GLint _transformObjectSlot = -1;
|
|
||||||
|
|
||||||
GLShader();
|
GLShader();
|
||||||
~GLShader();
|
~GLShader();
|
||||||
|
|
||||||
|
ShaderObjects _shaderObjects;
|
||||||
|
UniformMappingVersions _uniformMappings;
|
||||||
|
|
||||||
|
GLuint getProgram() const {
|
||||||
|
return _shaderObjects[Mono].glprogram;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint getUniformLocation(GLint srcLoc) {
|
||||||
|
return _uniformMappings[Mono][srcLoc];
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
static GLShader* syncGPUObject(const Shader& shader);
|
static GLShader* syncGPUObject(const Shader& shader);
|
||||||
static GLuint getShaderID(const ShaderPointer& shader);
|
|
||||||
|
|
||||||
class GLState : public GPUObject {
|
class GLState : public GPUObject {
|
||||||
public:
|
public:
|
||||||
|
@ -464,6 +487,7 @@ protected:
|
||||||
PipelinePointer _pipeline;
|
PipelinePointer _pipeline;
|
||||||
|
|
||||||
GLuint _program;
|
GLuint _program;
|
||||||
|
GLShader* _programShader;
|
||||||
bool _invalidProgram;
|
bool _invalidProgram;
|
||||||
|
|
||||||
State::Data _stateCache;
|
State::Data _stateCache;
|
||||||
|
@ -475,6 +499,7 @@ protected:
|
||||||
PipelineStageState() :
|
PipelineStageState() :
|
||||||
_pipeline(),
|
_pipeline(),
|
||||||
_program(0),
|
_program(0),
|
||||||
|
_programShader(nullptr),
|
||||||
_invalidProgram(false),
|
_invalidProgram(false),
|
||||||
_stateCache(State::DEFAULT),
|
_stateCache(State::DEFAULT),
|
||||||
_stateSignatureCache(0),
|
_stateSignatureCache(0),
|
||||||
|
|
|
@ -69,6 +69,7 @@ void GLBackend::do_setPipeline(Batch& batch, size_t paramOffset) {
|
||||||
_pipeline._pipeline.reset();
|
_pipeline._pipeline.reset();
|
||||||
|
|
||||||
_pipeline._program = 0;
|
_pipeline._program = 0;
|
||||||
|
_pipeline._programShader = nullptr;
|
||||||
_pipeline._invalidProgram = true;
|
_pipeline._invalidProgram = true;
|
||||||
|
|
||||||
_pipeline._state = nullptr;
|
_pipeline._state = nullptr;
|
||||||
|
@ -80,8 +81,10 @@ void GLBackend::do_setPipeline(Batch& batch, size_t paramOffset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the program cache
|
// check the program cache
|
||||||
if (_pipeline._program != pipelineObject->_program->_program) {
|
GLuint glprogram = pipelineObject->_program->getProgram();
|
||||||
_pipeline._program = pipelineObject->_program->_program;
|
if (_pipeline._program != glprogram) {
|
||||||
|
_pipeline._program = glprogram;
|
||||||
|
_pipeline._programShader = pipelineObject->_program;
|
||||||
_pipeline._invalidProgram = true;
|
_pipeline._invalidProgram = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +145,7 @@ void GLBackend::resetPipelineStage() {
|
||||||
// Second the shader side
|
// Second the shader side
|
||||||
_pipeline._invalidProgram = false;
|
_pipeline._invalidProgram = false;
|
||||||
_pipeline._program = 0;
|
_pipeline._program = 0;
|
||||||
|
_pipeline._programShader = nullptr;
|
||||||
_pipeline._pipeline.reset();
|
_pipeline._pipeline.reset();
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,27 +13,205 @@
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
|
|
||||||
GLBackend::GLShader::GLShader() :
|
GLBackend::GLShader::GLShader()
|
||||||
_shader(0),
|
{
|
||||||
_program(0)
|
}
|
||||||
{}
|
|
||||||
|
|
||||||
GLBackend::GLShader::~GLShader() {
|
GLBackend::GLShader::~GLShader() {
|
||||||
if (_shader != 0) {
|
for (auto& so : _shaderObjects) {
|
||||||
glDeleteShader(_shader);
|
if (so.glshader != 0) {
|
||||||
}
|
glDeleteShader(so.glshader);
|
||||||
if (_program != 0) {
|
}
|
||||||
glDeleteProgram(_program);
|
if (so.glprogram != 0) {
|
||||||
|
glDeleteProgram(so.glprogram);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeBindings(GLBackend::GLShader* shader) {
|
bool compileShader(GLenum shaderDomain, const std::string& shaderSource, const std::string& defines, GLuint &shaderObject, GLuint &programObject) {
|
||||||
if(!shader || !shader->_program) {
|
if (shaderSource.empty()) {
|
||||||
|
qCDebug(gpulogging) << "GLShader::compileShader - no GLSL shader source code ? so failed to create";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the shader object
|
||||||
|
GLuint glshader = glCreateShader(shaderDomain);
|
||||||
|
if (!glshader) {
|
||||||
|
qCDebug(gpulogging) << "GLShader::compileShader - failed to create the gl shader object";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the source
|
||||||
|
const int NUM_SOURCE_STRINGS = 2;
|
||||||
|
const GLchar* srcstr[] = { defines.c_str(), shaderSource.c_str() };
|
||||||
|
glShaderSource(glshader, NUM_SOURCE_STRINGS, srcstr, NULL);
|
||||||
|
|
||||||
|
// Compile !
|
||||||
|
glCompileShader(glshader);
|
||||||
|
|
||||||
|
// check if shader compiled
|
||||||
|
GLint compiled = 0;
|
||||||
|
glGetShaderiv(glshader, GL_COMPILE_STATUS, &compiled);
|
||||||
|
|
||||||
|
// if compilation fails
|
||||||
|
if (!compiled) {
|
||||||
|
// save the source code to a temp file so we can debug easily
|
||||||
|
/* std::ofstream filestream;
|
||||||
|
filestream.open("debugshader.glsl");
|
||||||
|
if (filestream.is_open()) {
|
||||||
|
filestream << shaderSource->source;
|
||||||
|
filestream.close();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
GLint infoLength = 0;
|
||||||
|
glGetShaderiv(glshader, GL_INFO_LOG_LENGTH, &infoLength);
|
||||||
|
|
||||||
|
char* temp = new char[infoLength];
|
||||||
|
glGetShaderInfoLog(glshader, infoLength, NULL, temp);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
filestream.open("debugshader.glsl.info.txt");
|
||||||
|
if (filestream.is_open()) {
|
||||||
|
filestream << std::string(temp);
|
||||||
|
filestream.close();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
qCWarning(gpulogging) << "GLShader::compileShader - failed to compile the gl shader object:";
|
||||||
|
for (auto s : srcstr) {
|
||||||
|
qCWarning(gpulogging) << s;
|
||||||
|
}
|
||||||
|
qCWarning(gpulogging) << "GLShader::compileShader - errors:";
|
||||||
|
qCWarning(gpulogging) << temp;
|
||||||
|
delete[] temp;
|
||||||
|
|
||||||
|
glDeleteShader(glshader);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint glprogram = 0;
|
||||||
|
#ifdef SEPARATE_PROGRAM
|
||||||
|
// so far so good, program is almost done, need to link:
|
||||||
|
GLuint glprogram = glCreateProgram();
|
||||||
|
if (!glprogram) {
|
||||||
|
qCDebug(gpulogging) << "GLShader::compileShader - failed to create the gl shader & gl program object";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glProgramParameteri(glprogram, GL_PROGRAM_SEPARABLE, GL_TRUE);
|
||||||
|
glAttachShader(glprogram, glshader);
|
||||||
|
glLinkProgram(glprogram);
|
||||||
|
|
||||||
|
GLint linked = 0;
|
||||||
|
glGetProgramiv(glprogram, GL_LINK_STATUS, &linked);
|
||||||
|
|
||||||
|
if (!linked) {
|
||||||
|
/*
|
||||||
|
// save the source code to a temp file so we can debug easily
|
||||||
|
std::ofstream filestream;
|
||||||
|
filestream.open("debugshader.glsl");
|
||||||
|
if (filestream.is_open()) {
|
||||||
|
filestream << shaderSource->source;
|
||||||
|
filestream.close();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
GLint infoLength = 0;
|
||||||
|
glGetProgramiv(glprogram, GL_INFO_LOG_LENGTH, &infoLength);
|
||||||
|
|
||||||
|
char* temp = new char[infoLength];
|
||||||
|
glGetProgramInfoLog(glprogram, infoLength, NULL, temp);
|
||||||
|
|
||||||
|
qCDebug(gpulogging) << "GLShader::compileShader - failed to LINK the gl program object :";
|
||||||
|
qCDebug(gpulogging) << temp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
filestream.open("debugshader.glsl.info.txt");
|
||||||
|
if (filestream.is_open()) {
|
||||||
|
filestream << String(temp);
|
||||||
|
filestream.close();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
delete[] temp;
|
||||||
|
|
||||||
|
glDeleteShader(glshader);
|
||||||
|
glDeleteProgram(glprogram);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
shaderObject = glshader;
|
||||||
|
programObject = glprogram;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint compileProgram(const std::vector<GLuint>& glshaders) {
|
||||||
|
// A brand new program:
|
||||||
|
GLuint glprogram = glCreateProgram();
|
||||||
|
if (!glprogram) {
|
||||||
|
qCDebug(gpulogging) << "GLShader::compileProgram - failed to create the gl program object";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// glProgramParameteri(glprogram, GL_PROGRAM_, GL_TRUE);
|
||||||
|
// Create the program from the sub shaders
|
||||||
|
for (auto so : glshaders) {
|
||||||
|
glAttachShader(glprogram, so);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Link!
|
||||||
|
glLinkProgram(glprogram);
|
||||||
|
|
||||||
|
GLint linked = 0;
|
||||||
|
glGetProgramiv(glprogram, GL_LINK_STATUS, &linked);
|
||||||
|
|
||||||
|
if (!linked) {
|
||||||
|
/*
|
||||||
|
// save the source code to a temp file so we can debug easily
|
||||||
|
std::ofstream filestream;
|
||||||
|
filestream.open("debugshader.glsl");
|
||||||
|
if (filestream.is_open()) {
|
||||||
|
filestream << shaderSource->source;
|
||||||
|
filestream.close();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
GLint infoLength = 0;
|
||||||
|
glGetProgramiv(glprogram, GL_INFO_LOG_LENGTH, &infoLength);
|
||||||
|
|
||||||
|
char* temp = new char[infoLength];
|
||||||
|
glGetProgramInfoLog(glprogram, infoLength, NULL, temp);
|
||||||
|
|
||||||
|
qCDebug(gpulogging) << "GLShader::compileProgram - failed to LINK the gl program object :";
|
||||||
|
qCDebug(gpulogging) << temp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
filestream.open("debugshader.glsl.info.txt");
|
||||||
|
if (filestream.is_open()) {
|
||||||
|
filestream << std::string(temp);
|
||||||
|
filestream.close();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
delete[] temp;
|
||||||
|
|
||||||
|
glDeleteProgram(glprogram);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return glprogram;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void makeProgramBindings(GLBackend::GLShader::ShaderObject& shaderObject) {
|
||||||
|
if (!shaderObject.glprogram) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
GLuint glprogram = shader->_program;
|
GLuint glprogram = shaderObject.glprogram;
|
||||||
GLint loc = -1;
|
GLint loc = -1;
|
||||||
|
|
||||||
//Check for gpu specific attribute slotBindings
|
//Check for gpu specific attribute slotBindings
|
||||||
loc = glGetAttribLocation(glprogram, "inPosition");
|
loc = glGetAttribLocation(glprogram, "inPosition");
|
||||||
if (loc >= 0 && loc != gpu::Stream::POSITION) {
|
if (loc >= 0 && loc != gpu::Stream::POSITION) {
|
||||||
|
@ -96,226 +274,111 @@ void makeBindings(GLBackend::GLShader* shader) {
|
||||||
loc = glGetProgramResourceIndex(glprogram, GL_SHADER_STORAGE_BLOCK, "transformObjectBuffer");
|
loc = glGetProgramResourceIndex(glprogram, GL_SHADER_STORAGE_BLOCK, "transformObjectBuffer");
|
||||||
if (loc >= 0) {
|
if (loc >= 0) {
|
||||||
glShaderStorageBlockBinding(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT);
|
glShaderStorageBlockBinding(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT);
|
||||||
shader->_transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT;
|
shaderObject.transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
loc = glGetUniformLocation(glprogram, "transformObjectBuffer");
|
loc = glGetUniformLocation(glprogram, "transformObjectBuffer");
|
||||||
if (loc >= 0) {
|
if (loc >= 0) {
|
||||||
glProgramUniform1i(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT);
|
glProgramUniform1i(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT);
|
||||||
shader->_transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT;
|
shaderObject.transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
loc = glGetUniformBlockIndex(glprogram, "transformCameraBuffer");
|
loc = glGetUniformBlockIndex(glprogram, "transformCameraBuffer");
|
||||||
if (loc >= 0) {
|
if (loc >= 0) {
|
||||||
glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_CAMERA_SLOT);
|
glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_CAMERA_SLOT);
|
||||||
shader->_transformCameraSlot = gpu::TRANSFORM_CAMERA_SLOT;
|
shaderObject.transformCameraSlot = gpu::TRANSFORM_CAMERA_SLOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void)CHECK_GL_ERROR();
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
GLBackend::GLShader* compileShader(const Shader& shader) {
|
GLBackend::GLShader* compileBackendShader(const Shader& shader) {
|
||||||
// Any GLSLprogram ? normally yes...
|
// Any GLSLprogram ? normally yes...
|
||||||
const std::string& shaderSource = shader.getSource().getCode();
|
const std::string& shaderSource = shader.getSource().getCode();
|
||||||
if (shaderSource.empty()) {
|
|
||||||
qCDebug(gpulogging) << "GLShader::compileShader - no GLSL shader source code ? so failed to create";
|
// GLSL version
|
||||||
return nullptr;
|
const std::string glslVersion = {
|
||||||
}
|
"#version 410 core"
|
||||||
|
};
|
||||||
|
|
||||||
// Shader domain
|
// Shader domain
|
||||||
const GLenum SHADER_DOMAINS[2] = { GL_VERTEX_SHADER, GL_FRAGMENT_SHADER };
|
const int NUM_SHADER_DOMAINS = 2;
|
||||||
|
const GLenum SHADER_DOMAINS[NUM_SHADER_DOMAINS] = {
|
||||||
|
GL_VERTEX_SHADER,
|
||||||
|
GL_FRAGMENT_SHADER
|
||||||
|
};
|
||||||
GLenum shaderDomain = SHADER_DOMAINS[shader.getType()];
|
GLenum shaderDomain = SHADER_DOMAINS[shader.getType()];
|
||||||
|
|
||||||
// Create the shader object
|
// Domain specific defines
|
||||||
GLuint glshader = glCreateShader(shaderDomain);
|
const std::string domainDefines[NUM_SHADER_DOMAINS] = {
|
||||||
if (!glshader) {
|
"#define VERTEX_SHADER",
|
||||||
qCDebug(gpulogging) << "GLShader::compileShader - failed to create the gl shader object";
|
"#define PIXEL_SHADER"
|
||||||
return nullptr;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Assign the source
|
|
||||||
const GLchar* srcstr = shaderSource.c_str();
|
|
||||||
glShaderSource(glshader, 1, &srcstr, NULL);
|
|
||||||
|
|
||||||
// Compile !
|
|
||||||
glCompileShader(glshader);
|
|
||||||
|
|
||||||
// check if shader compiled
|
// Versions specific of the shader
|
||||||
GLint compiled = 0;
|
const std::string versionDefines[GLBackend::GLShader::NumVersions] = {
|
||||||
glGetShaderiv(glshader, GL_COMPILE_STATUS, &compiled);
|
""
|
||||||
|
};
|
||||||
|
|
||||||
// if compilation fails
|
GLBackend::GLShader::ShaderObjects shaderObjects;
|
||||||
if (!compiled) {
|
|
||||||
// save the source code to a temp file so we can debug easily
|
for (int version = 0; version < GLBackend::GLShader::NumVersions; version++) {
|
||||||
/* std::ofstream filestream;
|
auto& shaderObject = shaderObjects[version];
|
||||||
filestream.open("debugshader.glsl");
|
|
||||||
if (filestream.is_open()) {
|
std::string shaderDefines = glslVersion + "\n" + domainDefines[shader.getType()] + "\n" + versionDefines[version];
|
||||||
filestream << shaderSource->source;
|
|
||||||
filestream.close();
|
bool result = compileShader(shaderDomain, shaderSource, shaderDefines, shaderObject.glshader, shaderObject.glprogram);
|
||||||
|
if (!result) {
|
||||||
|
return nullptr;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
GLint infoLength = 0;
|
|
||||||
glGetShaderiv(glshader, GL_INFO_LOG_LENGTH, &infoLength);
|
|
||||||
|
|
||||||
char* temp = new char[infoLength] ;
|
|
||||||
glGetShaderInfoLog(glshader, infoLength, NULL, temp);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
filestream.open("debugshader.glsl.info.txt");
|
|
||||||
if (filestream.is_open()) {
|
|
||||||
filestream << std::string(temp);
|
|
||||||
filestream.close();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
qCWarning(gpulogging) << "GLShader::compileShader - failed to compile the gl shader object:";
|
|
||||||
qCWarning(gpulogging) << srcstr;
|
|
||||||
qCWarning(gpulogging) << "GLShader::compileShader - errors:";
|
|
||||||
qCWarning(gpulogging) << temp;
|
|
||||||
delete[] temp;
|
|
||||||
|
|
||||||
glDeleteShader(glshader);
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint glprogram = 0;
|
|
||||||
#ifdef SEPARATE_PROGRAM
|
|
||||||
// so far so good, program is almost done, need to link:
|
|
||||||
GLuint glprogram = glCreateProgram();
|
|
||||||
if (!glprogram) {
|
|
||||||
qCDebug(gpulogging) << "GLShader::compileShader - failed to create the gl shader & gl program object";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
glProgramParameteri(glprogram, GL_PROGRAM_SEPARABLE, GL_TRUE);
|
|
||||||
glAttachShader(glprogram, glshader);
|
|
||||||
glLinkProgram(glprogram);
|
|
||||||
|
|
||||||
GLint linked = 0;
|
|
||||||
glGetProgramiv(glprogram, GL_LINK_STATUS, &linked);
|
|
||||||
|
|
||||||
if (!linked) {
|
|
||||||
/*
|
|
||||||
// save the source code to a temp file so we can debug easily
|
|
||||||
std::ofstream filestream;
|
|
||||||
filestream.open("debugshader.glsl");
|
|
||||||
if (filestream.is_open()) {
|
|
||||||
filestream << shaderSource->source;
|
|
||||||
filestream.close();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLint infoLength = 0;
|
|
||||||
glGetProgramiv(glprogram, GL_INFO_LOG_LENGTH, &infoLength);
|
|
||||||
|
|
||||||
char* temp = new char[infoLength] ;
|
|
||||||
glGetProgramInfoLog(glprogram, infoLength, NULL, temp);
|
|
||||||
|
|
||||||
qCDebug(gpulogging) << "GLShader::compileShader - failed to LINK the gl program object :";
|
|
||||||
qCDebug(gpulogging) << temp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
filestream.open("debugshader.glsl.info.txt");
|
|
||||||
if (filestream.is_open()) {
|
|
||||||
filestream << String(temp);
|
|
||||||
filestream.close();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
delete[] temp;
|
|
||||||
|
|
||||||
glDeleteShader(glshader);
|
|
||||||
glDeleteProgram(glprogram);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// So far so good, the shader is created successfully
|
// So far so good, the shader is created successfully
|
||||||
GLBackend::GLShader* object = new GLBackend::GLShader();
|
GLBackend::GLShader* object = new GLBackend::GLShader();
|
||||||
object->_shader = glshader;
|
object->_shaderObjects = shaderObjects;
|
||||||
object->_program = glprogram;
|
|
||||||
|
|
||||||
makeBindings(object);
|
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLBackend::GLShader* compileProgram(const Shader& program) {
|
GLBackend::GLShader* compileBackendProgram(const Shader& program) {
|
||||||
if(!program.isProgram()) {
|
if (!program.isProgram()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's go through every shaders and make sure they are ready to go
|
GLBackend::GLShader::ShaderObjects programObjects;
|
||||||
std::vector< GLuint > shaderObjects;
|
|
||||||
for (auto subShader : program.getShaders()) {
|
for (int version = 0; version < GLBackend::GLShader::NumVersions; version++) {
|
||||||
GLuint so = GLBackend::getShaderID(subShader);
|
auto& programObject = programObjects[version];
|
||||||
if (!so) {
|
|
||||||
qCDebug(gpulogging) << "GLShader::compileProgram - One of the shaders of the program is not compiled?";
|
// Let's go through every shaders and make sure they are ready to go
|
||||||
|
std::vector< GLuint > shaderGLObjects;
|
||||||
|
for (auto subShader : program.getShaders()) {
|
||||||
|
auto object = GLBackend::syncGPUObject(*subShader);
|
||||||
|
if (object) {
|
||||||
|
shaderGLObjects.push_back(object->_shaderObjects[version].glshader);
|
||||||
|
} else {
|
||||||
|
qCDebug(gpulogging) << "GLShader::compileBackendProgram - One of the shaders of the program is not compiled?";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint glprogram = compileProgram(shaderGLObjects);
|
||||||
|
if (glprogram == 0) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
shaderObjects.push_back(so);
|
|
||||||
|
programObject.glprogram = glprogram;
|
||||||
|
|
||||||
|
makeProgramBindings(programObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
// so far so good, program is almost done, need to link:
|
|
||||||
GLuint glprogram = glCreateProgram();
|
|
||||||
if (!glprogram) {
|
|
||||||
qCDebug(gpulogging) << "GLShader::compileProgram - failed to create the gl program object";
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// glProgramParameteri(glprogram, GL_PROGRAM_, GL_TRUE);
|
// So far so good, the program versions have all been created successfully
|
||||||
// Create the program from the sub shaders
|
|
||||||
for (auto so : shaderObjects) {
|
|
||||||
glAttachShader(glprogram, so);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Link!
|
|
||||||
glLinkProgram(glprogram);
|
|
||||||
|
|
||||||
GLint linked = 0;
|
|
||||||
glGetProgramiv(glprogram, GL_LINK_STATUS, &linked);
|
|
||||||
|
|
||||||
if (!linked) {
|
|
||||||
/*
|
|
||||||
// save the source code to a temp file so we can debug easily
|
|
||||||
std::ofstream filestream;
|
|
||||||
filestream.open("debugshader.glsl");
|
|
||||||
if (filestream.is_open()) {
|
|
||||||
filestream << shaderSource->source;
|
|
||||||
filestream.close();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
GLint infoLength = 0;
|
|
||||||
glGetProgramiv(glprogram, GL_INFO_LOG_LENGTH, &infoLength);
|
|
||||||
|
|
||||||
char* temp = new char[infoLength] ;
|
|
||||||
glGetProgramInfoLog(glprogram, infoLength, NULL, temp);
|
|
||||||
|
|
||||||
qCDebug(gpulogging) << "GLShader::compileProgram - failed to LINK the gl program object :";
|
|
||||||
qCDebug(gpulogging) << temp;
|
|
||||||
|
|
||||||
/*
|
|
||||||
filestream.open("debugshader.glsl.info.txt");
|
|
||||||
if (filestream.is_open()) {
|
|
||||||
filestream << std::string(temp);
|
|
||||||
filestream.close();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
delete[] temp;
|
|
||||||
|
|
||||||
glDeleteProgram(glprogram);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// So far so good, the program is created successfully
|
|
||||||
GLBackend::GLShader* object = new GLBackend::GLShader();
|
GLBackend::GLShader* object = new GLBackend::GLShader();
|
||||||
object->_shader = 0;
|
object->_shaderObjects = programObjects;
|
||||||
object->_program = glprogram;
|
|
||||||
|
|
||||||
makeBindings(object);
|
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
@ -329,14 +392,14 @@ GLBackend::GLShader* GLBackend::syncGPUObject(const Shader& shader) {
|
||||||
}
|
}
|
||||||
// need to have a gpu object?
|
// need to have a gpu object?
|
||||||
if (shader.isProgram()) {
|
if (shader.isProgram()) {
|
||||||
GLShader* tempObject = compileProgram(shader);
|
GLShader* tempObject = compileBackendProgram(shader);
|
||||||
if (tempObject) {
|
if (tempObject) {
|
||||||
object = tempObject;
|
object = tempObject;
|
||||||
Backend::setGPUObject(shader, object);
|
Backend::setGPUObject(shader, object);
|
||||||
}
|
}
|
||||||
} else if (shader.isDomain()) {
|
} else if (shader.isDomain()) {
|
||||||
GLShader* tempObject = compileShader(shader);
|
GLShader* tempObject = compileBackendShader(shader);
|
||||||
if (tempObject) {
|
if (tempObject) {
|
||||||
object = tempObject;
|
object = tempObject;
|
||||||
Backend::setGPUObject(shader, object);
|
Backend::setGPUObject(shader, object);
|
||||||
}
|
}
|
||||||
|
@ -345,23 +408,6 @@ GLBackend::GLShader* GLBackend::syncGPUObject(const Shader& shader) {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GLuint GLBackend::getShaderID(const ShaderPointer& shader) {
|
|
||||||
if (!shader) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
GLShader* object = GLBackend::syncGPUObject(*shader);
|
|
||||||
if (object) {
|
|
||||||
if (shader->isProgram()) {
|
|
||||||
return object->_program;
|
|
||||||
} else {
|
|
||||||
return object->_shader;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ElementResource {
|
class ElementResource {
|
||||||
public:
|
public:
|
||||||
gpu::Element _element;
|
gpu::Element _element;
|
||||||
|
@ -714,27 +760,38 @@ bool GLBackend::makeProgram(Shader& shader, const Shader::BindingSet& slotBindin
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (object->_program) {
|
// Apply bindings to all program versions and generate list of slots from default version
|
||||||
Shader::SlotSet buffers;
|
for (int version = 0; version < GLBackend::GLShader::NumVersions; version++) {
|
||||||
makeUniformBlockSlots(object->_program, slotBindings, buffers);
|
auto& shaderObject = object->_shaderObjects[version];
|
||||||
|
if (shaderObject.glprogram) {
|
||||||
|
Shader::SlotSet buffers;
|
||||||
|
makeUniformBlockSlots(shaderObject.glprogram, slotBindings, buffers);
|
||||||
|
|
||||||
Shader::SlotSet uniforms;
|
Shader::SlotSet uniforms;
|
||||||
Shader::SlotSet textures;
|
Shader::SlotSet textures;
|
||||||
Shader::SlotSet samplers;
|
Shader::SlotSet samplers;
|
||||||
makeUniformSlots(object->_program, slotBindings, uniforms, textures, samplers);
|
makeUniformSlots(shaderObject.glprogram, slotBindings, uniforms, textures, samplers);
|
||||||
|
|
||||||
Shader::SlotSet inputs;
|
|
||||||
makeInputSlots(object->_program, slotBindings, inputs);
|
|
||||||
|
|
||||||
Shader::SlotSet outputs;
|
Shader::SlotSet inputs;
|
||||||
makeOutputSlots(object->_program, slotBindings, outputs);
|
makeInputSlots(shaderObject.glprogram, slotBindings, inputs);
|
||||||
|
|
||||||
shader.defineSlots(uniforms, buffers, textures, samplers, inputs, outputs);
|
Shader::SlotSet outputs;
|
||||||
|
makeOutputSlots(shaderObject.glprogram, slotBindings, outputs);
|
||||||
} else if (object->_shader) {
|
|
||||||
|
|
||||||
|
// Define the public slots only from the default version
|
||||||
|
if (version == 0) {
|
||||||
|
shader.defineSlots(uniforms, buffers, textures, samplers, inputs, outputs);
|
||||||
|
} else {
|
||||||
|
GLShader::UniformMapping mapping;
|
||||||
|
for (auto srcUniform : shader.getUniforms()) {
|
||||||
|
mapping[srcUniform._location] = uniforms.findLocation(srcUniform._name);
|
||||||
|
}
|
||||||
|
object->_uniformMappings.push_back(mapping);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ ToneMappingEffect::ToneMappingEffect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToneMappingEffect::init() {
|
void ToneMappingEffect::init() {
|
||||||
const char BlitTextureGamma_frag[] = R"SCRIBE(#version 410 core
|
const char BlitTextureGamma_frag[] = R"SCRIBE(
|
||||||
// Generated on Sat Oct 24 09:34:37 2015
|
// Generated on Sat Oct 24 09:34:37 2015
|
||||||
//
|
//
|
||||||
// Draw texture 0 fetched at texcoord.xy
|
// Draw texture 0 fetched at texcoord.xy
|
||||||
|
|
Loading…
Reference in a new issue