Revamped model loading interface.

This commit is contained in:
2014-03-11 13:27:01 +01:00
parent c0c1cf113e
commit fb471aae51
14 changed files with 124 additions and 53 deletions
+2 -7
View File
@@ -1,17 +1,12 @@
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <GL/glew.h> #include "Renderer.h"
#define GLFW_INCLUDE_GLU #include "GameWorld.h"
#include <GLFW/glfw3.h>
#include <glext.h>
#include "logging.h" #include "logging.h"
#include "glerror.h" #include "glerror.h"
#include "Renderer.h"
#include "GameWorld.h"
class Engine class Engine
{ {
public: public:
+2 -2
View File
@@ -40,7 +40,7 @@
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LibraryPath>$(SolutionDir)\Libraries\openal-soft-1.15.1-bin\lib\Win32\Debug;$(SolutionDir)\Libraries\SOIL\lib\Debug;$(SolutionDir)\Libraries\glew-1.10.0\lib\Debug\Win32;$(SolutionDir)\Libraries\glfw-3.0.4\lib\Debug;$(LibraryPath)</LibraryPath> <LibraryPath>$(BOOST_ROOT)\lib32-msvc-11.0;$(SolutionDir)\Libraries\openal-soft-1.15.1-bin\lib\Win32\Debug;$(SolutionDir)\Libraries\SOIL\lib\Debug;$(SolutionDir)\Libraries\glew-1.10.0\lib\Debug\Win32;$(SolutionDir)\Libraries\glfw-3.0.4\lib\Debug;$(LibraryPath)</LibraryPath>
<OutDir>$(SolutionDir)bin\</OutDir> <OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>$(SolutionDir)obj\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)obj\$(ProjectName)\</IntDir>
<TargetName>$(ProjectName)-$(Configuration)</TargetName> <TargetName>$(ProjectName)-$(Configuration)</TargetName>
@@ -50,7 +50,7 @@
<IncludePath>$(BOOST_ROOT);$(SolutionDir)\Libraries\openal-soft-1.15.1-bin\include;$(SolutionDir)\Libraries\SOIL\src;$(ProjectDir);$(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(IncludePath)</IncludePath> <IncludePath>$(BOOST_ROOT);$(SolutionDir)\Libraries\openal-soft-1.15.1-bin\include;$(SolutionDir)\Libraries\SOIL\src;$(ProjectDir);$(SolutionDir)\Libraries;$(SolutionDir)\Libraries\glew-1.10.0\include;$(SolutionDir)\Libraries\glfw-3.0.4\include;$(SolutionDir)\Libraries\glm-0.9.5.2;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LibraryPath>$(SolutionDir)\Libraries\openal-soft-1.15.1-bin\lib\Win32\Release;$(SolutionDir)\Libraries\SOIL\lib\Release;$(SolutionDir)\Libraries\glew-1.10.0\lib\Release\Win32;$(SolutionDir)\Libraries\glfw-3.0.4\lib\Release;$(LibraryPath)</LibraryPath> <LibraryPath>$(BOOST_ROOT)\lib32-msvc-11.0;$(SolutionDir)\Libraries\openal-soft-1.15.1-bin\lib\Win32\Release;$(SolutionDir)\Libraries\SOIL\lib\Release;$(SolutionDir)\Libraries\glew-1.10.0\lib\Release\Win32;$(SolutionDir)\Libraries\glfw-3.0.4\lib\Release;$(LibraryPath)</LibraryPath>
<OutDir>$(SolutionDir)bin\</OutDir> <OutDir>$(SolutionDir)bin\</OutDir>
<IntDir>$(SolutionDir)obj\$(ProjectName)\</IntDir> <IntDir>$(SolutionDir)obj\$(ProjectName)\</IntDir>
<TargetName>$(ProjectName)-$(Configuration)</TargetName> <TargetName>$(ProjectName)-$(Configuration)</TargetName>
+45 -2
View File
@@ -3,12 +3,55 @@
Model::Model(const char* path) Model::Model(const char* path)
{ {
Loadobj(path, Vertices, Normals, TextureCoords); Loadobj(path, Vertices, Normals, TextureCoords);
CreateBuffers(Vertices, Normals, TextureCoords); CreateBuffers(Vertices, Normals, TextureCoords);
} }
Model::Model(OBJ &obj)
{
OBJ::MaterialInfo* currentMaterial = nullptr;
TextureGroup* currentTexGroup = nullptr;
int index = 0;
for (auto face : obj.Faces) {
// New material
if (face.Material != currentMaterial) {
currentMaterial = face.Material;
// Load texture
std::shared_ptr<Texture> texture = std::make_shared<Texture>(currentMaterial->TextureFile);
// TODO: Load material parameters
// Create new texture group (start index of new group is upcoming index)
TextureGroup texGroup = { texture, index, index };
TextureGroups.push_back(texGroup);
currentTexGroup = &TextureGroups.back();
}
// Face definitions
for (auto faceDef : face.Definitions) {
glm::vec3 vertex;
std::tie(vertex.x, vertex.y, vertex.z) = obj.Vertices.at(faceDef.VertexIndex - 1);
Vertices.push_back(vertex);
if (faceDef.NormalIndex != 0) {
glm::vec3 normal;
std::tie(normal.x, normal.y, normal.z) = obj.Normals.at(faceDef.NormalIndex - 1);
Normals.push_back(normal);
}
if (faceDef.TextureCoordIndex != 0) {
glm::vec2 texCoord;
// TODO: W-coord?
std::tie(texCoord.x, texCoord.y, std::ignore) = obj.TextureCoords.at(faceDef.TextureCoordIndex - 1);
TextureCoords.push_back(texCoord);
}
currentTexGroup->EndIndex = index;
index++;
}
}
CreateBuffers(Vertices, Normals, TextureCoords);
}
bool Model::Loadobj(const char* path, std::vector <glm::vec3> & out_vertices, std::vector <glm::vec3> &out_normals, std::vector <glm::vec2> & out_TextureCoords) bool Model::Loadobj(const char* path, std::vector <glm::vec3> & out_vertices, std::vector <glm::vec3> &out_normals, std::vector <glm::vec2> & out_TextureCoords)
{ {
std::vector< unsigned int > vertexIndices, TextureCoordIndices, normalIndices; std::vector< unsigned int > vertexIndices, TextureCoordIndices, normalIndices;
+22 -9
View File
@@ -8,7 +8,6 @@
#include <vector> #include <vector>
#include <memory> #include <memory>
#define _CRT_SECURE_NO_WARNINGS
#include <GL/glew.h> #include <GL/glew.h>
#define GLFW_INCLUDE_GLU #define GLFW_INCLUDE_GLU
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@@ -19,26 +18,42 @@
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include "glerror.h"
#include <cstdlib> #include <cstdlib>
#include <stack>
#include "glerror.h"
#include "Texture.h" #include "Texture.h"
#include "OBJ.h"
class Model class Model
{ {
public: public:
Model(OBJ &obj);
Model(const char* path);
struct TextureGroup
{
std::shared_ptr<Texture> Texture;
unsigned int StartIndex;
unsigned int EndIndex;
};
GLuint VAO;
std::vector<TextureGroup> TextureGroups;
std::vector<std::shared_ptr<Texture>> texture;
glm::mat4 GetMatrix();
std::vector<glm::vec3> Vertices; std::vector<glm::vec3> Vertices;
private:
std::vector<glm::vec3> Normals; std::vector<glm::vec3> Normals;
std::vector<glm::vec2> TextureCoords; std::vector<glm::vec2> TextureCoords;
GLuint VertexBuffer; GLuint VertexBuffer;
GLuint NormalBuffer; GLuint NormalBuffer;
GLuint TextureCoordBuffer; GLuint TextureCoordBuffer;
GLuint VAO;
std::vector<std::shared_ptr<Texture>> texture;
Model(const char* path);
bool Loadobj( bool Loadobj(
const char* path, const char* path,
@@ -47,8 +62,6 @@ public:
std::vector <glm::vec2> & out_TextureCoords std::vector <glm::vec2> & out_TextureCoords
); );
glm::mat4 GetMatrix();
void CreateBuffers( void CreateBuffers(
std::vector<glm::vec3> _Vertices, std::vector<glm::vec3> _Vertices,
std::vector<glm::vec3> _Normals, std::vector<glm::vec3> _Normals,
+18 -5
View File
@@ -5,13 +5,18 @@ OBJ::OBJ()
m_CurrentMaterial = nullptr; m_CurrentMaterial = nullptr;
} }
void OBJ::LoadFromFile(std::string filename) bool OBJ::LoadFromFile(std::string filename)
{ {
m_Path = boost::filesystem::path(filename); m_Path = boost::filesystem::path(filename);
LOG_INFO("Parsing .obj \"%s\"", m_Path.c_str());
// http://paulbourke.net/dataformats/obj/ // http://paulbourke.net/dataformats/obj/
std::ifstream file(m_Path.string()); std::ifstream file(m_Path.string());
if (!file.is_open()) {
LOG_ERROR("Failed to open .obj \"%s\"", m_Path.string().c_str());
return false;
}
LOG_INFO("Parsing .obj \"%s\"", m_Path.string().c_str());
std::string line; std::string line;
while (std::getline(file, line)) { while (std::getline(file, line)) {
@@ -74,7 +79,7 @@ void OBJ::LoadFromFile(std::string filename)
std::string faceDefString; std::string faceDefString;
while (ss >> faceDefString) { while (ss >> faceDefString) {
std::stringstream ss2(faceDefString); std::stringstream ss2(faceDefString);
FaceDefinition faceDef = { -1, -1, -1 }; FaceDefinition faceDef = { 0, 0, 0 };
ss2 >> faceDef.VertexIndex; ss2 >> faceDef.VertexIndex;
ss2.ignore(); // Ignore first delimiter ss2.ignore(); // Ignore first delimiter
@@ -94,13 +99,21 @@ void OBJ::LoadFromFile(std::string filename)
Faces.push_back(face); Faces.push_back(face);
} }
} }
return true;
} }
void OBJ::ParseMaterial() void OBJ::ParseMaterial()
{ {
// http://paulbourke.net/dataformats/mtl/ // http://paulbourke.net/dataformats/mtl/
std::ifstream file(m_MaterialPath.string()); std::ifstream file(m_MaterialPath.string());
if (!file.is_open()) {
LOG_ERROR("Failed to open .mtl \"%s\"", m_MaterialPath.string().c_str());
return;
}
LOG_INFO("Parsing .mtl \"%s\"", m_MaterialPath.string().c_str());
std::string currentMaterialName; std::string currentMaterialName;
MaterialInfo* currentMaterial = nullptr; MaterialInfo* currentMaterial = nullptr;
@@ -130,7 +143,7 @@ void OBJ::ParseMaterial()
}; };
ss >> currentMaterialName; ss >> currentMaterialName;
LOG_INFO("Parsing material %s", currentMaterialName); LOG_INFO("Parsing material %s", currentMaterialName.c_str());
Materials[currentMaterialName] = mat; Materials[currentMaterialName] = mat;
currentMaterial = &Materials[currentMaterialName]; currentMaterial = &Materials[currentMaterialName];
continue; continue;
+1 -1
View File
@@ -51,7 +51,7 @@ public:
std::vector<Face> Faces; std::vector<Face> Faces;
std::map<std::string, MaterialInfo> Materials; std::map<std::string, MaterialInfo> Materials;
void LoadFromFile(std::string filename); bool LoadFromFile(std::string filename);
private: private:
boost::filesystem::path m_Path; boost::filesystem::path m_Path;
+15 -9
View File
@@ -49,7 +49,7 @@ void Renderer::Initialize()
LoadContent(); LoadContent();
} }
void Renderer::Draw(double _dt) void Renderer::Draw(double dt)
{ {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(1.0f, 1.0f, 0.0f, 1.0f); glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
@@ -59,21 +59,27 @@ void Renderer::Draw(double _dt)
glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix(); glm::mat4 cameraMatrix = m_Camera->ProjectionMatrix() * m_Camera->ViewMatrix();
glm::mat4 MVP; glm::mat4 MVP;
for(int i = 0; i < ModelsToRender.size(); i++) for (int i = 0; i < ModelsToRender.size(); i++)
{ {
glActiveTexture(GL_TEXTURE0); ModelData* modelData = ModelsToRender.at(i);
glBindTexture(GL_TEXTURE_2D, ModelsToRender[i]->model->texture[0]->texture); auto model = modelData->model;
MVP = cameraMatrix * ModelsToRender[i]->ModelMatrix;
MVP = cameraMatrix * modelData->ModelMatrix;
glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "MVP"), 1, GL_FALSE, glm::value_ptr(MVP));
glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "model"), 1, GL_FALSE, glm::value_ptr(ModelsToRender[i]->ModelMatrix)); glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "model"), 1, GL_FALSE, glm::value_ptr(modelData->ModelMatrix));
glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "view"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix())); glUniformMatrix4fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "view"), 1, GL_FALSE, glm::value_ptr(m_Camera->ViewMatrix()));
glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "lightPosition"), 1, glm::value_ptr(glm::vec3(2.0f, 4.0f, 1.0f))); glUniform3fv(glGetUniformLocation(m_ShaderProgram.GetHandle(), "lightPosition"), 1, glm::value_ptr(glm::vec3(2.0f, 4.0f, 1.0f)));
glUniform1f(glGetUniformLocation(m_ShaderProgram.GetHandle(), "constantAttenuation"), 1.5f); glUniform1f(glGetUniformLocation(m_ShaderProgram.GetHandle(), "constantAttenuation"), 1.5f);
glUniform1f(glGetUniformLocation(m_ShaderProgram.GetHandle(), "linearAttenuation"), 0.0f); glUniform1f(glGetUniformLocation(m_ShaderProgram.GetHandle(), "linearAttenuation"), 0.0f);
glUniform1f(glGetUniformLocation(m_ShaderProgram.GetHandle(), "quadraticAttenuation"), 0.0f); glUniform1f(glGetUniformLocation(m_ShaderProgram.GetHandle(), "quadraticAttenuation"), 0.0f);
glBindVertexArray(ModelsToRender[i]->model->VAO);
glDrawArrays(GL_TRIANGLES, 0, ModelsToRender[i]->model->Vertices.size());
glBindVertexArray(model->VAO);
for (auto texGroup : model->TextureGroups) {
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texGroup.Texture->texture);
glDrawArrays(GL_TRIANGLES, texGroup.StartIndex, (texGroup.EndIndex - texGroup.StartIndex + 1) * abs(sin(glfwGetTime())));
}
} }
ModelsToRender.clear(); ModelsToRender.clear();
@@ -90,7 +96,7 @@ void Renderer::AddTextToDraw()
//Add to draw shit vector //Add to draw shit vector
} }
void Renderer::AddModelToDraw(Model* _model, glm::vec3 _position, glm::quat _orientation) void Renderer::AddModelToDraw(std::shared_ptr<Model> _model, glm::vec3 _position, glm::quat _orientation)
{ {
glm::mat4 RotationMatrix = glm::toMat4(_orientation); glm::mat4 RotationMatrix = glm::toMat4(_orientation);
glm::mat4 ModelMatrix = glm::translate(glm::mat4(), _position) * RotationMatrix ; glm::mat4 ModelMatrix = glm::translate(glm::mat4(), _position) * RotationMatrix ;
+4 -5
View File
@@ -7,7 +7,6 @@
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#define _CRT_SECURE_NO_WARNINGS
#include <GL/glew.h> #include <GL/glew.h>
#define GLFW_INCLUDE_GLU #define GLFW_INCLUDE_GLU
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@@ -36,10 +35,10 @@ public:
struct ModelData struct ModelData
{ {
Model* model; std::shared_ptr<Model> model;
glm::mat4 ModelMatrix; glm::mat4 ModelMatrix;
ModelData(Model* _model, glm::mat4 _modelMatrix) : model(_model), ModelMatrix(_modelMatrix) ModelData(std::shared_ptr<Model> _model, glm::mat4 _modelMatrix)
{} : model(_model), ModelMatrix(_modelMatrix) {}
}; };
std::vector<ModelData*> ModelsToRender; std::vector<ModelData*> ModelsToRender;
@@ -50,7 +49,7 @@ public:
void Draw(double dt); void Draw(double dt);
void DrawText(); void DrawText();
void AddModelToDraw(Model*, glm::vec3, glm::quat); void AddModelToDraw(std::shared_ptr<Model> model, glm::vec3 position, glm::quat orientation);
void AddTextToDraw(); void AddTextToDraw();
void LoadContent(); void LoadContent();
Binary file not shown.
+7 -5
View File
@@ -15,16 +15,20 @@ void Systems::RenderSystem::UpdateEntity( double dt, EntityID entity, EntityID p
auto transformComponent = m_World->GetComponent<Components::Transform>(entity, "Transform"); auto transformComponent = m_World->GetComponent<Components::Transform>(entity, "Transform");
if (transformComponent == nullptr) if (transformComponent == nullptr)
return; return;
// Draw models
auto modelComponent = m_World->GetComponent<Components::Model>(entity, "Model"); auto modelComponent = m_World->GetComponent<Components::Model>(entity, "Model");
if (modelComponent != nullptr) if (modelComponent != nullptr)
{ {
if (m_CachedModels.find(modelComponent->ModelFile) == m_CachedModels.end()){ if (m_CachedModels.find(modelComponent->ModelFile) == m_CachedModels.end()){
m_CachedModels[modelComponent->ModelFile] = new Model(modelComponent->ModelFile); m_CachedModels[modelComponent->ModelFile] = std::make_shared<Model>(OBJ(modelComponent->ModelFile));
} }
Model* model = m_CachedModels[modelComponent->ModelFile]; auto model = m_CachedModels[modelComponent->ModelFile];
m_Renderer->AddModelToDraw(model, transformComponent->Position, transformComponent->Orientation); m_Renderer->AddModelToDraw(model, transformComponent->Position, transformComponent->Orientation);
} }
// Update camera
auto cameraComponent = m_World->GetComponent<Components::Camera>(entity, "Camera"); auto cameraComponent = m_World->GetComponent<Components::Camera>(entity, "Camera");
if (cameraComponent != nullptr) if (cameraComponent != nullptr)
{ {
@@ -35,8 +39,6 @@ void Systems::RenderSystem::UpdateEntity( double dt, EntityID entity, EntityID p
m_Renderer->GetCamera()->NearClip(cameraComponent->NearClip); m_Renderer->GetCamera()->NearClip(cameraComponent->NearClip);
m_Renderer->GetCamera()->FarClip(cameraComponent->FarClip); m_Renderer->GetCamera()->FarClip(cameraComponent->FarClip);
} }
} }
+1 -1
View File
@@ -19,7 +19,7 @@ namespace Systems
RenderSystem(World* world, std::shared_ptr<Renderer> renderer) RenderSystem(World* world, std::shared_ptr<Renderer> renderer)
: System(world), m_Renderer(renderer) {} : System(world), m_Renderer(renderer) {}
std::unordered_map<std::string, Model*> m_CachedModels; std::unordered_map<std::string, std::shared_ptr<Model>> m_CachedModels;
void OnComponentCreated(std::string type, std:: shared_ptr<Component> component) override; void OnComponentCreated(std::string type, std:: shared_ptr<Component> component) override;
void UpdateEntity(double dt, EntityID entity, EntityID parent) override; void UpdateEntity(double dt, EntityID entity, EntityID parent) override;
+3 -3
View File
@@ -1,14 +1,14 @@
#include "Texture.h" #include "Texture.h"
Texture::Texture( const char* path ) Texture::Texture(std::string path)
{ {
Load(path); Load(path);
} }
void Texture::Load( const char* path ) void Texture::Load(std::string path)
{ {
texture = SOIL_load_OGL_texture(path, 0, 0, SOIL_FLAG_INVERT_Y); texture = SOIL_load_OGL_texture(path.c_str(), 0, 0, SOIL_FLAG_INVERT_Y);
} }
void Texture::Bind() void Texture::Bind()
+4 -2
View File
@@ -1,6 +1,8 @@
#ifndef Texture_h__ #ifndef Texture_h__
#define Texture_h__ #define Texture_h__
#include <string>
#include <GL/glew.h> #include <GL/glew.h>
#define GLFW_INCLUDE_GLU #define GLFW_INCLUDE_GLU
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
@@ -10,13 +12,13 @@
class Texture class Texture
{ {
public: public:
Texture(const char* path); Texture(std::string path);
~Texture(); ~Texture();
GLuint texture; GLuint texture;
void Load(const char* path); void Load(std::string path);
void Bind(); void Bind();
}; };
-2
View File
@@ -1,8 +1,6 @@
#ifndef _GLERROR_H #ifndef _GLERROR_H
#define _GLERROR_H #define _GLERROR_H
#define GLFW_INCLUDE_GLU
#include <GLFW\glfw3.h>
#include <iostream> #include <iostream>
#include "logging.h" #include "logging.h"