Performance optimizations, caching uniforms and bound textures and avoiding uploding them if they're already set.
This commit is contained in:
parent
2cac6e1766
commit
b4e66809cb
|
@ -153,6 +153,7 @@ void renderNode(SceneNode* node, Gloom::Shader* parent_shader, vector<NodeDistSh
|
|||
};
|
||||
static Light lights[N_LIGHTS];
|
||||
static Gloom::Shader* s = nullptr; // The currently active shader
|
||||
static Gloom::Shader* prev_s = nullptr; // The last shader to glDrawElements
|
||||
|
||||
// activate the correct shader
|
||||
Gloom::Shader* node_shader = (node->shader != nullptr)
|
||||
|
@ -164,39 +165,49 @@ void renderNode(SceneNode* node, Gloom::Shader* parent_shader, vector<NodeDistSh
|
|||
uint i = 0; for (Light l : lights) l.push_to_shader(s, i++);
|
||||
}
|
||||
|
||||
bool shader_changed = s == prev_s;
|
||||
#define cache(x) static decltype(node->x) cached_ ## x; if (shader_changed && cached_ ## x != node->x) { cached_ ## x = node->x;
|
||||
#define um4fv(x) cache(x) glUniformMatrix4fv(s->location(#x), 1, GL_FALSE, glm::value_ptr(node->x)); }
|
||||
#define u2fv(x) cache(x) glUniform2fv( s->location(#x), 1, glm::value_ptr(node->x)); }
|
||||
#define u3fv(x) cache(x) glUniform3fv( s->location(#x), 1, glm::value_ptr(node->x)); }
|
||||
#define u1f(x) cache(x) glUniform1f( s->location(#x), node->x); }
|
||||
#define u1ui(x) cache(x) glUniform1ui( s->location(#x), node->x); }
|
||||
#define ubtu(n,i,x) if(node->i) { cache(x) glBindTextureUnit(n, node->x); } }
|
||||
|
||||
switch(node->nodeType) {
|
||||
case GEOMETRY:
|
||||
if (transparent_nodes!=nullptr && node->has_transparancy()) {
|
||||
// defer to sorted pass later on
|
||||
transparent_nodes->emplace_back(node, node_shader, (float)glm::length(vec3(node->MVP*vec4(0,0,0,1))));
|
||||
//transparent_nodes->emplace_back(node, node_shader, glm::length(vec3(node->MVP[3])));
|
||||
//transparent_nodes->push_back({node, node_shader, glm::length(vec3(node->MVP[3]))});
|
||||
transparent_nodes->emplace_back(node, node_shader, glm::length(vec3(node->MVP*vec4(0,0,0,1))));
|
||||
//transparent_nodes->push_back({node, node_shader, glm::length(vec3(node->MVP*vec4(0,0,0,1)))});
|
||||
}
|
||||
else if(node->vertexArrayObjectID != -1) {
|
||||
// load uniforms
|
||||
glUniformMatrix4fv(s->location("MVP") , 1, GL_FALSE, glm::value_ptr(node->MVP));
|
||||
glUniformMatrix4fv(s->location("MV") , 1, GL_FALSE, glm::value_ptr(node->MV));
|
||||
glUniformMatrix4fv(s->location("MVnormal"), 1, GL_FALSE, glm::value_ptr(node->MVnormal));
|
||||
glUniform2fv(s->location("uvOffset") , 1, glm::value_ptr(node->uvOffset));
|
||||
glUniform3fv(s->location("diffuse_color") , 1, glm::value_ptr(node->diffuse_color));
|
||||
glUniform3fv(s->location("emissive_color"), 1, glm::value_ptr(node->emissive_color));
|
||||
glUniform3fv(s->location("specular_color"), 1, glm::value_ptr(node->specular_color));
|
||||
glUniform1f( s->location("opacity"), node->opacity);
|
||||
glUniform1f( s->location("shininess"), node->shininess);
|
||||
glUniform1f( s->location("reflexiveness"), node->reflexiveness);
|
||||
glUniform1f( s->location("displacementCoefficient"), node->displacementCoefficient);
|
||||
glUniform1ui(s->location("isTextured"), node->isTextured);
|
||||
glUniform1ui(s->location("isVertexColored"), node->isVertexColored);
|
||||
glUniform1ui(s->location("isNormalMapped"), node->isNormalMapped);
|
||||
glUniform1ui(s->location("isDisplacementMapped"), node->isDisplacementMapped);
|
||||
glUniform1ui(s->location("isReflectionMapped"), node->isReflectionMapped);
|
||||
glUniform1ui(s->location("isIlluminated"), node->isIlluminated);
|
||||
glUniform1ui(s->location("isInverted"), node->isInverted);
|
||||
|
||||
if (node->isTextured) glBindTextureUnit(0, node->diffuseTextureID);
|
||||
if (node->isNormalMapped) glBindTextureUnit(1, node->normalTextureID);
|
||||
if (node->isDisplacementMapped) glBindTextureUnit(2, node->displacementTextureID);
|
||||
if (node->isReflectionMapped) glBindTextureUnit(3, node->reflectionTextureID);
|
||||
um4fv(MVP); um4fv(MV); um4fv(MVnormal);
|
||||
u2fv (uvOffset);
|
||||
u3fv (diffuse_color);
|
||||
u3fv (emissive_color);
|
||||
u3fv (specular_color);
|
||||
u1f (opacity);
|
||||
u1f (shininess);
|
||||
u1f (reflexiveness);
|
||||
u1f (displacementCoefficient);
|
||||
u1ui (isTextured);
|
||||
u1ui (isVertexColored);
|
||||
u1ui (isNormalMapped);
|
||||
u1ui (isDisplacementMapped);
|
||||
u1ui (isReflectionMapped);
|
||||
u1ui (isIlluminated);
|
||||
u1ui (isInverted);
|
||||
ubtu(0, isTextured , diffuseTextureID);
|
||||
ubtu(1, isNormalMapped , normalTextureID);
|
||||
ubtu(2, isDisplacementMapped, displacementTextureID);
|
||||
ubtu(3, isReflectionMapped , reflectionTextureID);
|
||||
glBindVertexArray(node->vertexArrayObjectID);
|
||||
glDrawElements(GL_TRIANGLES, node->VAOIndexCount, GL_UNSIGNED_INT, nullptr);
|
||||
prev_s = s;
|
||||
}
|
||||
break;
|
||||
case SPOT_LIGHT:
|
||||
|
@ -215,6 +226,14 @@ void renderNode(SceneNode* node, Gloom::Shader* parent_shader, vector<NodeDistSh
|
|||
break;
|
||||
}
|
||||
|
||||
#undef um4fv
|
||||
#undef u2fv
|
||||
#undef u3fv
|
||||
#undef u1f
|
||||
#undef u1ui
|
||||
#undef ubtu
|
||||
#undef cache
|
||||
|
||||
if (do_recursive)
|
||||
for(SceneNode* child : node->children) {
|
||||
renderNode(child, node_shader, transparent_nodes, true);
|
||||
|
@ -238,12 +257,12 @@ void renderFrame(GLFWwindow* window, int windowWidth, int windowHeight) {
|
|||
[](NodeDistShader a, NodeDistShader b) {
|
||||
return a.dist > b.dist;
|
||||
});
|
||||
glDepthMask(GL_FALSE);
|
||||
glDepthMask(GL_FALSE); // read only
|
||||
//glDisable(GL_DEPTH_TEST);
|
||||
for (NodeDistShader a : transparent_nodes)
|
||||
renderNode(a.node, a.s, nullptr, false);
|
||||
std::cout << transparent_nodes.size() << std::endl;
|
||||
glDepthMask(GL_TRUE);
|
||||
glDepthMask(GL_TRUE); // read write
|
||||
//glEnable(GL_DEPTH_TEST);
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
|
||||
namespace Gloom
|
||||
|
@ -19,17 +20,21 @@ namespace Gloom
|
|||
public:
|
||||
Shader() { mProgram = glCreateProgram(); }
|
||||
|
||||
// hack?:
|
||||
GLint location(std::string const& name) {
|
||||
return glGetUniformLocation(mProgram, name.c_str());
|
||||
}
|
||||
|
||||
// Public member functions
|
||||
void activate() { glUseProgram(mProgram); }
|
||||
void deactivate() { glUseProgram(0); }
|
||||
GLuint get() { return mProgram; }
|
||||
void destroy() { glDeleteProgram(mProgram); }
|
||||
|
||||
GLint inline location(std::string const& name) {
|
||||
static std::map<std::string, GLint> cache {};
|
||||
auto it = cache.find(name);
|
||||
if (it == cache.end())
|
||||
return cache[name] = glGetUniformLocation(mProgram, name.c_str());
|
||||
return it->second;
|
||||
//return glGetUniformLocation(mProgram, name.c_str());
|
||||
}
|
||||
|
||||
/* Attach a shader to the current shader program */
|
||||
void attach(std::string const &filename)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue