From 91a34e28c514394593b54947c86df9dab98e10f2 Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Tue, 11 Oct 2022 22:03:17 +0200 Subject: [PATCH] Add basic texturing support for gltf --- data/shaders/basic.frag | 213 +++++------------------- src/Controller.cpp | 31 +++- src/Controller.h | 2 + src/Entity.h | 1 - src/FrameBuffer.h | 3 +- src/Light.cpp | 10 +- src/Mesh.cpp | 20 +-- src/Mesh.h | 6 +- src/Scene.cpp | 5 - src/VertexArray.cpp | 115 ++++++++++--- src/VertexArray.h | 10 ++ src/resources/AbstractTexture.h | 1 - src/resources/CubeMap.cpp | 46 ++---- src/resources/CubeMap.h | 10 -- src/resources/Resource.cpp | 5 - src/resources/Resource.h | 8 +- src/resources/ResourceHandler.cpp | 31 ---- src/resources/ResourceHandler.h | 1 - src/resources/Texture.cpp | 108 ++++++++----- src/resources/Texture.h | 30 ++-- src/resources/TextureType.h | 3 - tools/CMakeLists.txt | 3 - tools/fileformat.txt | 29 ---- tools/main.cpp | 261 ------------------------------ tools/primitiveModel.h | 25 --- 25 files changed, 281 insertions(+), 696 deletions(-) delete mode 100644 tools/CMakeLists.txt delete mode 100644 tools/fileformat.txt delete mode 100644 tools/main.cpp delete mode 100644 tools/primitiveModel.h diff --git a/data/shaders/basic.frag b/data/shaders/basic.frag index 4805a70..ca5de6e 100644 --- a/data/shaders/basic.frag +++ b/data/shaders/basic.frag @@ -10,62 +10,35 @@ in vec4 v_fragmentPositionDirectionalLightSpace; in vec3 v_lightDirectionTangent; in vec3 v_lightPositionTangent0; -//in vec3 v_lightPositionTangent1; -//in vec3 v_lightPositionTangent2; -//in vec3 v_lightPositionTangent3; in vec3 v_viewPositionTangent; -struct Material { - sampler2D texture_diffuse0; - sampler2D texture_diffuse1; - sampler2D texture_specular0; - sampler2D texture_normal0; - sampler2D texture_height0; - sampler2D texture_gloss0; - float shininess; +struct Material +{ + sampler2D texture_diffuse; + sampler2D texture_normal; }; uniform Material u_material; -struct DirectionalLight { +struct DirectionalLight +{ vec3 direction; bool isActive; vec3 color; }; uniform DirectionalLight u_directionalLight; -struct PointLight { +struct PointLight +{ vec3 position; bool isActive; vec3 color; }; + #define NUM_POINT_LIGHTS 1 uniform PointLight u_pointLight[NUM_POINT_LIGHTS]; -/*struct SpotLight { - bool isActive; - vec3 position; - vec3 direction; - - float innerCutOff; - float outerCutOff; - - float K_q; - - vec3 ambient; - vec3 diffuse; - vec3 specular; -}; -uniform SpotLight u_spotLight;*/ - -uniform mat3 u_normalMatrix; - -// uniform sampler2D u_texture_directionalShadowMap; -// uniform samplerCube u_texture_pointShadowMap0; -//uniform samplerCube u_texture_pointShadowMap1; -//uniform samplerCube u_texture_pointShadowMap2; -//uniform samplerCube u_texture_pointShadowMap3; - +// clang-format off vec3 sampleOffsetDirections[20] = vec3[] ( vec3( 1, 1, 1), vec3( 1, -1, 1), vec3(-1, -1, 1), vec3(-1, 1, 1), vec3( 1, 1, -1), vec3( 1, -1, -1), vec3(-1, -1, -1), vec3(-1, 1, -1), @@ -73,54 +46,42 @@ vec3 sampleOffsetDirections[20] = vec3[] ( vec3( 1, 0, 1), vec3(-1, 0, 1), vec3( 1, 0, -1), vec3(-1, 0, -1), vec3( 0, 1, 1), vec3( 0, -1, 1), vec3( 0, -1, -1), vec3( 0, 1, -1) ); - -// uniform bool b_drawShadows; - -// uniform float pointShadowDepthMapFarPlane; +// clang-format on vec3 directionalLightContribution(DirectionalLight light, vec3 normal, vec3 viewDir); vec3 pointLightContribution(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir); -//vec3 spotLightContribution(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir); -void computeShading( - vec3 light_ambient, vec3 light_diffuse, vec3 light_specular, - vec3 lightDir, vec3 viewDir, vec3 normal, - out vec3 ambient, out vec3 diffuse, out vec3 specular -); +void computeShading(vec3 light_ambient, vec3 light_diffuse, vec3 light_specular, vec3 lightDir, vec3 viewDir, + vec3 normal, out vec3 ambient, out vec3 diffuse, out vec3 specular); float computeAttenuation(vec3 lightPos, vec3 fragPos, float K_q); -// float computeDirectionalShadows(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir); -// float computePointShadows(vec3 fragPos, vec3 lightPos); - -void main() { - +void main() +{ vec3 fragmentColor = vec3(0.0f); - vec3 normal = texture(u_material.texture_normal0, v_texCoord).rgb; + vec3 normal = texture(u_material.texture_normal, v_texCoord).rgb; normal = normalize(normal * 2.0 - 1.0); vec3 viewDir = normalize(v_viewPositionTangent - v_fragmentPositionTangent); fragmentColor += directionalLightContribution(u_directionalLight, normal, viewDir); - for(int i = 0; i < NUM_POINT_LIGHTS; i++) { + for (int i = 0; i < NUM_POINT_LIGHTS; i++) { fragmentColor += pointLightContribution(u_pointLight[i], normal, v_fragmentPositionTangent, viewDir); } - // There are currently no spotlights - //fragmentColor += spotLightContribution(u_spotLight, normal, v_fragmentPositionTangent, viewDir); + // fragmentColor = (v_normal + 1.0f) * 0.5f; + fragmentColor = vec3(texture(u_material.texture_diffuse, v_texCoord)); f_color = vec4(fragmentColor, 1.0f); - f_color = vec4(0.95f, 0.16f, 0.33f, 1.0f); } -vec3 directionalLightContribution(DirectionalLight light, vec3 normal, vec3 viewDir) { - +vec3 directionalLightContribution(DirectionalLight light, vec3 normal, vec3 viewDir) +{ // Only compute if light source is active - if(!light.isActive) + if (!light.isActive) return vec3(0.0f); - //vec3 lightDir = normalize(-light.direction); vec3 lightDir = normalize(-v_lightDirectionTangent); vec3 diffuseColor = light.color; @@ -130,17 +91,13 @@ vec3 directionalLightContribution(DirectionalLight light, vec3 normal, vec3 view vec3 ambient, diffuse, specular; computeShading(ambientColor, diffuseColor, specularColor, lightDir, viewDir, normal, ambient, diffuse, specular); - float shadows = 0.0f; - // if(b_drawShadows) - // shadows = computeDirectionalShadows(v_fragmentPositionDirectionalLightSpace, normal, lightDir); - - return (ambient + (1.0f - shadows) * (diffuse + specular)); + return ambient + diffuse + specular; } -vec3 pointLightContribution(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir) { - +vec3 pointLightContribution(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir) +{ // Only compute if light source is active - if(!light.isActive) + if (!light.isActive) return vec3(0.0f); vec3 lightDir = normalize(v_lightPositionTangent0 - fragPos); @@ -153,123 +110,35 @@ vec3 pointLightContribution(PointLight light, vec3 normal, vec3 fragPos, vec3 vi computeShading(ambientColor, diffuseColor, specularColor, lightDir, viewDir, normal, ambient, diffuse, specular); float attenuation = computeAttenuation(v_lightPositionTangent0, fragPos, 0.032f); - //ambient *= attenuation; - //diffuse *= attenuation; - //specular *= attenuation; + // ambient *= attenuation; + // diffuse *= attenuation; + // specular *= attenuation; - float shadows = 0.0f; - // if(b_drawShadows) - // shadows = computePointShadows(v_fragmentPosition, light.position); - - return (ambient + (1.0f - shadows) * (diffuse + specular)); + return ambient + diffuse + specular; } -/*vec3 spotLightContribution(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) { - - // Only compute if light source is active - if(!light.isActive) - return vec3(0.0f); - - vec3 lightDir = normalize(light.position - fragPos); - - vec3 ambient, diffuse, specular; - computeShading(light.ambient, light.diffuse, light.specular, lightDir, viewDir, normal, ambient, diffuse, specular); - - float attenuation = computeAttenuation(light.position, fragPos, light.K_q); - ambient *= attenuation; - diffuse *= attenuation; - specular *= attenuation; - - float theta = dot(lightDir, normalize(-light.direction)); - float epsilon = light.innerCutOff - light.outerCutOff; - float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0f, 1.0f); - - diffuse *= intensity; - specular *= intensity; - - return (ambient + diffuse + specular); -}*/ - -void computeShading( - vec3 light_ambient, vec3 light_diffuse, vec3 light_specular, - vec3 lightDir, vec3 viewDir, vec3 normal, - out vec3 ambient, out vec3 diffuse, out vec3 specular) { - +void computeShading(vec3 light_ambient, vec3 light_diffuse, vec3 light_specular, vec3 lightDir, vec3 viewDir, + vec3 normal, out vec3 ambient, out vec3 diffuse, out vec3 specular) +{ // Diffuse shading float diffuseShading = max(dot(normal, lightDir), 0.0f); // Specular shading vec3 halfwayDir = normalize(lightDir + viewDir); - float specularShading = pow(max(dot(normal, halfwayDir), 0.0f), u_material.shininess); - - vec4 diffuseTex = texture(u_material.texture_diffuse0, v_texCoord); - vec4 specularTex = texture(u_material.texture_specular0, v_texCoord); + float specularShading = pow(max(dot(normal, halfwayDir), 0.0f), 100.0f); + + vec4 diffuseTex = texture(u_material.texture_diffuse, v_texCoord); + // vec4 specularTex = texture(u_material.texture_specular, v_texCoord); ambient = light_ambient * vec3(diffuseTex); diffuse = light_diffuse * diffuseShading * vec3(diffuseTex); - specular = light_specular * specularShading * vec3(specularTex); - + // specular = light_specular * specularShading * vec3(specularTex); + specular = vec3(0.0f); } -float computeAttenuation(vec3 lightPos, vec3 fragPos, float K_q) { - +float computeAttenuation(vec3 lightPos, vec3 fragPos, float K_q) +{ float distanceLightFragment = length(lightPos - fragPos); return 1.0f / (K_q * distanceLightFragment * distanceLightFragment); - } - -// float computeDirectionalShadows(vec4 fragPosLightSpace, vec3 normal, vec3 lightDir) { - -// // Perspective divide -// vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; - -// // Transform from [-1,1] to [0,1] -// projCoords *= 0.5f; -// projCoords += 0.5f; - -// if(projCoords.z > 1.0f) return 0.0f; - -// float closestDepth = texture(u_texture_directionalShadowMap, projCoords.xy).r; -// float currentDepth = projCoords.z; - -// float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005); -// bias *= 0.25f; - -// float shadow = 0.0; -// vec2 texelSize = 1.0 / textureSize(u_texture_directionalShadowMap, 0); -// for(int x = -1; x <= 1; x++) { -// for(int y = -1; y <= 1; y++) { -// float pcfDepth = texture(u_texture_directionalShadowMap, projCoords.xy + vec2(x, y) * texelSize).r; -// shadow += currentDepth - bias > pcfDepth ? 1.0 : 0.0; -// } -// } -// shadow /= 9.0f; - -// return shadow; -// } - -// float computePointShadows(vec3 fragPos, vec3 lightPos) { - -// // get vector between fragment position and light position -// vec3 fragToLight = fragPos - lightPos; - -// // now get current linear depth as the length between the fragment and light position -// float currentDepth = length(fragToLight); - -// float shadow = 0.0; -// float bias = 0.05; -// int samples = 20; -// float viewDistance = length(v_viewPositionTangent - fragPos); -// float diskRadius = 0.05; - -// for(int i = 0; i < samples; ++i) { -// float closestDepth = texture(u_texture_pointShadowMap0, fragToLight + sampleOffsetDirections[i] * diskRadius).r; -// closestDepth *= pointShadowDepthMapFarPlane; -// if(currentDepth - bias > closestDepth) -// shadow += 1.0; -// } - -// shadow /= float(samples); -// return shadow; -// } diff --git a/src/Controller.cpp b/src/Controller.cpp index f443f45..d5911b5 100644 --- a/src/Controller.cpp +++ b/src/Controller.cpp @@ -2,6 +2,7 @@ #include "Camera.h" #include "FrameBuffer.h" #include "Helper.h" +#include "Light.h" #include "Mesh.h" #include "ShaderProgram.h" #include "Window.h" @@ -25,8 +26,9 @@ Controller::Controller() std::string err; std::string warn; - bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "glTF/DamagedHelmet.gltf"); - // bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "minimal.gltf"); + // bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "WaterBottle/glTF/WaterBottle.gltf"); + // bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "Lantern/glTF/Lantern.gltf"); + bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "glTF/ABeautifulGame.gltf"); if (!warn.empty()) { Log::logger().warn("{}", warn); @@ -49,11 +51,25 @@ Controller::Controller() ShaderProgram::unbind(); + std::vector textures; + for (auto const &texture : m_model.textures) { + textures.emplace_back(texture, m_model.images); + } + m_textures = std::move(textures); + std::vector models; for (auto const &mesh : m_model.meshes) { std::vector meshes; for (auto const &primitive : mesh.primitives) { - meshes.emplace_back(Mesh({primitive, m_model, locations}, {})); + auto const &material = m_model.materials.at(primitive.material); + auto baseColorTexture = material.pbrMetallicRoughness.baseColorTexture; + std::vector> textures; + + if (baseColorTexture.index != -1) { + textures.push_back(m_textures.at(baseColorTexture.index)); + } + + meshes.emplace_back(Mesh({primitive, m_model, locations}, textures)); } models.emplace_back(Model(mesh.name, std::move(meshes))); } @@ -61,6 +77,10 @@ Controller::Controller() std::vector entities; for (auto const &node : m_model.nodes) { + if (node.mesh == -1) { + continue; + } + ModelEntity entity(Entity::Prototype(node.name, {}, {}, 1.0F), m_models[static_cast(node.mesh)], defaultProgram); @@ -84,8 +104,6 @@ Controller::Controller() entities[child].translate(glm::vec3(node.translation[0], node.translation[1], node.translation[2])); } } - - Log::logger().info("Load node {}.", node.name); } m_entities = std::move(entities); } @@ -95,12 +113,13 @@ void Controller::run() updateExposure(postProcessingProgram); m_camera->translate(glm::vec3(0., 1.5, 5.)); + DirectionalLight light(DirectionalLight::Prototype("", glm::vec3(-0.2, -1.0, -0.3), glm::vec3(1.0f), 10.f), + &defaultProgram); Log::logger().info("Startup complete. Enter game loop."); // This is the game loop while (glfwWindowShouldClose(&m_gameWindow->glfw_window()) == GLFW_FALSE) { - // --- Timing --- limit_framerate(); diff --git a/src/Controller.h b/src/Controller.h index a1b07c9..fcccaea 100644 --- a/src/Controller.h +++ b/src/Controller.h @@ -5,6 +5,7 @@ #include "VertexArray.h" #include "resources/Model.h" #include "Entity.h" +#include "resources/Texture.h" #include #include @@ -47,6 +48,7 @@ private: std::vector m_entities; std::vector m_models; + std::vector m_textures; double m_deltaTime{}; float m_exposure = 1.0; diff --git a/src/Entity.h b/src/Entity.h index 2d94c35..302f91a 100644 --- a/src/Entity.h +++ b/src/Entity.h @@ -22,7 +22,6 @@ public: : name(_name), position(_position), rotation(_rotation), scale(_scale) { } - virtual ~Prototype() = default; std::string name; glm::vec3 position; diff --git a/src/FrameBuffer.h b/src/FrameBuffer.h index fbe8a23..529dbfd 100644 --- a/src/FrameBuffer.h +++ b/src/FrameBuffer.h @@ -1,6 +1,7 @@ #pragma once -#include "resources/CubeMap.h" +#include "resources/Resource.h" + #include class ShaderProgram; diff --git a/src/Light.cpp b/src/Light.cpp index 2dce9d4..ffe3e1b 100644 --- a/src/Light.cpp +++ b/src/Light.cpp @@ -13,7 +13,8 @@ Light::Light(const std::string &name, glm::vec3 color, float intensity, ShaderPr } Light::~Light() -{} +{ +} glm::vec3 Light::getColor() { @@ -45,7 +46,8 @@ void Light::setActive(bool active) PointLight::PointLight(Prototype prototype, ShaderProgram *shaderProgram) : Light(prototype.name, prototype.color, prototype.intensity, shaderProgram), m_position(prototype.position) -{} +{ +} void PointLight::update() { @@ -78,7 +80,9 @@ void PointLight::setPosition(glm::vec3 position) DirectionalLight::DirectionalLight(Prototype prototype, ShaderProgram *shaderProgram) : Light(prototype.name, prototype.color, prototype.intensity, shaderProgram), m_direction(prototype.direction) -{} +{ + update(); +} void DirectionalLight::update() { diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 546252c..f2febf8 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -2,31 +2,20 @@ #include "ShaderProgram.h" #include "VertexArray.h" -#include "resources/ResourceHandler.h" #include "resources/Texture.h" #include -Mesh::Mesh(VertexArray vertexArray, std::vector textures) +Mesh::Mesh(VertexArray vertexArray, std::vector> textures) : m_vertexArray(std::move(vertexArray)), m_textures(std::move(textures)) { } void Mesh::draw(ShaderProgram const &shaderProgram) const { - std::array(TextureType::TEXTURE_TYPE_NUM_ITEMS)> typeNumberCount{}; - - glBindTexture(GL_TEXTURE_2D, 0); // Bind all textures in order to its texture unit std::size_t textureNum = 0; for (auto textureIt : m_textures) { - auto texture = std::static_pointer_cast(ResourceHandler::instance().resource(textureIt)); - TextureType currentTextureType = texture->textureType(); - - texture->bind(static_cast(textureNum), shaderProgram, - typeNumberCount.at(static_cast(currentTextureType))); - - typeNumberCount.at(static_cast(currentTextureType)) += 1; - + textureIt.get().bind(static_cast(textureNum), shaderProgram); textureNum++; } @@ -38,16 +27,17 @@ void Mesh::draw(ShaderProgram const &shaderProgram) const // Unbind all textures for (auto textureIt : m_textures) { - auto texture = std::static_pointer_cast(ResourceHandler::instance().resource(textureIt)); - texture->unbind(); + textureIt.get().unbind(); } } void Mesh::drawWithoutTextures() const { m_vertexArray.bind(); + glDrawElements(GL_TRIANGLES, static_cast(m_vertexArray.indicesCount()), static_cast(m_vertexArray.indicesType()), nullptr); + VertexArray::unbind(); } diff --git a/src/Mesh.h b/src/Mesh.h index e365395..0375017 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -1,7 +1,7 @@ #pragma once #include "VertexArray.h" -#include "resources/Resource.h" +#include "resources/Texture.h" #include @@ -10,7 +10,7 @@ class ShaderProgram; class Mesh { public: - Mesh(VertexArray vertexArray, std::vector textures); + Mesh(VertexArray vertexArray, std::vector> textures); void draw(ShaderProgram const &shaderProgram) const; void drawWithoutTextures() const; @@ -19,5 +19,5 @@ public: private: VertexArray m_vertexArray; - std::vector m_textures; + std::vector> m_textures; }; diff --git a/src/Scene.cpp b/src/Scene.cpp index 8ffe3a7..91d8c4d 100644 --- a/src/Scene.cpp +++ b/src/Scene.cpp @@ -14,11 +14,6 @@ Scene::Scene(std::vector> shaderPrograms) : m_shaderProgram(*Controller::getShaderProgramByName("defaultProgram", shaderPrograms)) { - // This will be removed in future when gloss maps are implemented - m_shaderProgram.bind(); - m_shaderProgram.setUniform("u_material.shininess", 100.0f); - m_shaderProgram.unbind(); - std::array modelDescriptors{ ModelDescriptor{"fallback", "data/res/models/fallback.ffo"}, ModelDescriptor{"backpack", "data/res/models/backpack.ffo"}, diff --git a/src/VertexArray.cpp b/src/VertexArray.cpp index 8833974..c8d3a0c 100644 --- a/src/VertexArray.cpp +++ b/src/VertexArray.cpp @@ -4,53 +4,118 @@ #include #include -VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model const &model, AttributeLocations &locations) +VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model const &model, + AttributeLocations &locations) { GLuint vao{}; glGenVertexArrays(1, &vao); glBindVertexArray(vao); int position_accessor_id = primitive.attributes.at("POSITION"); - // int normal_accessor = primitive.attributes.at("NORMAL"); - // int uv_accessor = primitive.attributes.at("TEXCOORD_0"); + int normal_accessor_id = primitive.attributes.at("NORMAL"); + int uv_accessor_id = primitive.attributes.at("TEXCOORD_0"); int indices_accessor_id = primitive.indices; auto const &position_accessor = model.accessors.at(position_accessor_id); + auto const &normal_accessor = model.accessors.at(normal_accessor_id); + auto const &uv_accessor = model.accessors.at(uv_accessor_id); auto const &indices_accessor = model.accessors.at(indices_accessor_id); int position_buffer_view_id = model.accessors[position_accessor_id].bufferView; + int normal_buffer_view_id = model.accessors[normal_accessor_id].bufferView; + int uv_buffer_view_id = model.accessors[uv_accessor_id].bufferView; int indices_buffer_view_id = model.accessors[indices_accessor_id].bufferView; auto const &position_buffer_view = model.bufferViews.at(position_buffer_view_id); + auto const &normal_buffer_view = model.bufferViews.at(normal_buffer_view_id); + auto const &uv_buffer_view = model.bufferViews.at(uv_buffer_view_id); auto const &indices_buffer_view = model.bufferViews.at(indices_buffer_view_id); auto const &position_buffer = model.buffers.at(position_buffer_view.buffer); + auto const &normal_buffer = model.buffers.at(normal_buffer_view.buffer); + auto const &uv_buffer = model.buffers.at(uv_buffer_view.buffer); auto const &indices_buffer = model.buffers.at(indices_buffer_view.buffer); GLuint positionVbo{}; - glGenBuffers(1, &positionVbo); - glBindBuffer(GL_ARRAY_BUFFER, positionVbo); - glBufferData(GL_ARRAY_BUFFER, position_buffer_view.byteLength, - position_buffer.data.data() + position_buffer_view.byteOffset, GL_STATIC_DRAW); + { + glGenBuffers(1, &positionVbo); + glBindBuffer(GL_ARRAY_BUFFER, positionVbo); + glBufferData(GL_ARRAY_BUFFER, position_buffer_view.byteLength, + position_buffer.data.data() + position_buffer_view.byteOffset, GL_STATIC_DRAW); - int size = 1; - if (position_accessor.type == TINYGLTF_TYPE_SCALAR) { - size = 1; - } else if (position_accessor.type == TINYGLTF_TYPE_VEC2) { - size = 2; - } else if (position_accessor.type == TINYGLTF_TYPE_VEC3) { - size = 3; - } else if (position_accessor.type == TINYGLTF_TYPE_VEC4) { - size = 4; - } else { - assert(0); + int size = 1; + if (position_accessor.type == TINYGLTF_TYPE_SCALAR) { + size = 1; + } else if (position_accessor.type == TINYGLTF_TYPE_VEC2) { + size = 2; + } else if (position_accessor.type == TINYGLTF_TYPE_VEC3) { + size = 3; + } else if (position_accessor.type == TINYGLTF_TYPE_VEC4) { + size = 4; + } else { + assert(0); + } + + int position_byte_stride = position_accessor.ByteStride(position_buffer_view); + glEnableVertexAttribArray(locations.position); + glVertexAttribPointer(locations.position, size, position_accessor.componentType, + position_accessor.normalized ? GL_TRUE : GL_FALSE, position_byte_stride, + (void *)position_accessor.byteOffset); } - int position_byte_stride = position_accessor.ByteStride(position_buffer_view); - glEnableVertexAttribArray(locations.position); - glVertexAttribPointer(locations.position, size, position_accessor.componentType, - position_accessor.normalized ? GL_TRUE : GL_FALSE, position_byte_stride, - (void *)position_accessor.byteOffset); + GLuint normalVbo{}; + { + glGenBuffers(1, &normalVbo); + glBindBuffer(GL_ARRAY_BUFFER, normalVbo); + glBufferData(GL_ARRAY_BUFFER, normal_buffer_view.byteLength, + normal_buffer.data.data() + normal_buffer_view.byteOffset, GL_STATIC_DRAW); + + int size = 1; + if (normal_accessor.type == TINYGLTF_TYPE_SCALAR) { + size = 1; + } else if (normal_accessor.type == TINYGLTF_TYPE_VEC2) { + size = 2; + } else if (normal_accessor.type == TINYGLTF_TYPE_VEC3) { + size = 3; + } else if (normal_accessor.type == TINYGLTF_TYPE_VEC4) { + size = 4; + } else { + assert(0); + } + + int normal_byte_stride = normal_accessor.ByteStride(normal_buffer_view); + glEnableVertexAttribArray(locations.normal); + glVertexAttribPointer(locations.normal, size, normal_accessor.componentType, + normal_accessor.normalized ? GL_TRUE : GL_FALSE, normal_byte_stride, + (void *)normal_accessor.byteOffset); + } + + GLuint uvVbo{}; + { + glGenBuffers(1, &uvVbo); + glBindBuffer(GL_ARRAY_BUFFER, uvVbo); + glBufferData(GL_ARRAY_BUFFER, uv_buffer_view.byteLength, + uv_buffer.data.data() + uv_buffer_view.byteOffset, GL_STATIC_DRAW); + + int size = 1; + if (uv_accessor.type == TINYGLTF_TYPE_SCALAR) { + size = 1; + } else if (uv_accessor.type == TINYGLTF_TYPE_VEC2) { + size = 2; + } else if (uv_accessor.type == TINYGLTF_TYPE_VEC3) { + size = 3; + } else if (uv_accessor.type == TINYGLTF_TYPE_VEC4) { + size = 4; + } else { + assert(0); + } + + int uv_byte_stride = uv_accessor.ByteStride(uv_buffer_view); + glEnableVertexAttribArray(locations.uv); + glVertexAttribPointer(locations.uv, size, uv_accessor.componentType, + uv_accessor.normalized ? GL_TRUE : GL_FALSE, uv_byte_stride, + (void *)uv_accessor.byteOffset); + } GLuint ebo{}; glGenBuffers(1, &ebo); @@ -63,6 +128,8 @@ VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model c m_vao = vao; m_ebo = ebo; m_positionVbo = positionVbo; + m_normalVbo = normalVbo; + m_uvVbo = uvVbo; m_indicesCount = indices_accessor.count; m_indicesType = indices_accessor.componentType; } @@ -72,6 +139,8 @@ VertexArray::~VertexArray() glDeleteVertexArrays(1, &m_vao); glDeleteBuffers(1, &m_positionVbo); + glDeleteBuffers(1, &m_normalVbo); + glDeleteBuffers(1, &m_uvVbo); glDeleteBuffers(1, &m_ebo); } diff --git a/src/VertexArray.h b/src/VertexArray.h index 1b6addf..a924469 100644 --- a/src/VertexArray.h +++ b/src/VertexArray.h @@ -15,11 +15,15 @@ public: m_indicesType(other.m_indicesType), m_vao(other.m_vao), m_positionVbo(other.m_positionVbo), + m_normalVbo(other.m_normalVbo), + m_uvVbo(other.m_uvVbo), m_ebo(other.m_ebo) { other.m_ebo = 0; other.m_vao = 0; other.m_positionVbo = 0; + other.m_normalVbo = 0; + other.m_uvVbo = 0; } auto operator=(VertexArray &&other) noexcept -> VertexArray & @@ -28,11 +32,15 @@ public: m_indicesType = other.m_indicesType; m_vao = other.m_vao; m_positionVbo = other.m_positionVbo; + m_normalVbo = other.m_normalVbo; + m_uvVbo = other.m_uvVbo; m_ebo = other.m_ebo; other.m_ebo = 0; other.m_vao = 0; other.m_positionVbo = 0; + other.m_normalVbo = 0; + other.m_uvVbo = 0; return *this; } @@ -55,5 +63,7 @@ private: GLuint m_vao; GLuint m_positionVbo; + GLuint m_normalVbo; + GLuint m_uvVbo; GLuint m_ebo; }; diff --git a/src/resources/AbstractTexture.h b/src/resources/AbstractTexture.h index a2c820a..d470229 100644 --- a/src/resources/AbstractTexture.h +++ b/src/resources/AbstractTexture.h @@ -11,5 +11,4 @@ public: protected: uint32_t m_textureWidth; uint32_t m_textureHeight; - uint32_t m_numComponents; }; diff --git a/src/resources/CubeMap.cpp b/src/resources/CubeMap.cpp index 22838ab..b33a007 100644 --- a/src/resources/CubeMap.cpp +++ b/src/resources/CubeMap.cpp @@ -6,9 +6,6 @@ TextureCubeMap::TextureCubeMap(const TextureCubeMapDescriptor &descriptor) : AbstractCubeMap(descriptor.path) { - // Reserve space in vector so that elements can be accessed explicitly. - m_textureBuffers.resize(static_cast(CubeMapFace::CUBEMAP_FACES_NUM_ITEMS)); - stbi_set_flip_vertically_on_load(0); glGenTextures(1, &m_glId); @@ -20,7 +17,7 @@ TextureCubeMap::TextureCubeMap(const TextureCubeMapDescriptor &descriptor) : Abs glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - std::size_t i = 0; + std::size_t faceCount = 0; for (const auto &faceName : FACE_NAMES) { std::string texturePath = descriptor.path + faceName; @@ -28,43 +25,20 @@ TextureCubeMap::TextureCubeMap(const TextureCubeMapDescriptor &descriptor) : Abs int textureHeight{}; int numComponents{}; - auto textureBuffer = stbi_load(texturePath.c_str(), &textureWidth, &textureHeight, &numComponents, 0); + auto *textureBuffer = stbi_load(texturePath.c_str(), &textureWidth, &textureHeight, &numComponents, 0); m_textureWidth = static_cast(textureWidth); m_textureHeight = static_cast(textureHeight); - m_numComponents = static_cast(numComponents); - if (!textureBuffer) { + if (textureBuffer == nullptr) { Log::logger().warn("CubeMap texture {} could not be loaded", texturePath); return; } - m_textureBuffers[i] = textureBuffer; - i++; - } + GLint internalFormat{}; + GLenum dataFormat{}; - glBindTexture(GL_TEXTURE_CUBE_MAP, 0); -} - -void TextureCubeMap::initialize() -{ - m_initialized = true; - - glGenTextures(1, &m_glId); - glBindTexture(GL_TEXTURE_CUBE_MAP, m_glId); - - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - int i = 0; - for (auto &textureBuffer : m_textureBuffers) { - GLint internalFormat; - GLenum dataFormat; - - switch (m_numComponents) { + switch (numComponents) { case 1: internalFormat = GL_RED; dataFormat = GL_RED; @@ -79,12 +53,13 @@ void TextureCubeMap::initialize() break; } - glTexImage2D(static_cast(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i), 0, internalFormat, + glTexImage2D(static_cast(GL_TEXTURE_CUBE_MAP_POSITIVE_X + faceCount), 0, internalFormat, static_cast(m_textureWidth), static_cast(m_textureHeight), 0, dataFormat, GL_UNSIGNED_BYTE, textureBuffer); stbi_image_free(textureBuffer); - i++; + + faceCount++; } glBindTexture(GL_TEXTURE_CUBE_MAP, 0); @@ -108,7 +83,6 @@ InternalCubeMap::InternalCubeMap(unsigned int resolution) : AbstractCubeMap("int { m_textureWidth = resolution; m_textureHeight = resolution; - m_initialized = true; glGenTextures(1, &m_glId); glBindTexture(GL_TEXTURE_CUBE_MAP, m_glId); @@ -121,7 +95,7 @@ InternalCubeMap::InternalCubeMap(unsigned int resolution) : AbstractCubeMap("int for (unsigned int i = 0; i < static_cast(CubeMapFace::CUBEMAP_FACES_NUM_ITEMS); i++) { glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT24, static_cast(resolution), - static_cast(resolution), 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL); + static_cast(resolution), 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr); } glBindTexture(GL_TEXTURE_CUBE_MAP, 0); diff --git a/src/resources/CubeMap.h b/src/resources/CubeMap.h index 22995b7..f4387da 100644 --- a/src/resources/CubeMap.h +++ b/src/resources/CubeMap.h @@ -41,20 +41,10 @@ class TextureCubeMap : public AbstractCubeMap { public: TextureCubeMap(const TextureCubeMapDescriptor &descriptor); - -protected: - void initialize() override; - -private: - std::vector m_textureBuffers; }; class InternalCubeMap : public AbstractCubeMap { public: InternalCubeMap(unsigned int resolution); - -protected: - void initialize() override - {} }; diff --git a/src/resources/Resource.cpp b/src/resources/Resource.cpp index 2516d63..95aad75 100644 --- a/src/resources/Resource.cpp +++ b/src/resources/Resource.cpp @@ -13,11 +13,6 @@ auto Resource::id() const -> ResourceId return m_id; } -auto Resource::isInitialized() const -> bool -{ - return m_initialized; -} - auto Resource::resourcePath() const -> const std::filesystem::path & { return m_path; diff --git a/src/resources/Resource.h b/src/resources/Resource.h index bc0174b..220cf0e 100644 --- a/src/resources/Resource.h +++ b/src/resources/Resource.h @@ -18,13 +18,7 @@ public: [[nodiscard]] auto id() const -> ResourceId; [[nodiscard]] auto resourcePath() const -> const std::filesystem::path &; - -protected: - [[nodiscard]] auto isInitialized() const -> bool; - virtual void initialize() = 0; - - bool m_initialized = false; - + private: ResourceId m_id; static ResourceId s_idCounter; diff --git a/src/resources/ResourceHandler.cpp b/src/resources/ResourceHandler.cpp index aca9622..8e3b3b0 100644 --- a/src/resources/ResourceHandler.cpp +++ b/src/resources/ResourceHandler.cpp @@ -1,7 +1,6 @@ #include "ResourceHandler.h" #include "../util/Log.h" #include "CubeMap.h" -#include "Texture.h" #include @@ -20,7 +19,6 @@ auto ResourceHandler::registerResource(Param const &...param) -> ResourceId return resource->id(); } -template ResourceId ResourceHandler::registerResource(TextureDescriptor const &); template ResourceId ResourceHandler::registerResource(TextureCubeMapDescriptor const &); template ResourceId ResourceHandler::registerResource(int const &); @@ -30,38 +28,9 @@ auto ResourceHandler::resource(const ResourceId resourceId) const -> std::shared if (resourceIt != m_resources.end()) { auto resource = resourceIt->second; - - if (!resource->isInitialized()) { - resource->initialize(); - } - return resource; } Log::logger().warn("Could not find resource with id {}", resourceId); return {}; } - -auto ResourceHandler::resource(const std::string &name) const -> std::shared_ptr -{ - auto resourceIt = std::find_if(m_resources.begin(), m_resources.end(), [&name](const auto &resource) { - if (auto namedResource = std::dynamic_pointer_cast(resource.second)) { - return namedResource->name() == name; - } - - return false; - }); - - if (resourceIt != m_resources.end()) { - auto resource = resourceIt->second; - - if (!resource->isInitialized()) { - resource->initialize(); - } - - return resource; - } - - Log::logger().warn("Could not find resource with unique name \"{}\"", name); - return {}; -} diff --git a/src/resources/ResourceHandler.h b/src/resources/ResourceHandler.h index f7c54fb..8f484fc 100644 --- a/src/resources/ResourceHandler.h +++ b/src/resources/ResourceHandler.h @@ -14,7 +14,6 @@ public: auto registerResource(Param const &...param) -> ResourceId; [[nodiscard]] auto resource(ResourceId resourceId) const -> std::shared_ptr; - [[nodiscard]] auto resource(const std::string &name) const -> std::shared_ptr; private: ResourceHandler() = default; diff --git a/src/resources/Texture.cpp b/src/resources/Texture.cpp index 505b884..d20cfcc 100644 --- a/src/resources/Texture.cpp +++ b/src/resources/Texture.cpp @@ -4,34 +4,76 @@ #include -Texture::Texture(const TextureDescriptor &descriptor) - : AbstractTexture(descriptor.path), m_textureType(descriptor.textureType) +// Texture::Texture(const TextureDescriptor &descriptor) : m_textureType(descriptor.textureType) +// { +// stbi_set_flip_vertically_on_load(1); + +// int textureWidth{}; +// int textureHeight{}; +// int numComponents{}; + +// m_textureBuffer = stbi_load(resourcePath().c_str(), &textureWidth, &textureHeight, &numComponents, 0); + +// m_textureWidth = static_cast(textureWidth); +// m_textureHeight = static_cast(textureHeight); + +// if (m_textureBuffer == nullptr) { +// Log::logger().warn("Texture {} could not be loaded", resourcePath().string()); +// } + +// GLenum internalFormat{}; +// GLenum dataFormat{}; + +// switch (numComponents) { +// case 1: +// internalFormat = GL_RED; +// dataFormat = GL_RED; +// break; +// case 3: +// internalFormat = (m_textureType == TextureType::Diffuse) ? GL_SRGB8 : GL_RGB8; +// dataFormat = GL_RGB; +// break; +// case 4: +// internalFormat = (m_textureType == TextureType::Diffuse) ? GL_SRGB8_ALPHA8 : GL_RGBA8; +// dataFormat = GL_RGBA; +// break; +// } + +// // Push texture to grahics card +// glGenTextures(1, &m_glId); +// glBindTexture(GL_TEXTURE_2D, m_glId); + +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); +// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, -2.0F); + +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); +// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + +// glTexImage2D(GL_TEXTURE_2D, 0, static_cast(internalFormat), static_cast(m_textureWidth), +// static_cast(m_textureHeight), 0, dataFormat, GL_UNSIGNED_BYTE, m_textureBuffer); +// glGenerateMipmap(GL_TEXTURE_2D); + +// glBindTexture(GL_TEXTURE_2D, 0); + +// stbi_image_free(m_textureBuffer); +// } + +Texture::Texture(tinygltf::Texture const &texture, std::span images) { - stbi_set_flip_vertically_on_load(1); + auto sampler = texture.sampler; + auto const &image = images[texture.source]; - int textureWidth{}; - int textureHeight{}; - int numComponents{}; + m_textureType = TextureType::Diffuse; - m_textureBuffer = stbi_load(resourcePath().c_str(), &textureWidth, &textureHeight, &numComponents, 0); - - m_textureWidth = static_cast(textureWidth); - m_textureHeight = static_cast(textureHeight); - m_numComponents = static_cast(numComponents); - - if (m_textureBuffer == nullptr) { - Log::logger().warn("Texture {} could not be loaded", resourcePath().string()); - } -} - -void Texture::initialize() -{ - m_initialized = true; + uint32_t width = image.width; + uint32_t height = image.height; + unsigned int components = image.component; GLenum internalFormat{}; GLenum dataFormat{}; - switch (m_numComponents) { + switch (components) { case 1: internalFormat = GL_RED; dataFormat = GL_RED; @@ -46,7 +88,6 @@ void Texture::initialize() break; } - // Push texture to grahics card glGenTextures(1, &m_glId); glBindTexture(GL_TEXTURE_2D, m_glId); @@ -57,13 +98,11 @@ void Texture::initialize() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexImage2D(GL_TEXTURE_2D, 0, static_cast(internalFormat), static_cast(m_textureWidth), - static_cast(m_textureHeight), 0, dataFormat, GL_UNSIGNED_BYTE, m_textureBuffer); + glTexImage2D(GL_TEXTURE_2D, 0, static_cast(internalFormat), static_cast(width), + static_cast(height), 0, dataFormat, GL_UNSIGNED_BYTE, image.image.data()); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); - - stbi_image_free(m_textureBuffer); } auto Texture::textureType() const -> TextureType @@ -71,26 +110,17 @@ auto Texture::textureType() const -> TextureType return m_textureType; } -void Texture::bind(uint8_t textureUnit, ShaderProgram const &shaderProgram, uint8_t textureTypeNum) const +void Texture::bind(uint8_t textureUnit, ShaderProgram const &shaderProgram) const { std::string uniformName = "texture_"; switch (m_textureType) { case TextureType::Diffuse: - uniformName += "diffuse" + std::to_string(textureTypeNum); - break; - case TextureType::Specular: - uniformName += "specular" + std::to_string(textureTypeNum); + uniformName += "diffuse"; break; case TextureType::Normal: - uniformName += "normal" + std::to_string(textureTypeNum); - break; - case TextureType::Height: - uniformName += "height" + std::to_string(textureTypeNum); - break; - case TextureType::Gloss: - uniformName += "gloss" + std::to_string(textureTypeNum); + uniformName += "normal"; break; default: break; @@ -104,7 +134,7 @@ void Texture::bind(uint8_t textureUnit, ShaderProgram const &shaderProgram, uint glBindTexture(GL_TEXTURE_2D, m_glId); } -void Texture::unbind() const +void Texture::unbind() { glBindTexture(GL_TEXTURE_2D, 0); } diff --git a/src/resources/Texture.h b/src/resources/Texture.h index 88c4ea9..74ef60f 100644 --- a/src/resources/Texture.h +++ b/src/resources/Texture.h @@ -1,34 +1,32 @@ #pragma once -#include "AbstractTexture.h" #include "TextureType.h" -#include +#include +#include #include +#include class ShaderProgram; -struct TextureDescriptor -{ - std::string path; - TextureType textureType; -}; +// struct TextureDescriptor +// { +// std::string path; +// TextureType textureType; +// }; -class Texture : public AbstractTexture +class Texture { public: - Texture(const TextureDescriptor &descriptor); + // Texture(const TextureDescriptor &descriptor); + Texture(tinygltf::Texture const &texture, std::span images); [[nodiscard]] auto textureType() const -> TextureType; - void bind(uint8_t textureUnit, ShaderProgram const &shaderProgram, uint8_t textureTypeNum) const; - void unbind() const override; - -protected: - void initialize() override; + void bind(uint8_t textureUnit, ShaderProgram const &shaderProgram) const; + static void unbind(); private: - stbi_uc *m_textureBuffer; - TextureType m_textureType; + GLuint m_glId = 0; }; \ No newline at end of file diff --git a/src/resources/TextureType.h b/src/resources/TextureType.h index 0667b32..febbcd8 100644 --- a/src/resources/TextureType.h +++ b/src/resources/TextureType.h @@ -3,9 +3,6 @@ enum class TextureType { Diffuse, - Specular, Normal, - Height, - Gloss, TEXTURE_TYPE_NUM_ITEMS }; \ No newline at end of file diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt deleted file mode 100644 index 769e9fd..0000000 --- a/tools/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_executable(obj-converter main.cpp) - -target_link_libraries(obj-converter assimp glm) diff --git a/tools/fileformat.txt b/tools/fileformat.txt deleted file mode 100644 index 0b1f221..0000000 --- a/tools/fileformat.txt +++ /dev/null @@ -1,29 +0,0 @@ -NUM_TEXTURES -TYPE_DIFFUSE -TYPE_DIFFUSE -TYPE_SPECULAR -TYPE_NORMAL -TYPE_HEIGHT -./diffuse0.jpg000000000000 -./diffuse1.jpg000000000000 -./specular.jpg000000000000 -./normal.jpg00000000000000 -./height.jpg00000000000000 -NUM_VERTICES -NUM_INDICES -NUM_TEXTUREIDS - - - -NUM_VERTICES -NUM_INDICES -NUM_TEXTUREIDS - - - -NUM_VERTICES -NUM_INDICES -NUM_TEXTUREIDS - - - diff --git a/tools/main.cpp b/tools/main.cpp deleted file mode 100644 index 845e489..0000000 --- a/tools/main.cpp +++ /dev/null @@ -1,261 +0,0 @@ -/* - - This is the tool to generate model files for the Fall-Fever game. It's used to - reduce loading time of the game, and also to reduce runtime dependencies (libassimp). - - The model files do not support material colors; only textures at this point. - All path strings are 128 elements long. - -*/ - -#include -#include -#include - -#include -#include -#include -#include - -#include "../src/definitions/models.h" -#include "../src/resources/TextureTypes.h" -#include "primitiveModel.h" - -void processNode(aiNode *node, const aiScene *scene, Model *model); -Mesh processMesh(aiMesh *mesh, const aiScene *scene, Model *model); -std::vector loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType, Mesh *mesh, - Model *model); - -int main(int argc, char** argv) { - - if(argc <= 1) { - std::cout << "Usage: " << argv[0] << " " << std::endl; - } - - std::vector modelSources; - - for(int i = 0; i < argc - 1; i++) { - modelSources.push_back(argv[i+1]); - } - - Assimp::Importer importer; - - for(auto it = modelSources.begin(); it != modelSources.end(); it++) { - unsigned int flags = - aiProcess_Triangulate | - aiProcess_FlipUVs | - aiProcess_PreTransformVertices | - aiProcess_GenNormals | - aiProcess_OptimizeMeshes | - aiProcess_OptimizeGraph | - aiProcess_JoinIdenticalVertices | - aiProcess_ImproveCacheLocality | - aiProcess_CalcTangentSpace; - - const aiScene* scene = importer.ReadFile((*it).c_str(), flags); - - if(!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { - std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl; - return 1; - } - - Model currentModel; - if(((*it).find('/')) < (*it).length()) { - // source includes a / - currentModel.m_workingPath = (*it).substr(0, (*it).find_last_of('/')); - } else { - currentModel.m_workingPath = "."; - } - - processNode(scene->mRootNode, scene, ¤tModel); - - std::string filenameWithoutExtension = (*it).substr(0, (*it).find_last_of('.')); - std::string outputFilename = filenameWithoutExtension + ".ffo"; - - std::ofstream output(outputFilename, std::ios::out | std::ios::binary); - - uint32_t numTextures = currentModel.textures.size(); - output.write((char*) &numTextures, sizeof(uint32_t)); - - // Write texture types in order - for(auto it1 = currentModel.textures.begin(); it1 != currentModel.textures.end(); it1++) { - uint32_t currentTextureType = (*it1).textureType; - output.write((char*) ¤tTextureType, sizeof(uint32_t)); - } - - // Write texture sources - for(auto it1 = currentModel.textures.begin(); it1 != currentModel.textures.end(); it1++) { - for(unsigned int i = 0; i < 128; i++) { - if(i < (*it1).pathToTexture.size()) { - uint8_t character = (*it1).pathToTexture[i]; - output.write((char*) &character, sizeof(uint8_t)); - } else { - uint8_t character = 0; - output.write((char*) &character, sizeof(uint8_t)); - } - - } - } - - // Write meshes - uint32_t numMeshes = currentModel.m_meshes.size(); - output.write((char*) &numMeshes, sizeof(uint32_t)); - for (auto it1 = currentModel.m_meshes.begin(); it1 != currentModel.m_meshes.end(); it1++) { - uint32_t numVertices = (*it1).vertices.size(); - uint32_t numIndices = (*it1).indices.size(); - uint32_t numTextureIds = (*it1).textureIds.size(); - - output.write((char*) &numVertices, sizeof(uint32_t)); - output.write((char*) &numIndices, sizeof(uint32_t)); - output.write((char*) &numTextureIds, sizeof(uint32_t)); - - Vertex *vertexData = (*it1).vertices.data(); - output.write((char*) vertexData, numVertices * sizeof(Vertex)); - - uint32_t *indexData = (*it1).indices.data(); - output.write((char*) indexData, numIndices * sizeof(uint32_t)); - - uint32_t *textureIdData = (*it1).textureIds.data(); - output.write((char*) textureIdData, numTextureIds * sizeof(uint32_t)); - } - - output.close(); - } - - return 0; -} - -void processNode(aiNode *node, const aiScene *scene, Model* model) { - - // Push the node's meshes into the mesh vector - for(uint32_t i = 0; i < node->mNumMeshes; i++) { - aiMesh *mesh = scene->mMeshes[node->mMeshes[i]]; - model->m_meshes.push_back(processMesh(mesh, scene, model)); - } - - // Process child nodes too - for(uint32_t i = 0; i < node->mNumChildren; i++) { - processNode(node->mChildren[i], scene, model); - } - -} - -Mesh processMesh(aiMesh *mesh, const aiScene *scene, Model *model) { - std::vector vertices; - std::vector indices; - std::vector textures; - Mesh currentMesh; - - for(uint32_t i = 0; i < mesh->mNumVertices; i++) { - Vertex vertex; - - // Position - glm::vec3 vector; - vector.x = mesh->mVertices[i].x; - vector.y = mesh->mVertices[i].y; - vector.z = mesh->mVertices[i].z; - vertex.position = vector; - - // Normals - vector.x = mesh->mNormals[i].x; - vector.y = mesh->mNormals[i].y; - vector.z = mesh->mNormals[i].z; - vertex.normalVec = vector; - - // Tangents - vector.x = mesh->mTangents[i].x; - vector.y = mesh->mTangents[i].y; - vector.z = mesh->mTangents[i].z; - vertex.tangentVec = vector; - - // Bitangents - vector.x = mesh->mBitangents[i].x; - vector.y = mesh->mBitangents[i].y; - vector.z = mesh->mBitangents[i].z; - vertex.bitangentVec = vector; - - // Texture UV mapping - if(mesh->mTextureCoords[0]) { - glm::vec2 vec; - vec.x = mesh->mTextureCoords[0][i].x; - vec.y = mesh->mTextureCoords[0][i].y; - vertex.textureCoords = vec; - } else { - vertex.textureCoords = glm::vec2(0.0f, 0.0f); - } - - vertices.push_back(vertex); - } - - // Indices - for(uint32_t i = 0; i < mesh->mNumFaces; i++) { - aiFace face = mesh->mFaces[i]; - for(uint32_t j = 0; j < face.mNumIndices; j++) { - indices.push_back(face.mIndices[j]); - } - } - - // Material - if(mesh->mMaterialIndex > 0) { - aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex]; - - std::vector diffuseMaps = loadMaterialTextures( - material, aiTextureType_DIFFUSE, static_cast(TextureType::Diffuse), ¤tMesh, model); - textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end()); - - std::vector specularMaps = loadMaterialTextures( - material, aiTextureType_SPECULAR, static_cast(TextureType::Specular), ¤tMesh, model); - textures.insert(textures.end(), specularMaps.begin(), specularMaps.end()); - - std::vector normalMaps = loadMaterialTextures( - material, aiTextureType_HEIGHT, static_cast(TextureType::Normal), ¤tMesh, model); - textures.insert(textures.end(), normalMaps.begin(), normalMaps.end()); - - // Not entirely sure if aiTextureType_HEIGHT is correct - std::vector heightMaps = loadMaterialTextures( - material, aiTextureType_HEIGHT, static_cast(TextureType::Height), ¤tMesh, model); - textures.insert(textures.end(), heightMaps.begin(), heightMaps.end()); - } - - currentMesh.vertices = vertices; - currentMesh.indices = indices; - - return currentMesh; -} - -std::vector loadMaterialTextures(aiMaterial *mat, aiTextureType type, uint8_t textureType, Mesh *mesh, - Model *model) -{ - - std::vector textures; - for(uint32_t i = 0; i < mat->GetTextureCount(type); i++) { - aiString filename; - mat->GetTexture(type, i, &filename); - - std::string currentPath = model->m_workingPath + '/' + filename.C_Str(); - - bool skip = 0; - for(uint32_t j = 0; j < model->textures.size(); j++) { - if(std::strcmp(model->textures[j].pathToTexture.c_str(), currentPath.c_str()) == 0) { - textures.push_back(model->textures[j]); - skip = 1; - break; - } - } - - if(!skip) { - Texture texture; - texture.pathToTexture = currentPath; - texture.textureType = textureType; - // textureIds start at 0, but vector elements start at 1. - texture.m_textureId = model->textures.size(); - - model->textures.push_back(texture); - - // Add newest texture id to mesh - mesh->textureIds.push_back(texture.m_textureId); - } - } - - return textures; -} diff --git a/tools/primitiveModel.h b/tools/primitiveModel.h deleted file mode 100644 index 634446b..0000000 --- a/tools/primitiveModel.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include -#include - -struct Texture -{ - std::string pathToTexture; - uint32_t textureType; - uint32_t m_textureId; -}; - -struct Mesh -{ - std::vector vertices; - std::vector indices; - std::vector textureIds; -}; - -struct Model -{ - std::vector textures; - std::vector m_meshes; - std::string m_workingPath; -};