Make it possible ot have different shaders along scene graph
This commit is contained in:
parent
88376587e5
commit
da7a29a2d1
|
@ -17,12 +17,12 @@ uniform bool isTextured;
|
||||||
uniform bool isNormalMapped;
|
uniform bool isNormalMapped;
|
||||||
uniform bool isInverted;
|
uniform bool isInverted;
|
||||||
|
|
||||||
// point lights
|
// lights
|
||||||
struct Light {
|
struct Light {
|
||||||
vec3 position;
|
vec3 position;
|
||||||
mat4 MV;
|
mat4 MV;
|
||||||
bool is_spot;
|
bool is_spot; // false means point light
|
||||||
vec3 spot_target; // MV space coordinates
|
vec3 spot_target; // MV space coordinates for spots
|
||||||
};
|
};
|
||||||
|
|
||||||
//named
|
//named
|
||||||
|
|
|
@ -48,7 +48,10 @@ double ballRadius = 3.0f;
|
||||||
// These are heap allocated, because they should not be initialised at the start of the program
|
// These are heap allocated, because they should not be initialised at the start of the program
|
||||||
sf::Sound* sound;
|
sf::Sound* sound;
|
||||||
sf::SoundBuffer* buffer;
|
sf::SoundBuffer* buffer;
|
||||||
Gloom::Shader* shader;
|
Gloom::Shader* default_shader;
|
||||||
|
Gloom::Shader* test_shader;
|
||||||
|
Gloom::Shader* plain_shader;
|
||||||
|
Gloom::Shader* post_shader;
|
||||||
|
|
||||||
const vec3 boxDimensions(180, 90, 50);
|
const vec3 boxDimensions(180, 90, 50);
|
||||||
const vec3 padDimensions(30, 3, 40);
|
const vec3 padDimensions(30, 3, 40);
|
||||||
|
@ -109,10 +112,10 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) {
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||||
glfwSetCursorPosCallback(window, mouseCallback);
|
glfwSetCursorPosCallback(window, mouseCallback);
|
||||||
|
|
||||||
shader = new Gloom::Shader();
|
// load shaders
|
||||||
shader->makeBasicShader("../res/shaders/simple.vert", "../res/shaders/simple.frag");
|
default_shader = new Gloom::Shader();
|
||||||
shader->activate();
|
default_shader->makeBasicShader("../res/shaders/simple.vert", "../res/shaders/simple.frag");
|
||||||
|
|
||||||
Mesh box = generateBox(boxDimensions.x, boxDimensions.y, boxDimensions.z, true);
|
Mesh box = generateBox(boxDimensions.x, boxDimensions.y, boxDimensions.z, true);
|
||||||
Mesh pad = generateBox(padDimensions.x, padDimensions.y, padDimensions.z, false);
|
Mesh pad = generateBox(padDimensions.x, padDimensions.y, padDimensions.z, false);
|
||||||
Mesh sphere = generateSphere(1.0, 40, 40);
|
Mesh sphere = generateSphere(1.0, 40, 40);
|
||||||
|
@ -391,39 +394,66 @@ void updateFrame(GLFWwindow* window) {
|
||||||
|
|
||||||
|
|
||||||
void renderNode(SceneNode* node) {
|
void renderNode(SceneNode* node) {
|
||||||
|
struct Light { // lights as stored in the shader
|
||||||
|
glm::vec3 position;
|
||||||
|
glm::mat4 MV;
|
||||||
|
bool is_spot;
|
||||||
|
glm::vec3 spot_target; // MV space coordinates
|
||||||
|
|
||||||
|
void push_to_shader(Gloom::Shader* shader, uint id) {
|
||||||
|
#define l(x) shader->location("light[" + std::to_string(id) + "]." + #x)
|
||||||
|
glUniformMatrix4fv(l(MV) , 1, GL_FALSE, glm::value_ptr(MV));
|
||||||
|
glUniform3fv (l(position) , 1, glm::value_ptr(position));
|
||||||
|
glUniform3fv (l(spot_target), 1, glm::value_ptr(spot_target));
|
||||||
|
glUniform1i (l(is_spot) , is_spot);
|
||||||
|
#undef l
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static Light lights[3];
|
||||||
|
static Gloom::Shader* s = nullptr; // The currently active shader
|
||||||
|
|
||||||
|
// activate the correct shader
|
||||||
|
Gloom::Shader* node_shader = (node->shader != nullptr)
|
||||||
|
? node->shader
|
||||||
|
: default_shader;
|
||||||
|
if (s != node_shader) {
|
||||||
|
s = node_shader;
|
||||||
|
s->activate();
|
||||||
|
uint i = 0; for (Light l : lights) l.push_to_shader(s, i++);
|
||||||
|
}
|
||||||
|
|
||||||
|
// load uniforms
|
||||||
glUniformMatrix4fv(s->location("MVP") , 1, GL_FALSE, glm::value_ptr(node->MVP));
|
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("MV") , 1, GL_FALSE, glm::value_ptr(node->MV));
|
||||||
glUniformMatrix4fv(s->location("MVnormal"), 1, GL_FALSE, glm::value_ptr(node->MVnormal));
|
glUniformMatrix4fv(s->location("MVnormal"), 1, GL_FALSE, glm::value_ptr(node->MVnormal));
|
||||||
glUniform1ui(shader->location("isNormalMapped"), false);
|
glUniform1ui(s->location("isNormalMapped"), false);
|
||||||
glUniform1ui(shader->location("isTextured"), false);
|
glUniform1ui(s->location("isTextured"), false);
|
||||||
|
|
||||||
switch(node->nodeType) {
|
switch(node->nodeType) {
|
||||||
case NORMAL_TEXTURED_GEOMETRY:
|
case NORMAL_TEXTURED_GEOMETRY:
|
||||||
glUniform1ui(shader->location("isNormalMapped"), true);
|
glUniform1ui(s->location("isNormalMapped"), true);
|
||||||
glBindTextureUnit(1, node->normalTextureID);
|
glBindTextureUnit(1, node->normalTextureID);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case TEXTURED_GEOMETRY:
|
case TEXTURED_GEOMETRY:
|
||||||
glUniform1ui(shader->location("isTextured"), true);
|
glUniform1ui(s->location("isTextured"), true);
|
||||||
glBindTextureUnit(0, node->diffuseTextureID);
|
glBindTextureUnit(0, node->diffuseTextureID);
|
||||||
[[fallthrough]];
|
[[fallthrough]];
|
||||||
case GEOMETRY:
|
case GEOMETRY:
|
||||||
if(node->vertexArrayObjectID != -1) {
|
if(node->vertexArrayObjectID != -1) {
|
||||||
glUniform1ui(shader->location("isIlluminated"), node->isIlluminated);
|
glUniform1ui(s->location("isIlluminated"), node->isIlluminated);
|
||||||
glUniform1ui(shader->location("isInverted"), node->isInverted);
|
glUniform1ui(s->location("isInverted"), node->isInverted);
|
||||||
glBindVertexArray(node->vertexArrayObjectID);
|
glBindVertexArray(node->vertexArrayObjectID);
|
||||||
glDrawElements(GL_TRIANGLES, node->VAOIndexCount, GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, node->VAOIndexCount, GL_UNSIGNED_INT, nullptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SPOT_LIGHT:
|
case SPOT_LIGHT:
|
||||||
case POINT_LIGHT: {
|
case POINT_LIGHT: {
|
||||||
std::string pre = "light[" + std::to_string(node->lightID) + "]";
|
uint id = node->lightID;
|
||||||
|
lights[id].position = node->position;
|
||||||
glUniform3fv(shader->location(pre+".position"), 1, glm::value_ptr(node->position));
|
lights[id].MV = node->MV;
|
||||||
glUniformMatrix4fv(shader->location(pre+".MV"), 1, GL_FALSE, glm::value_ptr(node->currentTransformationMatrixMV));
|
lights[id].is_spot = node->nodeType == SPOT_LIGHT;
|
||||||
|
lights[id].spot_target = node->rotation;
|
||||||
glUniform1i(shader->location(pre+".is_spot"), node->nodeType == SPOT_LIGHT);
|
lights[id].push_to_shader(s, id);
|
||||||
glUniform3fv(shader->location(pre+".spot_target"), 1, glm::value_ptr(node->rotation));
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HUD:
|
case HUD:
|
||||||
|
|
|
@ -44,6 +44,9 @@ struct SceneNode {
|
||||||
glm::vec3 rotation;
|
glm::vec3 rotation;
|
||||||
glm::vec3 scale;
|
glm::vec3 scale;
|
||||||
|
|
||||||
|
// set this if the shape uses a custom shader other than the default one
|
||||||
|
Gloom::Shader* shader = nullptr;
|
||||||
|
|
||||||
// A transformation matrix representing the transformation of the node's location relative to its parent. This matrix is updated every frame.
|
// A transformation matrix representing the transformation of the node's location relative to its parent. This matrix is updated every frame.
|
||||||
glm::mat4 MVP; // MVP
|
glm::mat4 MVP; // MVP
|
||||||
glm::mat4 MV; // MV
|
glm::mat4 MV; // MV
|
||||||
|
|
Loading…
Reference in New Issue