Add normal mapping support for gltf
This commit is contained in:
@@ -4,9 +4,7 @@ layout(location = 0) out vec4 f_color;
|
||||
|
||||
in vec3 v_normal;
|
||||
in vec2 v_texCoord;
|
||||
in vec3 v_fragmentPosition;
|
||||
in vec3 v_fragmentPositionTangent;
|
||||
in vec4 v_fragmentPositionDirectionalLightSpace;
|
||||
|
||||
in vec3 v_lightDirectionTangent;
|
||||
in vec3 v_lightPositionTangent0;
|
||||
@@ -62,6 +60,7 @@ void main()
|
||||
|
||||
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);
|
||||
@@ -69,10 +68,7 @@ void main()
|
||||
for (int i = 0; i < NUM_POINT_LIGHTS; i++) {
|
||||
fragmentColor += pointLightContribution(u_pointLight[i], 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);
|
||||
}
|
||||
|
||||
@@ -132,8 +128,7 @@ void computeShading(vec3 light_ambient, vec3 light_diffuse, vec3 light_specular,
|
||||
|
||||
ambient = light_ambient * vec3(diffuseTex);
|
||||
diffuse = light_diffuse * diffuseShading * vec3(diffuseTex);
|
||||
// specular = light_specular * specularShading * vec3(specularTex);
|
||||
specular = vec3(0.0f);
|
||||
specular = light_specular * specularShading * vec3(1.0f);//vec3(specularTex);
|
||||
}
|
||||
|
||||
float computeAttenuation(vec3 lightPos, vec3 fragPos, float K_q)
|
||||
|
||||
@@ -3,19 +3,18 @@
|
||||
layout(location = 0) in vec3 a_position;
|
||||
layout(location = 1) in vec2 a_texCoord;
|
||||
layout(location = 2) in vec3 a_normal;
|
||||
layout(location = 3) in vec3 a_tangent;
|
||||
layout(location = 4) in vec3 a_bitangent;
|
||||
layout(location = 3) in vec4 a_tangent;
|
||||
|
||||
out vec3 v_normal;
|
||||
out vec2 v_texCoord;
|
||||
|
||||
out vec3 v_fragmentPosition;
|
||||
out vec3 v_fragmentPositionTangent;
|
||||
out vec4 v_fragmentPositionDirectionalLightSpace;
|
||||
|
||||
out vec3 v_viewPositionTangent;
|
||||
|
||||
struct DirectionalLight {
|
||||
struct DirectionalLight
|
||||
{
|
||||
vec3 direction;
|
||||
bool isActive;
|
||||
vec3 color;
|
||||
@@ -23,7 +22,8 @@ struct DirectionalLight {
|
||||
uniform DirectionalLight u_directionalLight;
|
||||
out vec3 v_lightDirectionTangent;
|
||||
|
||||
struct PointLight {
|
||||
struct PointLight
|
||||
{
|
||||
vec3 position;
|
||||
bool isActive;
|
||||
vec3 color;
|
||||
@@ -31,37 +31,27 @@ struct PointLight {
|
||||
#define NUM_POINT_LIGHTS 1
|
||||
uniform PointLight u_pointLight[NUM_POINT_LIGHTS];
|
||||
out vec3 v_lightPositionTangent0;
|
||||
//out vec3 v_lightPositionTangent1;
|
||||
//out vec3 v_lightPositionTangent2;
|
||||
//out vec3 v_lightPositionTangent3;
|
||||
|
||||
uniform vec3 u_viewPosition;
|
||||
|
||||
uniform mat4 u_modelViewProjMatrix;
|
||||
uniform mat4 u_modelMatrix;
|
||||
|
||||
uniform mat4 u_directionalLightViewProjMatrix;
|
||||
|
||||
void main() {
|
||||
void main()
|
||||
{
|
||||
gl_Position = u_modelViewProjMatrix * vec4(a_position, 1.0f);
|
||||
|
||||
vec3 T = normalize(vec3(u_modelMatrix * vec4(a_tangent, 0.0f)));
|
||||
vec3 B = normalize(vec3(u_modelMatrix * vec4(a_bitangent, 0.0f)));
|
||||
vec3 T = normalize(vec3(u_modelMatrix * vec4(a_tangent.xyz, 0.0f)));
|
||||
vec3 N = normalize(vec3(u_modelMatrix * vec4(a_normal, 0.0f)));
|
||||
T = normalize(T - dot(T, N) * N);
|
||||
vec3 B = cross(N, T) * a_tangent.w;
|
||||
mat3 TBN_transposed = transpose(mat3(T, B, N));
|
||||
|
||||
v_lightDirectionTangent = TBN_transposed * u_directionalLight.direction;
|
||||
v_lightPositionTangent0 = TBN_transposed * u_pointLight[0].position;
|
||||
//v_lightPositionTangent1 = vec3(0.0f);
|
||||
//v_lightPositionTangent2 = vec3(0.0f);
|
||||
//v_lightPositionTangent3 = vec3(0.0f);
|
||||
|
||||
v_fragmentPositionTangent = TBN_transposed * vec3(u_modelMatrix * vec4(a_position, 1.0f));
|
||||
|
||||
v_fragmentPosition = vec3(u_modelMatrix * vec4(a_position, 1.0f));
|
||||
v_fragmentPositionDirectionalLightSpace = u_directionalLightViewProjMatrix * vec4(v_fragmentPosition, 1.0f);
|
||||
|
||||
v_viewPositionTangent = TBN_transposed * u_viewPosition;
|
||||
v_viewPositionTangent = TBN_transposed * u_viewPosition; // seems like this is always 0 ?
|
||||
|
||||
v_normal = a_normal;
|
||||
v_texCoord = a_texCoord;
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#version 330 core
|
||||
|
||||
layout(location = 0) out vec4 f_color;
|
||||
|
||||
uniform vec3 v_lightColor;
|
||||
|
||||
void main() {
|
||||
f_color = vec4(v_lightColor, 1.0f);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#version 330 core
|
||||
|
||||
layout(location = 0) in vec3 a_position;
|
||||
|
||||
uniform mat4 u_modelViewProjMatrix;
|
||||
|
||||
void main() {
|
||||
gl_Position = u_modelViewProjMatrix * vec4(a_position, 1.0f);
|
||||
}
|
||||
@@ -42,25 +42,30 @@ void Camera::updatePositionFromKeyboardInput(KeyInput const &key_input, float de
|
||||
{
|
||||
glm::vec3 frontVecWithoutY = glm::vec3(m_front_vec.x, 0., m_front_vec.z);
|
||||
glm::vec3 deltaPos = glm::vec3(0., 0., 0.);
|
||||
float deltaFactor = SPEED * deltaTime * (m_accellerate ? 5.0 : 1.0);
|
||||
m_accellerate = false;
|
||||
|
||||
for (auto const &[key, pressed] : key_input) {
|
||||
if (key == GLFW_KEY_W && pressed) {
|
||||
deltaPos += SPEED * deltaTime * glm::normalize(frontVecWithoutY);
|
||||
deltaPos += deltaFactor * glm::normalize(frontVecWithoutY);
|
||||
}
|
||||
if (key == GLFW_KEY_S && pressed) {
|
||||
deltaPos -= SPEED * deltaTime * glm::normalize(frontVecWithoutY);
|
||||
deltaPos -= deltaFactor * glm::normalize(frontVecWithoutY);
|
||||
}
|
||||
if (key == GLFW_KEY_A && pressed) {
|
||||
deltaPos -= SPEED * deltaTime * glm::normalize(glm::cross(m_front_vec, UP_VEC));
|
||||
deltaPos -= deltaFactor * glm::normalize(glm::cross(m_front_vec, UP_VEC));
|
||||
}
|
||||
if (key == GLFW_KEY_D && pressed) {
|
||||
deltaPos += SPEED * deltaTime * glm::normalize(glm::cross(m_front_vec, UP_VEC));
|
||||
deltaPos += deltaFactor * glm::normalize(glm::cross(m_front_vec, UP_VEC));
|
||||
}
|
||||
if (key == GLFW_KEY_SPACE && pressed) {
|
||||
deltaPos += SPEED * deltaTime * UP_VEC;
|
||||
deltaPos += deltaFactor * UP_VEC;
|
||||
}
|
||||
if (key == GLFW_KEY_LEFT_SHIFT && pressed) {
|
||||
deltaPos -= SPEED * deltaTime * UP_VEC;
|
||||
deltaPos -= deltaFactor * UP_VEC;
|
||||
}
|
||||
if (key == GLFW_KEY_LEFT_ALT && pressed) {
|
||||
m_accellerate = true;
|
||||
}
|
||||
}
|
||||
m_position += deltaPos;
|
||||
|
||||
@@ -36,11 +36,13 @@ private:
|
||||
glm::vec3 m_front_vec = glm::vec3(0., 0., -1.);
|
||||
|
||||
static constexpr glm::vec3 UP_VEC = glm::vec3(0., 1., 0.);
|
||||
static constexpr float SPEED = 2.;
|
||||
static constexpr float SPEED = .5;
|
||||
static constexpr float DEFAULT_YAW = -90.;
|
||||
|
||||
float m_pitch{};
|
||||
float m_yaw = DEFAULT_YAW;
|
||||
|
||||
float m_fov;
|
||||
|
||||
bool m_accellerate = false;
|
||||
};
|
||||
|
||||
@@ -26,9 +26,11 @@ Controller::Controller()
|
||||
|
||||
std::string err;
|
||||
std::string warn;
|
||||
// bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "WaterBottle/glTF/WaterBottle.gltf");
|
||||
bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "WaterBottle/glTF/WaterBottle.gltf");
|
||||
// bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "Duck/glTF/Duck.gltf");
|
||||
// bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "Lantern/glTF/Lantern.gltf");
|
||||
bool ret = loader.LoadASCIIFromFile(&m_model, &err, &warn, "glTF/ABeautifulGame.gltf");
|
||||
// bool ret = loader.LoadBinaryFromFile(&m_model, &err, &warn, "Camera.glb");
|
||||
// bool ret = loader.LoadBinaryFromFile(&m_model, &err, &warn, "ABeautifulGame/ABeautifulGame.glb");
|
||||
|
||||
if (!warn.empty()) {
|
||||
Log::logger().warn("{}", warn);
|
||||
@@ -48,28 +50,34 @@ Controller::Controller()
|
||||
locations.position = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_position");
|
||||
locations.normal = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_normal");
|
||||
locations.uv = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_texCoord");
|
||||
locations.tangent = glGetAttribLocation(defaultProgram.getShaderProgramId(), "a_tangent");
|
||||
|
||||
ShaderProgram::unbind();
|
||||
|
||||
std::vector<Texture> textures;
|
||||
for (auto const &texture : m_model.textures) {
|
||||
textures.emplace_back(texture, m_model.images);
|
||||
}
|
||||
m_textures = std::move(textures);
|
||||
|
||||
std::vector<Model> models;
|
||||
for (auto const &mesh : m_model.meshes) {
|
||||
std::vector<Mesh> meshes;
|
||||
for (auto const &primitive : mesh.primitives) {
|
||||
auto const &material = m_model.materials.at(primitive.material);
|
||||
auto baseColorTexture = material.pbrMetallicRoughness.baseColorTexture;
|
||||
std::vector<std::reference_wrapper<const Texture>> textures;
|
||||
auto baseColorTexture = material.pbrMetallicRoughness.baseColorTexture.index;
|
||||
auto normalTexture = material.normalTexture.index;
|
||||
|
||||
if (baseColorTexture.index != -1) {
|
||||
textures.push_back(m_textures.at(baseColorTexture.index));
|
||||
std::vector<std::reference_wrapper<const Texture>> primitive_textures;
|
||||
|
||||
// Check if texture already exists, if not load it.
|
||||
if (baseColorTexture != -1 && !m_textures.contains(baseColorTexture)) {
|
||||
auto const &gltf_texture = m_model.textures.at(baseColorTexture);
|
||||
m_textures.emplace(baseColorTexture, Texture(gltf_texture, m_model.images, TextureType::Diffuse));
|
||||
primitive_textures.push_back(m_textures.at(baseColorTexture));
|
||||
}
|
||||
|
||||
meshes.emplace_back(Mesh({primitive, m_model, locations}, textures));
|
||||
if (normalTexture != -1 && !m_textures.contains(normalTexture)) {
|
||||
auto const &gltf_texture = m_model.textures.at(normalTexture);
|
||||
m_textures.emplace(normalTexture, Texture(gltf_texture, m_model.images, TextureType::Normal));
|
||||
primitive_textures.push_back(m_textures.at(normalTexture));
|
||||
}
|
||||
|
||||
meshes.emplace_back(Mesh({primitive, m_model, locations}, primitive_textures));
|
||||
}
|
||||
models.emplace_back(Model(mesh.name, std::move(meshes)));
|
||||
}
|
||||
@@ -112,9 +120,14 @@ 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),
|
||||
m_camera->translate(glm::vec3(0., .5, 2.));
|
||||
DirectionalLight directional_light(
|
||||
DirectionalLight::Prototype("", glm::vec3(-0.2, -1.0, -0.3), glm::vec3(1.0f), 5.f), &defaultProgram);
|
||||
directional_light.setActive(true);
|
||||
|
||||
PointLight point_light(PointLight::Prototype("", "", glm::vec3(4.0, 1.0, 6.0), glm::vec3(1.0F), 3.0F),
|
||||
&defaultProgram);
|
||||
point_light.setActive(true);
|
||||
|
||||
Log::logger().info("Startup complete. Enter game loop.");
|
||||
|
||||
@@ -124,9 +137,6 @@ void Controller::run()
|
||||
limit_framerate();
|
||||
|
||||
// --- Update game ---
|
||||
lightProgram.bind();
|
||||
lightProgram.setUniform("v_lightColor", glm::vec3{1., 1., 1.} * 100.0F);
|
||||
ShaderProgram::unbind();
|
||||
|
||||
// --- Render and buffer swap ---
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <memory>
|
||||
#include <tiny_gltf.h>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
class Window;
|
||||
class Scene;
|
||||
@@ -35,7 +36,6 @@ private:
|
||||
std::shared_ptr<Camera> m_camera;
|
||||
|
||||
ShaderProgram defaultProgram{{"defaultProgram", "data/shaders/basic.vert", "data/shaders/basic.frag"}};
|
||||
ShaderProgram lightProgram{{"lightProgram", "data/shaders/light.vert", "data/shaders/light.frag"}};
|
||||
ShaderProgram skyboxProgram{{"skyboxProgram", "data/shaders/skybox.vert", "data/shaders/skybox.frag"}};
|
||||
ShaderProgram postProcessingProgram{
|
||||
{"postProcessingProgram", "data/shaders/postprocessing.vert", "data/shaders/postprocessing.frag"}};
|
||||
@@ -48,7 +48,7 @@ private:
|
||||
|
||||
std::vector<ModelEntity> m_entities;
|
||||
std::vector<Model> m_models;
|
||||
std::vector<Texture> m_textures;
|
||||
std::unordered_map<unsigned, Texture> m_textures;
|
||||
|
||||
double m_deltaTime{};
|
||||
float m_exposure = 1.0;
|
||||
|
||||
@@ -106,11 +106,6 @@ void ModelEntity::draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition) const
|
||||
glm::mat4 modelViewProj = viewProjMatrix * m_modelMatrix;
|
||||
m_shaderProgram.setUniform("u_modelViewProjMatrix", modelViewProj);
|
||||
m_shaderProgram.setUniform("u_modelMatrix", m_modelMatrix);
|
||||
|
||||
glm::mat3 normalMatrix = glm::mat3(m_modelMatrix);
|
||||
normalMatrix = glm::transpose(glm::inverse(normalMatrix));
|
||||
m_shaderProgram.setUniform("u_normalMatrix", normalMatrix);
|
||||
|
||||
m_shaderProgram.setUniform("u_viewPosition", viewPosition);
|
||||
|
||||
// Draw the model
|
||||
@@ -119,31 +114,6 @@ void ModelEntity::draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition) const
|
||||
m_shaderProgram.unbind();
|
||||
}
|
||||
|
||||
void ModelEntity::drawDirectionalShadows(glm::mat4 viewProjMatrix, ShaderProgram *shaderProgram) const
|
||||
{
|
||||
shaderProgram->bind();
|
||||
|
||||
glm::mat4 modelViewProj = viewProjMatrix * m_modelMatrix;
|
||||
shaderProgram->setUniform("u_modelViewProjMatrix", modelViewProj);
|
||||
|
||||
// Draw the model
|
||||
m_model.drawWithoutTextures();
|
||||
|
||||
shaderProgram->unbind();
|
||||
}
|
||||
|
||||
void ModelEntity::drawPointShadows(ShaderProgram *shaderProgram) const
|
||||
{
|
||||
shaderProgram->bind();
|
||||
|
||||
shaderProgram->setUniform("u_modelMatrix", m_modelMatrix);
|
||||
|
||||
// Draw the model
|
||||
m_model.drawWithoutTextures();
|
||||
|
||||
shaderProgram->unbind();
|
||||
}
|
||||
|
||||
Skybox::Skybox(Prototype prototype, Model *cubeModel, ShaderProgram *shaderProgram)
|
||||
: m_cubeModel(cubeModel), m_shaderProgram(shaderProgram), m_vertexArray(cubeModel->getMesh(0)->getVertexArray())
|
||||
{
|
||||
|
||||
@@ -67,8 +67,6 @@ public:
|
||||
ModelEntity(Entity::Prototype prototype, Model const &model, ShaderProgram const &shaderProgram);
|
||||
|
||||
void draw(glm::mat4 viewProjMatrix, glm::vec3 viewPosition) const;
|
||||
void drawDirectionalShadows(glm::mat4 viewProjMatrix, ShaderProgram *p_shaderProgram) const;
|
||||
void drawPointShadows(ShaderProgram *p_shaderProgram) const;
|
||||
|
||||
private:
|
||||
Model const &m_model;
|
||||
|
||||
@@ -6,15 +6,12 @@
|
||||
uint32_t Light::s_idCounter = 0;
|
||||
|
||||
Light::Light(const std::string &name, glm::vec3 color, float intensity, ShaderProgram *shaderProgram)
|
||||
: Entity(name), m_shaderProgram(shaderProgram), m_intensity(intensity)
|
||||
: Entity(name), m_shaderProgram(shaderProgram), m_intensity(intensity), m_lightColor(color * intensity)
|
||||
{
|
||||
m_id = s_idCounter++;
|
||||
m_lightColor = color * intensity;
|
||||
}
|
||||
|
||||
Light::~Light()
|
||||
{
|
||||
}
|
||||
Light::~Light() = default;
|
||||
|
||||
glm::vec3 Light::getColor()
|
||||
{
|
||||
@@ -47,6 +44,7 @@ void Light::setActive(bool active)
|
||||
PointLight::PointLight(Prototype prototype, ShaderProgram *shaderProgram)
|
||||
: Light(prototype.name, prototype.color, prototype.intensity, shaderProgram), m_position(prototype.position)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void PointLight::update()
|
||||
|
||||
@@ -43,8 +43,7 @@ protected:
|
||||
uint32_t m_id;
|
||||
static uint32_t s_idCounter;
|
||||
|
||||
bool m_isActive;
|
||||
bool m_shouldCastShadow = true;
|
||||
bool m_isActive = true;
|
||||
|
||||
float m_intensity;
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ ShaderProgram::ShaderProgram(Prototype prototype) : m_shaderProgramId(glCreatePr
|
||||
glDeleteShader(fs);
|
||||
#endif
|
||||
|
||||
Log::logger().info(R"(Loaded shaderprogram "{}")", prototype.name);
|
||||
Log::logger().trace(R"(Loaded shaderprogram "{}".)", prototype.name);
|
||||
}
|
||||
|
||||
ShaderProgram::~ShaderProgram()
|
||||
@@ -98,7 +98,12 @@ auto ShaderProgram::retrieveUniformLocation(std::string_view uniform_name) const
|
||||
}
|
||||
|
||||
GLint location = glGetUniformLocation(m_shaderProgramId, uniform_name.data());
|
||||
m_uniformLocationCache[uniform_name.data()] = location;
|
||||
|
||||
if (location != -1) {
|
||||
m_uniformLocationCache[uniform_name.data()] = location;
|
||||
} else {
|
||||
Log::logger().warn(R"(Uniform "{}" not found.)", uniform_name);
|
||||
}
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
@@ -14,26 +14,31 @@ VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model c
|
||||
int position_accessor_id = primitive.attributes.at("POSITION");
|
||||
int normal_accessor_id = primitive.attributes.at("NORMAL");
|
||||
int uv_accessor_id = primitive.attributes.at("TEXCOORD_0");
|
||||
int tangent_accessor_id = primitive.attributes.at("TANGENT");
|
||||
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 &tangent_accessor = model.accessors.at(tangent_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 tangent_buffer_view_id = model.accessors[tangent_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 &tangent_buffer_view = model.bufferViews.at(tangent_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 &tangent_buffer = model.buffers.at(tangent_buffer_view.buffer);
|
||||
auto const &indices_buffer = model.buffers.at(indices_buffer_view.buffer);
|
||||
|
||||
GLuint positionVbo{};
|
||||
@@ -94,8 +99,8 @@ VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model c
|
||||
{
|
||||
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);
|
||||
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) {
|
||||
@@ -117,6 +122,33 @@ VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model c
|
||||
(void *)uv_accessor.byteOffset);
|
||||
}
|
||||
|
||||
GLuint tangentVbo{};
|
||||
{
|
||||
glGenBuffers(1, &tangentVbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, tangentVbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, tangent_buffer_view.byteLength, tangent_buffer.data.data() + tangent_buffer_view.byteOffset,
|
||||
GL_STATIC_DRAW);
|
||||
|
||||
int size = 1;
|
||||
if (tangent_accessor.type == TINYGLTF_TYPE_SCALAR) {
|
||||
size = 1;
|
||||
} else if (tangent_accessor.type == TINYGLTF_TYPE_VEC2) {
|
||||
size = 2;
|
||||
} else if (tangent_accessor.type == TINYGLTF_TYPE_VEC3) {
|
||||
size = 3;
|
||||
} else if (tangent_accessor.type == TINYGLTF_TYPE_VEC4) {
|
||||
size = 4;
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
int tangent_byte_stride = tangent_accessor.ByteStride(tangent_buffer_view);
|
||||
glEnableVertexAttribArray(locations.tangent);
|
||||
glVertexAttribPointer(locations.tangent, size, tangent_accessor.componentType,
|
||||
tangent_accessor.normalized ? GL_TRUE : GL_FALSE, tangent_byte_stride,
|
||||
(void *)tangent_accessor.byteOffset);
|
||||
}
|
||||
|
||||
GLuint ebo{};
|
||||
glGenBuffers(1, &ebo);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||
@@ -130,6 +162,7 @@ VertexArray::VertexArray(tinygltf::Primitive const &primitive, tinygltf::Model c
|
||||
m_positionVbo = positionVbo;
|
||||
m_normalVbo = normalVbo;
|
||||
m_uvVbo = uvVbo;
|
||||
m_tangentVbo = tangentVbo;
|
||||
m_indicesCount = indices_accessor.count;
|
||||
m_indicesType = indices_accessor.componentType;
|
||||
}
|
||||
@@ -141,6 +174,7 @@ VertexArray::~VertexArray()
|
||||
glDeleteBuffers(1, &m_positionVbo);
|
||||
glDeleteBuffers(1, &m_normalVbo);
|
||||
glDeleteBuffers(1, &m_uvVbo);
|
||||
glDeleteBuffers(1, &m_tangentVbo);
|
||||
glDeleteBuffers(1, &m_ebo);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
m_positionVbo(other.m_positionVbo),
|
||||
m_normalVbo(other.m_normalVbo),
|
||||
m_uvVbo(other.m_uvVbo),
|
||||
m_tangentVbo(other.m_tangentVbo),
|
||||
m_ebo(other.m_ebo)
|
||||
{
|
||||
other.m_ebo = 0;
|
||||
@@ -24,6 +25,7 @@ public:
|
||||
other.m_positionVbo = 0;
|
||||
other.m_normalVbo = 0;
|
||||
other.m_uvVbo = 0;
|
||||
other.m_tangentVbo = 0;
|
||||
}
|
||||
|
||||
auto operator=(VertexArray &&other) noexcept -> VertexArray &
|
||||
@@ -34,6 +36,7 @@ public:
|
||||
m_positionVbo = other.m_positionVbo;
|
||||
m_normalVbo = other.m_normalVbo;
|
||||
m_uvVbo = other.m_uvVbo;
|
||||
m_tangentVbo = other.m_tangentVbo;
|
||||
m_ebo = other.m_ebo;
|
||||
|
||||
other.m_ebo = 0;
|
||||
@@ -41,6 +44,7 @@ public:
|
||||
other.m_positionVbo = 0;
|
||||
other.m_normalVbo = 0;
|
||||
other.m_uvVbo = 0;
|
||||
other.m_tangentVbo = 0;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -65,5 +69,6 @@ private:
|
||||
GLuint m_positionVbo;
|
||||
GLuint m_normalVbo;
|
||||
GLuint m_uvVbo;
|
||||
GLuint m_tangentVbo;
|
||||
GLuint m_ebo;
|
||||
};
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
Window::Window()
|
||||
{
|
||||
// Hint Wayland preference to GLFW
|
||||
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);
|
||||
// glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);
|
||||
|
||||
// Initialize GLFW
|
||||
if (glfwInit() == 0) {
|
||||
@@ -19,7 +19,7 @@ Window::Window()
|
||||
m_width = INIT_WINDOW_WIDTH;
|
||||
m_height = INIT_WINDOW_HEIGHT;
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
@@ -62,7 +62,7 @@ Window::Window()
|
||||
#ifndef NDEBUG
|
||||
Log::logger().debug("OpenGL version: {}", reinterpret_cast<const char *>(glGetString(GL_VERSION))); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
glDebugMessageCallback(Helper::gl_debug_callback, nullptr);
|
||||
glDebugMessageCallback(&Helper::gl_debug_callback, nullptr);
|
||||
|
||||
// Disable mouse cursor
|
||||
m_mouse_catched = false;
|
||||
@@ -90,9 +90,6 @@ Window::Window()
|
||||
glfwSetKeyCallback(m_glfw_window.get(), key_callback);
|
||||
glfwSetMouseButtonCallback(m_glfw_window.get(), mouse_button_callback);
|
||||
glfwSetCursorPosCallback(m_glfw_window.get(), mouse_cursor_callback);
|
||||
|
||||
// Tell GLFW which function to call when window is resized
|
||||
// glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
}
|
||||
|
||||
auto Window::dimensions_changed() const -> bool
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#include "Model.h"
|
||||
#include "Texture.h"
|
||||
#include "../util/Log.h"
|
||||
|
||||
Model::Model(std::string_view name, std::vector<Mesh> meshes) : m_meshes(std::move(meshes)), m_name(name)
|
||||
{
|
||||
Log::logger().trace(R"(Loaded model "{}".)", name);
|
||||
}
|
||||
|
||||
void Model::draw(ShaderProgram const &shaderProgram) const
|
||||
|
||||
@@ -2,70 +2,12 @@
|
||||
#include "../ShaderProgram.h"
|
||||
#include "../util/Log.h"
|
||||
|
||||
#include <stb/stb_image.h>
|
||||
|
||||
// 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<unsigned>(textureWidth);
|
||||
// m_textureHeight = static_cast<unsigned>(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<GLint>(internalFormat), static_cast<GLsizei>(m_textureWidth),
|
||||
// static_cast<GLsizei>(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<tinygltf::Image> images)
|
||||
Texture::Texture(tinygltf::Texture const &texture, std::span<tinygltf::Image> images, TextureType textureType)
|
||||
: m_textureType(textureType)
|
||||
{
|
||||
auto sampler = texture.sampler;
|
||||
auto const &image = images[texture.source];
|
||||
|
||||
m_textureType = TextureType::Diffuse;
|
||||
|
||||
uint32_t width = image.width;
|
||||
uint32_t height = image.height;
|
||||
unsigned int components = image.component;
|
||||
@@ -103,6 +45,8 @@ Texture::Texture(tinygltf::Texture const &texture, std::span<tinygltf::Image> im
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
Log::logger().trace(R"(Loaded texture "{}".)", image.name);
|
||||
}
|
||||
|
||||
auto Texture::textureType() const -> TextureType
|
||||
@@ -115,7 +59,6 @@ void Texture::bind(uint8_t textureUnit, ShaderProgram const &shaderProgram) cons
|
||||
std::string uniformName = "texture_";
|
||||
|
||||
switch (m_textureType) {
|
||||
|
||||
case TextureType::Diffuse:
|
||||
uniformName += "diffuse";
|
||||
break;
|
||||
|
||||
@@ -9,17 +9,10 @@
|
||||
|
||||
class ShaderProgram;
|
||||
|
||||
// struct TextureDescriptor
|
||||
// {
|
||||
// std::string path;
|
||||
// TextureType textureType;
|
||||
// };
|
||||
|
||||
class Texture
|
||||
{
|
||||
public:
|
||||
// Texture(const TextureDescriptor &descriptor);
|
||||
Texture(tinygltf::Texture const &texture, std::span<tinygltf::Image> images);
|
||||
Texture(tinygltf::Texture const &texture, std::span<tinygltf::Image> images, TextureType textureType);
|
||||
|
||||
[[nodiscard]] auto textureType() const -> TextureType;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "Log.h"
|
||||
|
||||
#include <spdlog/sinks/stdout_color_sinks.h>
|
||||
#include <spdlog/cfg/env.h>
|
||||
|
||||
Log Log::s_instance;
|
||||
|
||||
@@ -14,6 +15,9 @@ Log::Log() noexcept
|
||||
#else
|
||||
m_logger->set_level(spdlog::level::warn);
|
||||
#endif
|
||||
|
||||
// Override level when running with environment variable.
|
||||
spdlog::cfg::load_env_levels();
|
||||
}
|
||||
|
||||
spdlog::logger &Log::logger()
|
||||
|
||||
Reference in New Issue
Block a user