Add vertex color array

This commit is contained in:
Peder Bergebakken Sundt 2019-03-18 11:48:11 +01:00
parent 86f339ef56
commit 29defbaba9
10 changed files with 82 additions and 49 deletions

3
.gitmodules vendored
View File

@ -28,3 +28,6 @@
[submodule "lib/lodepng"] [submodule "lib/lodepng"]
path = lib/lodepng path = lib/lodepng
url = https://github.com/lvandeve/lodepng url = https://github.com/lvandeve/lodepng
[submodule "lib/assimp"]
path = lib/assimp
url = git@github.com:assimp/assimp.git

View File

@ -2,7 +2,7 @@
# Specify minimum CMake version and project name # Specify minimum CMake version and project name
# #
cmake_minimum_required (VERSION 3.0) cmake_minimum_required (VERSION 3.0)
project (glowbox) project (plain_of_awesome)
# #
# CMake setup # CMake setup
@ -37,6 +37,12 @@ option (SFML_BUILD_WINDOW OFF)
option (SFML_BUILD_NETWORK OFF) option (SFML_BUILD_NETWORK OFF)
add_subdirectory(lib/SFML) 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 # Set include paths
# #
@ -47,6 +53,7 @@ include_directories (src/
lib/glm/ lib/glm/
lib/stb/ lib/stb/
lib/arrrgh/ lib/arrrgh/
lib/assimp/include/
lib/SFML/include/) lib/SFML/include/)
# #
@ -88,5 +95,6 @@ add_executable (${PROJECT_NAME} ${PROJECT_SOURCES} ${PROJECT_HEADERS}
target_link_libraries (${PROJECT_NAME} target_link_libraries (${PROJECT_NAME}
glfw glfw
sfml-audio sfml-audio
assimp
${GLFW_LIBRARIES} ${GLFW_LIBRARIES}
${GLAD_LIBRARIES}) ${GLAD_LIBRARIES})

1
lib/assimp Submodule

@ -0,0 +1 @@
Subproject commit e899067f440c79747549772fef61abe916bd496e

View File

@ -3,8 +3,9 @@
in layout(location = 0) vec3 vertex; in layout(location = 0) vec3 vertex;
in layout(location = 1) vec3 normal; in layout(location = 1) vec3 normal;
in layout(location = 2) vec2 UV; in layout(location = 2) vec2 UV;
in layout(location = 3) vec3 tangent; in layout(location = 3) vec4 color;
in layout(location = 4) vec3 bitangent; in layout(location = 4) vec3 tangent;
in layout(location = 5) vec3 bitangent;
layout(binding = 0) uniform sampler2D diffuseTexture; layout(binding = 0) uniform sampler2D diffuseTexture;
layout(binding = 1) uniform sampler2D normalTexture; layout(binding = 1) uniform sampler2D normalTexture;
@ -15,10 +16,12 @@ uniform mat4 MVP;
uniform mat4 MV; uniform mat4 MV;
uniform mat4 MVnormal; uniform mat4 MVnormal;
uniform float shinyness; uniform float shininess;
uniform vec4 basecolor;
uniform bool isIlluminated; uniform bool isIlluminated;
uniform bool isTextured; uniform bool isTextured;
uniform bool isColorMapped;
uniform bool isNormalMapped; uniform bool isNormalMapped;
uniform bool isDisplacementMapped; uniform bool isDisplacementMapped;
uniform bool isInverted; uniform bool isInverted;
@ -40,7 +43,7 @@ struct Light { // point lights, coordinates in MV space
uniform Light light[N_LIGHTS]; uniform Light light[N_LIGHTS];
out vec4 color; out vec4 color_out;
vec4 phong(vec4 basecolor) { vec4 phong(vec4 basecolor) {
@ -102,7 +105,7 @@ vec4 phong(vec4 basecolor) {
float diffuse_i = dot(nnormal, L); float diffuse_i = dot(nnormal, L);
float specular_i = dot(reflect(-L, nnormal), -normalize(vertex)); float specular_i = dot(reflect(-L, nnormal), -normalize(vertex));
specular_i = (specular_i>0) specular_i = (specular_i>0)
? pow(specular_i, shinyness) ? pow(specular_i, shininess)
: 0; : 0;
emmissive_component += light[i].color_emissive; emmissive_component += light[i].color_emissive;
@ -114,14 +117,10 @@ vec4 phong(vec4 basecolor) {
} }
void main() { void main() {
if(isIlluminated) { vec4 c = basecolor;
if (isTextured) { if (isColorMapped) c *= color;
color = phong(texture(diffuseTexture, UV)); if (isTextured) c *= texture(diffuseTexture, UV);
} else { if (isIlluminated) c = phong(c);
color = phong(vec4(1.0)); if (isInverted) c.rgb = 1 - c.rgb;
} color_out = c;
} else {
color = texture(diffuseTexture, UV);
}
if (isInverted) color.rgb = 1 - color.rgb;
} }

View File

@ -3,8 +3,9 @@
in layout(location = 0) vec3 position; in layout(location = 0) vec3 position;
in layout(location = 1) vec3 normal; in layout(location = 1) vec3 normal;
in layout(location = 2) vec2 UV; in layout(location = 2) vec2 UV;
in layout(location = 3) vec3 tangent; in layout(location = 3) vec4 color;
in layout(location = 4) vec3 bitangent; in layout(location = 4) vec3 tangent;
in layout(location = 5) vec3 bitangent;
layout(binding = 2) uniform sampler2D displacementTexture; layout(binding = 2) uniform sampler2D displacementTexture;
uniform float displacementCoefficient; uniform float displacementCoefficient;
@ -13,7 +14,7 @@ uniform mat4 MVP;
uniform mat4 MV; uniform mat4 MV;
uniform mat4 MVnormal; uniform mat4 MVnormal;
uniform float shinyness; uniform float shininess;
uniform vec2 uvOffset; uniform vec2 uvOffset;
uniform bool isIlluminated; uniform bool isIlluminated;
@ -25,8 +26,9 @@ uniform bool isInverted;
out layout(location = 0) vec3 vertex_out; out layout(location = 0) vec3 vertex_out;
out layout(location = 1) vec3 normal_out; out layout(location = 1) vec3 normal_out;
out layout(location = 2) vec2 uv_out; out layout(location = 2) vec2 uv_out;
out layout(location = 3) vec3 tangent_out; out layout(location = 3) vec4 color_out;
out layout(location = 4) vec3 bitangent_out; out layout(location = 4) vec3 tangent_out;
out layout(location = 5) vec3 bitangent_out;
void main() { void main() {
vec3 displacement = vec3(0.0); vec3 displacement = vec3(0.0);
@ -43,6 +45,8 @@ void main() {
uv_out = UV + uvOffset; uv_out = UV + uvOffset;
gl_Position = MVP * vec4(position+displacement, 1.0f); gl_Position = MVP * vec4(position+displacement, 1.0f);
color_out = color;
tangent_out = normalize(vec3(MVnormal * vec4(tangent, 1.0f))); tangent_out = normalize(vec3(MVnormal * vec4(tangent, 1.0f)));
bitangent_out = normalize(vec3(MVnormal * vec4(bitangent, 1.0f))); bitangent_out = normalize(vec3(MVnormal * vec4(bitangent, 1.0f)));
} }

View File

@ -132,7 +132,7 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) {
plainNode->setTexture(&t_plain_diff, &t_plain_normal, &t_perlin); plainNode->setTexture(&t_plain_diff, &t_plain_normal, &t_perlin);
plainNode->setMesh(&plain); plainNode->setMesh(&plain);
plainNode->position = {0, 0, 0}; plainNode->position = {0, 0, 0};
plainNode->shinyness = 20; plainNode->shininess = 20;
plainNode->displacementCoefficient = 40; plainNode->displacementCoefficient = 40;
rootNode->children.push_back(plainNode); rootNode->children.push_back(plainNode);
@ -142,7 +142,7 @@ void initGame(GLFWwindow* window, CommandLineOptions gameOptions) {
boxNode->position = {500, 500, 40}; boxNode->position = {500, 500, 40};
boxNode->referencePoint = {25, 25, 25}; boxNode->referencePoint = {25, 25, 25};
boxNode->scale *= 2; boxNode->scale *= 2;
boxNode->shinyness = 20; boxNode->shininess = 20;
boxNode->displacementCoefficient = 40; boxNode->displacementCoefficient = 40;
rootNode->children.push_back(boxNode); rootNode->children.push_back(boxNode);
@ -258,7 +258,7 @@ void updateFrame(GLFWwindow* window, int windowWidth, int windowHeight) {
// update positions of nodes (like the car) // update positions of nodes (like the car)
plainNode->uvOffset.x += timeDelta*0.5; plainNode->uvOffset.x += timeDelta*0.5;
plainNode->uvOffset.y -= timeDelta*0.5; plainNode->uvOffset.y -= timeDelta*0.5;
boxNode->rotation.z += timeDelta; if (boxNode) boxNode->rotation.z += timeDelta;
lightNode[1]->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("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));
glUniform2fv(s->location("uvOffset") , 1, glm::value_ptr(node->uvOffset)); 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); glUniform1f( s->location("displacementCoefficient"), node->displacementCoefficient);
glUniform1ui(s->location("isTextured"), node->isTextured); glUniform1ui(s->location("isTextured"), node->isTextured);
glUniform1ui(s->location("isColorMapped"), node->isColorMapped);
glUniform1ui(s->location("isNormalMapped"), node->isNormalMapped); glUniform1ui(s->location("isNormalMapped"), node->isNormalMapped);
glUniform1ui(s->location("isDisplacementMapped"), node->isDisplacementMapped); glUniform1ui(s->location("isDisplacementMapped"), node->isDisplacementMapped);
glUniform1ui(s->location("isIlluminated"), node->isIlluminated); glUniform1ui(s->location("isIlluminated"), node->isIlluminated);
@ -330,7 +332,7 @@ void renderNode(SceneNode* node, Gloom::Shader* parent_shader = default_shader)
case SPOT_LIGHT: case SPOT_LIGHT:
case POINT_LIGHT: { case POINT_LIGHT: {
uint id = node->lightID; 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].is_spot = node->nodeType == SPOT_LIGHT;
lights[id].spot_target = node->rotation; // already MV space, todo: change this lights[id].spot_target = node->rotation; // already MV space, todo: change this
lights[id].spot_cuttof_angle = glm::sin(node->spot_cuttof_angle); lights[id].spot_cuttof_angle = glm::sin(node->spot_cuttof_angle);

View File

@ -18,6 +18,7 @@
using glm::vec2; using glm::vec2;
using glm::vec3; using glm::vec3;
using glm::vec4;
using glm::mat4; using glm::mat4;
using std::map; using std::map;
using std::vector; using std::vector;
@ -34,17 +35,18 @@ struct SceneNode {
nodeType = type; nodeType = type;
} }
void setMesh(Mesh* mesh) { void setMesh(const Mesh* mesh) {
static map<Mesh*, int> cache; static map<const Mesh*, int> cache;
if (cache.find(mesh) == cache.end()) if (cache.find(mesh) == cache.end())
cache[mesh] = generateBuffer(*mesh, isNormalMapped || isDisplacementMapped); cache[mesh] = generateBuffer(*mesh, isNormalMapped || isDisplacementMapped);
vertexArrayObjectID = cache[mesh]; vertexArrayObjectID = cache[mesh];
VAOIndexCount = mesh->indices.size(); VAOIndexCount = mesh->indices.size();
isColorMapped = ! mesh->colors.empty();
} }
void setTexture(PNGImage* diffuse, PNGImage* normal=nullptr, PNGImage* displacement=nullptr) { void setTexture(const PNGImage* diffuse, const PNGImage* normal=nullptr, const PNGImage* displacement=nullptr) {
static map<PNGImage*, int> cache; static map<const PNGImage*, int> cache;
assert(vertexArrayObjectID==-1); assert(vertexArrayObjectID==-1);
isTextured = false; isTextured = false;
isNormalMapped = false; isNormalMapped = false;
@ -96,7 +98,8 @@ struct SceneNode {
uint VAOIndexCount = 0; uint VAOIndexCount = 0;
// textures // 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 vec2 uvOffset = vec2(0.0, 0.0); // specular power
uint diffuseTextureID; uint diffuseTextureID;
uint normalTextureID; uint normalTextureID;
@ -105,6 +108,7 @@ struct SceneNode {
// shader flags // shader flags
bool isTextured = false; bool isTextured = false;
bool isColorMapped = false;
bool isNormalMapped = false; bool isNormalMapped = false;
bool isDisplacementMapped = false; bool isDisplacementMapped = false;
bool isIlluminated = true; bool isIlluminated = true;

View File

@ -4,11 +4,12 @@
#include "glutils.h" #include "glutils.h"
using std::vector; using std::vector;
using glm::vec4;
using glm::vec3; using glm::vec3;
using glm::vec2; using glm::vec2;
typedef unsigned int uint; typedef unsigned int uint;
uint generateBuffer(Mesh &mesh, bool isNormalMapped) { uint generateBuffer(const Mesh &mesh, bool doAddTangents) {
uint vaoID; uint vaoID;
glGenVertexArrays(1, &vaoID); glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID); glBindVertexArray(vaoID);
@ -32,21 +33,31 @@ uint generateBuffer(Mesh &mesh, bool isNormalMapped) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size() * sizeof(uint), mesh.indices.data(), GL_STATIC_DRAW); 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; uint textureBufferID;
glGenBuffers(1, &textureBufferID); glGenBuffers(1, &textureBufferID);
glBindBuffer(GL_ARRAY_BUFFER, textureBufferID); glBindBuffer(GL_ARRAY_BUFFER, textureBufferID);
glBufferData(GL_ARRAY_BUFFER, mesh.textureCoordinates.size() * sizeof(vec2), mesh.textureCoordinates.data(), GL_STATIC_DRAW); 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); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0);
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
}
if (isNormalMapped) addTangents(vaoID, mesh); 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);
return vaoID; return vaoID;
} }
void addTangents(uint vaoID, Mesh& mesh) { void addTangents(uint vaoID, const Mesh& mesh) {
vector<vec3> tangents(mesh.vertices.size()); vector<vec3> tangents(mesh.vertices.size());
vector<vec3> bitangents(mesh.vertices.size()); vector<vec3> bitangents(mesh.vertices.size());
@ -95,15 +106,15 @@ void addTangents(uint vaoID, Mesh& mesh) {
glGenBuffers(1, &tangentBufferID); glGenBuffers(1, &tangentBufferID);
glBindBuffer(GL_ARRAY_BUFFER, tangentBufferID); glBindBuffer(GL_ARRAY_BUFFER, tangentBufferID);
glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size() * sizeof(vec3), tangents.data(), GL_STATIC_DRAW); 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); glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glEnableVertexAttribArray(3); glEnableVertexAttribArray(4);
uint bitangentBufferID; uint bitangentBufferID;
glGenBuffers(1, &bitangentBufferID); glGenBuffers(1, &bitangentBufferID);
glBindBuffer(GL_ARRAY_BUFFER, bitangentBufferID); glBindBuffer(GL_ARRAY_BUFFER, bitangentBufferID);
glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size() * sizeof(vec3), bitangents.data(), GL_STATIC_DRAW); 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); glVertexAttribPointer(5, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glEnableVertexAttribArray(4); glEnableVertexAttribArray(5);
} }
uint generateTexture(const PNGImage& texture) { uint generateTexture(const PNGImage& texture) {

View File

@ -4,8 +4,8 @@
#include "imageLoader.hpp" #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); unsigned int generateTexture(const PNGImage& texture);

View File

@ -7,6 +7,7 @@ struct Mesh {
std::vector<glm::vec3> vertices; std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals; std::vector<glm::vec3> normals;
std::vector<glm::vec2> textureCoordinates; std::vector<glm::vec2> textureCoordinates;
std::vector<glm::vec4> colors;
std::vector<unsigned int> indices; std::vector<unsigned int> indices;
}; };