From 29defbaba9e26c017ffa178e42b6828acd9d6dc5 Mon Sep 17 00:00:00 2001 From: Peder Bergebakken Sundt Date: Mon, 18 Mar 2019 11:48:11 +0100 Subject: [PATCH] Add vertex color array --- .gitmodules | 3 +++ CMakeLists.txt | 10 ++++++++- lib/assimp | 1 + res/shaders/simple.frag | 29 +++++++++++++------------- res/shaders/simple.vert | 14 ++++++++----- src/gamelogic.cpp | 12 ++++++----- src/sceneGraph.hpp | 14 ++++++++----- src/utilities/glutils.cpp | 43 ++++++++++++++++++++++++--------------- src/utilities/glutils.h | 4 ++-- src/utilities/mesh.h | 1 + 10 files changed, 82 insertions(+), 49 deletions(-) create mode 160000 lib/assimp diff --git a/.gitmodules b/.gitmodules index 8233d4f..12118d9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -28,3 +28,6 @@ [submodule "lib/lodepng"] path = lib/lodepng url = https://github.com/lvandeve/lodepng +[submodule "lib/assimp"] + path = lib/assimp + url = git@github.com:assimp/assimp.git diff --git a/CMakeLists.txt b/CMakeLists.txt index b8014ba..74b7c31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ # Specify minimum CMake version and project name # cmake_minimum_required (VERSION 3.0) -project (glowbox) +project (plain_of_awesome) # # CMake setup @@ -37,6 +37,12 @@ option (SFML_BUILD_WINDOW OFF) option (SFML_BUILD_NETWORK OFF) add_subdirectory(lib/SFML) +# assimp +set(BUILD_ASSIMP_TOOLS ON) +set(ASSIMP_BUILD_STATIC_LIB ON) +add_subdirectory(lib/assimp) +link_directories("lib/assimp/build/code") + # # Set include paths # @@ -47,6 +53,7 @@ include_directories (src/ lib/glm/ lib/stb/ lib/arrrgh/ + lib/assimp/include/ lib/SFML/include/) # @@ -88,5 +95,6 @@ add_executable (${PROJECT_NAME} ${PROJECT_SOURCES} ${PROJECT_HEADERS} target_link_libraries (${PROJECT_NAME} glfw sfml-audio + assimp ${GLFW_LIBRARIES} ${GLAD_LIBRARIES}) diff --git a/lib/assimp b/lib/assimp new file mode 160000 index 0000000..e899067 --- /dev/null +++ b/lib/assimp @@ -0,0 +1 @@ +Subproject commit e899067f440c79747549772fef61abe916bd496e diff --git a/res/shaders/simple.frag b/res/shaders/simple.frag index 2b36a5b..aab0a87 100644 --- a/res/shaders/simple.frag +++ b/res/shaders/simple.frag @@ -3,8 +3,9 @@ in layout(location = 0) vec3 vertex; in layout(location = 1) vec3 normal; in layout(location = 2) vec2 UV; -in layout(location = 3) vec3 tangent; -in layout(location = 4) vec3 bitangent; +in layout(location = 3) vec4 color; +in layout(location = 4) vec3 tangent; +in layout(location = 5) vec3 bitangent; layout(binding = 0) uniform sampler2D diffuseTexture; layout(binding = 1) uniform sampler2D normalTexture; @@ -15,10 +16,12 @@ uniform mat4 MVP; uniform mat4 MV; uniform mat4 MVnormal; -uniform float shinyness; +uniform float shininess; +uniform vec4 basecolor; uniform bool isIlluminated; uniform bool isTextured; +uniform bool isColorMapped; uniform bool isNormalMapped; uniform bool isDisplacementMapped; uniform bool isInverted; @@ -40,7 +43,7 @@ struct Light { // point lights, coordinates in MV space uniform Light light[N_LIGHTS]; -out vec4 color; +out vec4 color_out; vec4 phong(vec4 basecolor) { @@ -102,7 +105,7 @@ vec4 phong(vec4 basecolor) { float diffuse_i = dot(nnormal, L); float specular_i = dot(reflect(-L, nnormal), -normalize(vertex)); specular_i = (specular_i>0) - ? pow(specular_i, shinyness) + ? pow(specular_i, shininess) : 0; emmissive_component += light[i].color_emissive; @@ -114,14 +117,10 @@ vec4 phong(vec4 basecolor) { } void main() { - if(isIlluminated) { - if (isTextured) { - color = phong(texture(diffuseTexture, UV)); - } else { - color = phong(vec4(1.0)); - } - } else { - color = texture(diffuseTexture, UV); - } - if (isInverted) color.rgb = 1 - color.rgb; + vec4 c = basecolor; + if (isColorMapped) c *= color; + if (isTextured) c *= texture(diffuseTexture, UV); + if (isIlluminated) c = phong(c); + if (isInverted) c.rgb = 1 - c.rgb; + color_out = c; } diff --git a/res/shaders/simple.vert b/res/shaders/simple.vert index fbed9ca..6320aa2 100644 --- a/res/shaders/simple.vert +++ b/res/shaders/simple.vert @@ -3,8 +3,9 @@ in layout(location = 0) vec3 position; in layout(location = 1) vec3 normal; in layout(location = 2) vec2 UV; -in layout(location = 3) vec3 tangent; -in layout(location = 4) vec3 bitangent; +in layout(location = 3) vec4 color; +in layout(location = 4) vec3 tangent; +in layout(location = 5) vec3 bitangent; layout(binding = 2) uniform sampler2D displacementTexture; uniform float displacementCoefficient; @@ -13,7 +14,7 @@ uniform mat4 MVP; uniform mat4 MV; uniform mat4 MVnormal; -uniform float shinyness; +uniform float shininess; uniform vec2 uvOffset; uniform bool isIlluminated; @@ -25,8 +26,9 @@ uniform bool isInverted; out layout(location = 0) vec3 vertex_out; out layout(location = 1) vec3 normal_out; out layout(location = 2) vec2 uv_out; -out layout(location = 3) vec3 tangent_out; -out layout(location = 4) vec3 bitangent_out; +out layout(location = 3) vec4 color_out; +out layout(location = 4) vec3 tangent_out; +out layout(location = 5) vec3 bitangent_out; void main() { vec3 displacement = vec3(0.0); @@ -43,6 +45,8 @@ void main() { uv_out = UV + uvOffset; gl_Position = MVP * vec4(position+displacement, 1.0f); + color_out = color; + tangent_out = normalize(vec3(MVnormal * vec4(tangent, 1.0f))); bitangent_out = normalize(vec3(MVnormal * vec4(bitangent, 1.0f))); } diff --git a/src/gamelogic.cpp b/src/gamelogic.cpp index 2820a28..0832e49 100644 --- a/src/gamelogic.cpp +++ b/src/gamelogic.cpp @@ -132,7 +132,7 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) { plainNode->setTexture(&t_plain_diff, &t_plain_normal, &t_perlin); plainNode->setMesh(&plain); plainNode->position = {0, 0, 0}; - plainNode->shinyness = 20; + plainNode->shininess = 20; plainNode->displacementCoefficient = 40; rootNode->children.push_back(plainNode); @@ -142,7 +142,7 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) { boxNode->position = {500, 500, 40}; boxNode->referencePoint = {25, 25, 25}; boxNode->scale *= 2; - boxNode->shinyness = 20; + boxNode->shininess = 20; boxNode->displacementCoefficient = 40; rootNode->children.push_back(boxNode); @@ -258,7 +258,7 @@ void updateFrame(GLFWwindow* window, int windowWidth, int windowHeight) { // update positions of nodes (like the car) plainNode->uvOffset.x += timeDelta*0.5; plainNode->uvOffset.y -= timeDelta*0.5; - boxNode->rotation.z += timeDelta; + if (boxNode) boxNode->rotation.z += timeDelta; lightNode[1]->rotation.z -= timeDelta; } @@ -312,9 +312,11 @@ void renderNode(SceneNode* node, Gloom::Shader* parent_shader = default_shader) 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)); - glUniform1f( s->location("shinyness"), node->shinyness); + glUniform4fv(s->location("basecolor") , 1, glm::value_ptr(node->basecolor)); + glUniform1f( s->location("shininess"), node->shininess); glUniform1f( s->location("displacementCoefficient"), node->displacementCoefficient); glUniform1ui(s->location("isTextured"), node->isTextured); + glUniform1ui(s->location("isColorMapped"), node->isColorMapped); glUniform1ui(s->location("isNormalMapped"), node->isNormalMapped); glUniform1ui(s->location("isDisplacementMapped"), node->isDisplacementMapped); glUniform1ui(s->location("isIlluminated"), node->isIlluminated); @@ -330,7 +332,7 @@ void renderNode(SceneNode* node, Gloom::Shader* parent_shader = default_shader) case SPOT_LIGHT: case POINT_LIGHT: { uint id = node->lightID; - lights[id].position = vec3(node->MV * vec4(1.0)); + lights[id].position = vec3(node->MV * vec4(vec3(0.0), 1.0)); lights[id].is_spot = node->nodeType == SPOT_LIGHT; lights[id].spot_target = node->rotation; // already MV space, todo: change this lights[id].spot_cuttof_angle = glm::sin(node->spot_cuttof_angle); diff --git a/src/sceneGraph.hpp b/src/sceneGraph.hpp index cd7e1ad..cad36f0 100644 --- a/src/sceneGraph.hpp +++ b/src/sceneGraph.hpp @@ -18,6 +18,7 @@ using glm::vec2; using glm::vec3; +using glm::vec4; using glm::mat4; using std::map; using std::vector; @@ -34,17 +35,18 @@ struct SceneNode { nodeType = type; } - void setMesh(Mesh* mesh) { - static map cache; + void setMesh(const Mesh* mesh) { + static map cache; if (cache.find(mesh) == cache.end()) cache[mesh] = generateBuffer(*mesh, isNormalMapped || isDisplacementMapped); vertexArrayObjectID = cache[mesh]; VAOIndexCount = mesh->indices.size(); + isColorMapped = ! mesh->colors.empty(); } - void setTexture(PNGImage* diffuse, PNGImage* normal=nullptr, PNGImage* displacement=nullptr) { - static map cache; + void setTexture(const PNGImage* diffuse, const PNGImage* normal=nullptr, const PNGImage* displacement=nullptr) { + static map cache; assert(vertexArrayObjectID==-1); isTextured = false; isNormalMapped = false; @@ -96,7 +98,8 @@ struct SceneNode { uint VAOIndexCount = 0; // textures - float shinyness = 10.0; // specular power + float shininess = 10.0; // specular power + vec4 basecolor = vec4(1.0); vec2 uvOffset = vec2(0.0, 0.0); // specular power uint diffuseTextureID; uint normalTextureID; @@ -105,6 +108,7 @@ struct SceneNode { // shader flags bool isTextured = false; + bool isColorMapped = false; bool isNormalMapped = false; bool isDisplacementMapped = false; bool isIlluminated = true; diff --git a/src/utilities/glutils.cpp b/src/utilities/glutils.cpp index d5bf8c1..97bbdda 100644 --- a/src/utilities/glutils.cpp +++ b/src/utilities/glutils.cpp @@ -4,11 +4,12 @@ #include "glutils.h" using std::vector; +using glm::vec4; using glm::vec3; using glm::vec2; typedef unsigned int uint; -uint generateBuffer(Mesh &mesh, bool isNormalMapped) { +uint generateBuffer(const Mesh &mesh, bool doAddTangents) { uint vaoID; glGenVertexArrays(1, &vaoID); glBindVertexArray(vaoID); @@ -32,21 +33,31 @@ uint generateBuffer(Mesh &mesh, bool isNormalMapped) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID); glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size() * sizeof(uint), mesh.indices.data(), GL_STATIC_DRAW); - if (mesh.textureCoordinates.empty()) return vaoID; + if (!mesh.textureCoordinates.empty()) { + uint textureBufferID; + glGenBuffers(1, &textureBufferID); + glBindBuffer(GL_ARRAY_BUFFER, textureBufferID); + glBufferData(GL_ARRAY_BUFFER, mesh.textureCoordinates.size() * sizeof(vec2), mesh.textureCoordinates.data(), GL_STATIC_DRAW); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0); + glEnableVertexAttribArray(2); + } + + if (!mesh.colors.empty()) { + uint colorBufferID; + glGenBuffers(1, &colorBufferID); + glBindBuffer(GL_ARRAY_BUFFER, colorBufferID); + glBufferData(GL_ARRAY_BUFFER, mesh.colors.size() * sizeof(vec4), mesh.colors.data(), GL_STATIC_DRAW); + glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), 0); + glEnableVertexAttribArray(3); + } + + if (doAddTangents && !mesh.textureCoordinates.empty()) + addTangents(vaoID, mesh); - uint textureBufferID; - glGenBuffers(1, &textureBufferID); - glBindBuffer(GL_ARRAY_BUFFER, textureBufferID); - glBufferData(GL_ARRAY_BUFFER, mesh.textureCoordinates.size() * sizeof(vec2), mesh.textureCoordinates.data(), GL_STATIC_DRAW); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0); - glEnableVertexAttribArray(2); - - if (isNormalMapped) addTangents(vaoID, mesh); - return vaoID; } -void addTangents(uint vaoID, Mesh& mesh) { +void addTangents(uint vaoID, const Mesh& mesh) { vector tangents(mesh.vertices.size()); vector bitangents(mesh.vertices.size()); @@ -95,15 +106,15 @@ void addTangents(uint vaoID, Mesh& mesh) { glGenBuffers(1, &tangentBufferID); glBindBuffer(GL_ARRAY_BUFFER, tangentBufferID); glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size() * sizeof(vec3), tangents.data(), GL_STATIC_DRAW); - glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); - glEnableVertexAttribArray(3); + glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); + glEnableVertexAttribArray(4); uint bitangentBufferID; glGenBuffers(1, &bitangentBufferID); glBindBuffer(GL_ARRAY_BUFFER, bitangentBufferID); glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size() * sizeof(vec3), bitangents.data(), GL_STATIC_DRAW); - glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); - glEnableVertexAttribArray(4); + glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0); + glEnableVertexAttribArray(5); } uint generateTexture(const PNGImage& texture) { diff --git a/src/utilities/glutils.h b/src/utilities/glutils.h index 8a26b97..1583687 100644 --- a/src/utilities/glutils.h +++ b/src/utilities/glutils.h @@ -4,8 +4,8 @@ #include "imageLoader.hpp" -unsigned int generateBuffer(Mesh &mesh, bool isNormalMapped = false); +unsigned int generateBuffer(const Mesh &mesh, bool doAddTangents=false); -void addTangents(unsigned int vaoID, Mesh& mesh); +void addTangents(unsigned int vaoID, const Mesh& mesh); unsigned int generateTexture(const PNGImage& texture); diff --git a/src/utilities/mesh.h b/src/utilities/mesh.h index 00837ee..ae0bded 100644 --- a/src/utilities/mesh.h +++ b/src/utilities/mesh.h @@ -7,6 +7,7 @@ struct Mesh { std::vector vertices; std::vector normals; std::vector textureCoordinates; + std::vector colors; std::vector indices; };