Add ability to load model
This commit is contained in:
parent
da892ceee5
commit
9d0c832f3c
@ -19,7 +19,10 @@ file(GLOB IMGUI_SOURCES
|
|||||||
${CMAKE_CURRENT_LIST_DIR}/include/imgui/*.cpp
|
${CMAKE_CURRENT_LIST_DIR}/include/imgui/*.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
file(GLOB TINY_GLTF_SOURCES ${CMAKE_CURRENT_LIST_DIR}/include/tiny_gltf/*.cc)
|
||||||
|
|
||||||
target_sources(Main PRIVATE ${IMGUI_SOURCES})
|
target_sources(Main PRIVATE ${IMGUI_SOURCES})
|
||||||
|
target_sources(Main PRIVATE ${TINY_GLTF_SOURCES})
|
||||||
|
|
||||||
find_package(glfw3 3.4 REQUIRED)
|
find_package(glfw3 3.4 REQUIRED)
|
||||||
set(OpenGL_GL_PREFERENCE GLVND)
|
set(OpenGL_GL_PREFERENCE GLVND)
|
||||||
@ -41,21 +44,19 @@ add_custom_command(TARGET Shaders POST_BUILD
|
|||||||
"$<TARGET_PROPERTY:Main,BINARY_DIR>/$<CONFIGURATION>/shaders"
|
"$<TARGET_PROPERTY:Main,BINARY_DIR>/$<CONFIGURATION>/shaders"
|
||||||
)
|
)
|
||||||
|
|
||||||
# copy textures
|
|
||||||
file(GLOB TEX_SOURCE_FILES
|
|
||||||
textures/*
|
|
||||||
)
|
|
||||||
|
|
||||||
|
# copy assets
|
||||||
|
file(GLOB ASSET_FILES assets/*)
|
||||||
add_custom_target(
|
add_custom_target(
|
||||||
Textures
|
Assets
|
||||||
DEPENDS ${TEX_SOURCE_FILES}
|
DEPENDS ${ASSET_FILES}
|
||||||
)
|
)
|
||||||
add_dependencies(Main Textures)
|
add_dependencies(Main Assets)
|
||||||
|
|
||||||
add_custom_command(TARGET Textures POST_BUILD
|
add_custom_command(TARGET Assets POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
"$<TARGET_PROPERTY:Main,SOURCE_DIR>/assets/textures"
|
"$<TARGET_PROPERTY:Main,SOURCE_DIR>/assets"
|
||||||
"$<TARGET_PROPERTY:Main,BINARY_DIR>/$<CONFIGURATION>/assets/textures"
|
"$<TARGET_PROPERTY:Main,BINARY_DIR>/$<CONFIGURATION>/assets"
|
||||||
)
|
)
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
|
|||||||
24757
assets/models/woman.gltf
Normal file
24757
assets/models/woman.gltf
Normal file
File diff suppressed because one or more lines are too long
BIN
assets/textures/woman.png
Normal file
BIN
assets/textures/woman.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 196 B |
1724
include/stb_image_write.h
Normal file
1724
include/stb_image_write.h
Normal file
File diff suppressed because it is too large
Load Diff
26753
include/tiny_gltf/json.hpp
Normal file
26753
include/tiny_gltf/json.hpp
Normal file
File diff suppressed because it is too large
Load Diff
4
include/tiny_gltf/tiny_gltf.cc
Normal file
4
include/tiny_gltf/tiny_gltf.cc
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#define TINYGLTF_IMPLEMENTATION
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||||
|
#include "tiny_gltf.h"
|
||||||
8744
include/tiny_gltf/tiny_gltf.h
Normal file
8744
include/tiny_gltf/tiny_gltf.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,12 +1,15 @@
|
|||||||
#version 460 core
|
#version 460 core
|
||||||
|
|
||||||
layout (location = 0) in vec4 tex_color;
|
layout (location = 0) in vec3 normal;
|
||||||
layout (location = 1) in vec2 tex_coord;
|
layout (location = 1) in vec2 tex_coord;
|
||||||
|
|
||||||
out vec4 frag_color;
|
out vec4 frag_color;
|
||||||
|
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
|
vec3 light_pos = vec3(4.0, 5.0, -3.0);
|
||||||
|
vec3 light_color = vec3(0.5, 0.5, 0.5);
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
frag_color = texture(tex, tex_coord) * tex_color;
|
float light_angle = max(dot(normalize(normal), normalize(light_pos)), 0.0);
|
||||||
|
frag_color = texture(tex, tex_coord) * vec4((0.3 + 0.7 * light_angle) * light_color, 1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,20 @@
|
|||||||
#version 460 core
|
#version 460 core
|
||||||
|
|
||||||
layout (location = 0) in vec3 a_pos;
|
layout (location = 0) in vec3 a_pos;
|
||||||
layout (location = 1) in vec3 a_color;
|
layout (location = 1) in vec3 a_normal;
|
||||||
layout (location = 2) in vec2 a_tex_coord;
|
layout (location = 2) in vec2 a_tex_coord;
|
||||||
|
|
||||||
|
layout (location = 0) out vec3 normal;
|
||||||
|
layout (location = 1) out vec2 tex_coord;
|
||||||
|
|
||||||
layout (std140, binding = 0) uniform Matrices {
|
layout (std140, binding = 0) uniform Matrices {
|
||||||
mat4 view;
|
mat4 view;
|
||||||
mat4 projection;
|
mat4 projection;
|
||||||
};
|
};
|
||||||
|
|
||||||
layout (location = 0) out vec4 tex_color;
|
|
||||||
layout (location = 1) out vec2 tex_coord;
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_Position = projection * view * vec4(a_pos, 1.0);
|
gl_Position = projection * view * vec4(a_pos, 1.0);
|
||||||
tex_color = vec4(a_color, 1.0);
|
normal = a_normal;
|
||||||
tex_coord = a_tex_coord;
|
tex_coord = a_tex_coord;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
274
src/model.cpp
274
src/model.cpp
@ -1,137 +1,161 @@
|
|||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
void init_model(Model *model) {
|
bool load_model(Model *model, Render_Data *render_data, string model_filepath, string texture_filepath) {
|
||||||
model->vertex_data.vertices.resize(36);
|
{
|
||||||
|
bool success = load_texture(&model->texture, texture_filepath);
|
||||||
|
if (!success) {
|
||||||
|
log(1, "%s: failed to load texture\n", __FUNCTION__);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* front */
|
model->gltf_model = new tinygltf::Model();
|
||||||
model->vertex_data.vertices[0].position = Vector3(-0.5f, -0.5f, 0.5f);
|
tinygltf::TinyGLTF gltf_loader;
|
||||||
model->vertex_data.vertices[1].position = Vector3( 0.5f, 0.5f, 0.5f);
|
string loader_errors;
|
||||||
model->vertex_data.vertices[2].position = Vector3(-0.5f, 0.5f, 0.5f);
|
string loader_warnings;
|
||||||
model->vertex_data.vertices[3].position = Vector3(-0.5f, -0.5f, 0.5f);
|
bool result = false;
|
||||||
model->vertex_data.vertices[4].position = Vector3( 0.5f, -0.5f, 0.5f);
|
result = gltf_loader.LoadASCIIFromFile(model->gltf_model, &loader_errors, &loader_warnings, model_filepath);
|
||||||
model->vertex_data.vertices[5].position = Vector3( 0.5f, 0.5f, 0.5f);
|
|
||||||
|
|
||||||
model->vertex_data.vertices[0].color = Vector3(1.0f, 0.5f, 0.5f);
|
if (!loader_warnings.empty()) {
|
||||||
model->vertex_data.vertices[1].color = Vector3(1.0f, 0.5f, 0.5f);
|
log(1, "%s: warnings while loading glTF model:\n%s", __FUNCTION__, loader_warnings.c_str());
|
||||||
model->vertex_data.vertices[2].color = Vector3(1.0f, 0.5f, 0.5f);
|
}
|
||||||
model->vertex_data.vertices[3].color = Vector3(1.0f, 0.5f, 0.5f);
|
|
||||||
model->vertex_data.vertices[4].color = Vector3(1.0f, 0.5f, 0.5f);
|
|
||||||
model->vertex_data.vertices[5].color = Vector3(1.0f, 0.5f, 0.5f);
|
|
||||||
|
|
||||||
model->vertex_data.vertices[0].uv = Vector2(0.0, 0.0);
|
if (!loader_errors.empty()) {
|
||||||
model->vertex_data.vertices[1].uv = Vector2(1.0, 1.0);
|
log(1, "%s: errors while loading glTF model:\n%s", __FUNCTION__, loader_errors.c_str());
|
||||||
model->vertex_data.vertices[2].uv = Vector2(0.0, 1.0);
|
}
|
||||||
model->vertex_data.vertices[3].uv = Vector2(0.0, 0.0);
|
|
||||||
model->vertex_data.vertices[4].uv = Vector2(1.0, 0.0);
|
|
||||||
model->vertex_data.vertices[5].uv = Vector2(1.0, 1.0);
|
|
||||||
|
|
||||||
/* back */
|
if (!result) {
|
||||||
model->vertex_data.vertices[6].position = Vector3(-0.5f, -0.5f, -0.5f);
|
log(1, "%s error: could not load file '%s'\n", __FUNCTION__, model_filepath.c_str());
|
||||||
model->vertex_data.vertices[7].position = Vector3(-0.5f, 0.5f, -0.5f);
|
return false;
|
||||||
model->vertex_data.vertices[8].position = Vector3( 0.5f, 0.5f, -0.5f);
|
}
|
||||||
model->vertex_data.vertices[9].position = Vector3(-0.5f, -0.5f, -0.5f);
|
|
||||||
model->vertex_data.vertices[10].position = Vector3( 0.5f, 0.5f, -0.5f);
|
|
||||||
model->vertex_data.vertices[11].position = Vector3( 0.5f, -0.5f, -0.5f);
|
|
||||||
|
|
||||||
model->vertex_data.vertices[6].color = Vector3(0.5f, 1.0f, 0.5f);
|
glGenVertexArrays(1, &model->vao);
|
||||||
model->vertex_data.vertices[7].color = Vector3(0.5f, 1.0f, 0.5f);
|
glBindVertexArray(model->vao);
|
||||||
model->vertex_data.vertices[8].color = Vector3(0.5f, 1.0f, 0.5f);
|
|
||||||
model->vertex_data.vertices[9].color = Vector3(0.5f, 1.0f, 0.5f);
|
|
||||||
model->vertex_data.vertices[10].color = Vector3(0.5f, 1.0f, 0.5f);
|
|
||||||
model->vertex_data.vertices[11].color = Vector3(0.5f, 1.0f, 0.5f);
|
|
||||||
|
|
||||||
model->vertex_data.vertices[6].uv = Vector2(1.0, 0.0);
|
create_model_vertex_buffers(model);
|
||||||
model->vertex_data.vertices[7].uv = Vector2(1.0, 1.0);
|
create_model_index_buffer(model);
|
||||||
model->vertex_data.vertices[8].uv = Vector2(0.0, 1.0);
|
|
||||||
model->vertex_data.vertices[9].uv = Vector2(1.0, 0.0);
|
|
||||||
model->vertex_data.vertices[10].uv = Vector2(0.0, 1.0);
|
|
||||||
model->vertex_data.vertices[11].uv = Vector2(0.0, 0.0);
|
|
||||||
|
|
||||||
/* left */
|
glBindVertexArray(0);
|
||||||
model->vertex_data.vertices[12].position = Vector3(-0.5f, -0.5f, 0.5f);
|
|
||||||
model->vertex_data.vertices[13].position = Vector3(-0.5f, 0.5f, 0.5f);
|
|
||||||
model->vertex_data.vertices[14].position = Vector3(-0.5f, 0.5f, -0.5f);
|
|
||||||
model->vertex_data.vertices[15].position = Vector3(-0.5f, -0.5f, 0.5f);
|
|
||||||
model->vertex_data.vertices[16].position = Vector3(-0.5f, 0.5f, -0.5f);
|
|
||||||
model->vertex_data.vertices[17].position = Vector3(-0.5f, -0.5f, -0.5f);
|
|
||||||
|
|
||||||
model->vertex_data.vertices[12].color = Vector3(0.5f, 0.5f, 1.0f);
|
render_data->triangle_count = get_model_triangle_count(model);
|
||||||
model->vertex_data.vertices[13].color = Vector3(0.5f, 0.5f, 1.0f);
|
|
||||||
model->vertex_data.vertices[14].color = Vector3(0.5f, 0.5f, 1.0f);
|
|
||||||
model->vertex_data.vertices[15].color = Vector3(0.5f, 0.5f, 1.0f);
|
|
||||||
model->vertex_data.vertices[16].color = Vector3(0.5f, 0.5f, 1.0f);
|
|
||||||
model->vertex_data.vertices[17].color = Vector3(0.5f, 0.5f, 1.0f);
|
|
||||||
|
|
||||||
model->vertex_data.vertices[12].uv = Vector2(1.0, 0.0);
|
return true;
|
||||||
model->vertex_data.vertices[13].uv = Vector2(1.0, 1.0);
|
}
|
||||||
model->vertex_data.vertices[14].uv = Vector2(0.0, 1.0);
|
|
||||||
model->vertex_data.vertices[15].uv = Vector2(1.0, 0.0);
|
void draw_model(Model *model) {
|
||||||
model->vertex_data.vertices[16].uv = Vector2(0.0, 1.0);
|
const tinygltf::Primitive& primitives = model->gltf_model->meshes.at(0).primitives.at(0);
|
||||||
model->vertex_data.vertices[17].uv = Vector2(0.0, 0.0);
|
const tinygltf::Accessor& index_accessor = model->gltf_model->accessors.at(primitives.indices);
|
||||||
|
u32 draw_mode = GL_TRIANGLES;
|
||||||
/* right */
|
switch (primitives.mode) {
|
||||||
model->vertex_data.vertices[18].position = Vector3(0.5f, -0.5f, 0.5f);
|
case TINYGLTF_MODE_TRIANGLES:
|
||||||
model->vertex_data.vertices[19].position = Vector3(0.5f, 0.5f, -0.5f);
|
draw_mode = GL_TRIANGLES;
|
||||||
model->vertex_data.vertices[20].position = Vector3(0.5f, 0.5f, 0.5f);
|
break;
|
||||||
model->vertex_data.vertices[21].position = Vector3(0.5f, -0.5f, 0.5f);
|
default:
|
||||||
model->vertex_data.vertices[22].position = Vector3(0.5f, -0.5f, -0.5f);
|
log(1, "%s error: unknown draw mode %i\n", __FUNCTION__, draw_mode);
|
||||||
model->vertex_data.vertices[23].position = Vector3(0.5f, 0.5f, -0.5f);
|
break;
|
||||||
|
}
|
||||||
model->vertex_data.vertices[18].color = Vector3(0.0f, 0.5f, 0.5f);
|
|
||||||
model->vertex_data.vertices[19].color = Vector3(0.0f, 0.5f, 0.5f);
|
bind_texture(&model->texture);
|
||||||
model->vertex_data.vertices[20].color = Vector3(0.0f, 0.5f, 0.5f);
|
glBindVertexArray(model->vao);
|
||||||
model->vertex_data.vertices[21].color = Vector3(0.0f, 0.5f, 0.5f);
|
glDrawElements(draw_mode, index_accessor.count, index_accessor.componentType, nullptr);
|
||||||
model->vertex_data.vertices[22].color = Vector3(0.0f, 0.5f, 0.5f);
|
glBindVertexArray(0);
|
||||||
model->vertex_data.vertices[23].color = Vector3(0.0f, 0.5f, 0.5f);
|
unbind_texture();
|
||||||
|
}
|
||||||
model->vertex_data.vertices[18].uv = Vector2(0.0, 0.0);
|
|
||||||
model->vertex_data.vertices[19].uv = Vector2(1.0, 1.0);
|
void cleanup_model(Model *model) {
|
||||||
model->vertex_data.vertices[20].uv = Vector2(0.0, 1.0);
|
glDeleteBuffers(model->vertex_vbo.size(), model->vertex_vbo.data());
|
||||||
model->vertex_data.vertices[21].uv = Vector2(0.0, 0.0);
|
glDeleteBuffers(1, &model->vao);
|
||||||
model->vertex_data.vertices[22].uv = Vector2(1.0, 0.0);
|
glDeleteBuffers(1, &model->index_vbo);
|
||||||
model->vertex_data.vertices[23].uv = Vector2(1.0, 1.0);
|
cleanup_texture(&model->texture);
|
||||||
|
delete model->gltf_model;
|
||||||
/* top */
|
}
|
||||||
model->vertex_data.vertices[24].position = Vector3( 0.5f, 0.5f, 0.5f);
|
|
||||||
model->vertex_data.vertices[25].position = Vector3(-0.5f, 0.5f, -0.5f);
|
void create_model_vertex_buffers(Model *model) {
|
||||||
model->vertex_data.vertices[26].position = Vector3(-0.5f, 0.5f, 0.5f);
|
const tinygltf::Primitive &primitives = model->gltf_model->meshes.at(0).primitives.at(0);
|
||||||
model->vertex_data.vertices[27].position = Vector3( 0.5f, 0.5f, 0.5f);
|
model->vertex_vbo.resize(primitives.attributes.size());
|
||||||
model->vertex_data.vertices[28].position = Vector3( 0.5f, 0.5f, -0.5f);
|
|
||||||
model->vertex_data.vertices[29].position = Vector3(-0.5f, 0.5f, -0.5f);
|
for (const auto& attrib : primitives.attributes) {
|
||||||
|
const string attrib_type = attrib.first;
|
||||||
model->vertex_data.vertices[24].color = Vector3(0.5f, 0.0f, 0.5f);
|
const s32 accessor_num = attrib.second;
|
||||||
model->vertex_data.vertices[25].color = Vector3(0.5f, 0.0f, 0.5f);
|
const tinygltf::Accessor &accessor = model->gltf_model->accessors.at(accessor_num);
|
||||||
model->vertex_data.vertices[26].color = Vector3(0.5f, 0.0f, 0.5f);
|
const tinygltf::BufferView &buffer_view = model->gltf_model->bufferViews[accessor.bufferView];
|
||||||
model->vertex_data.vertices[27].color = Vector3(0.5f, 0.0f, 0.5f);
|
const tinygltf::Buffer &buffer = model->gltf_model->buffers[buffer_view.buffer];
|
||||||
model->vertex_data.vertices[28].color = Vector3(0.5f, 0.0f, 0.5f);
|
|
||||||
model->vertex_data.vertices[29].color = Vector3(0.5f, 0.0f, 0.5f);
|
if ((attrib_type.compare("POSITION") != 0) &&
|
||||||
|
(attrib_type.compare("NORMAL") != 0) &&
|
||||||
model->vertex_data.vertices[24].uv = Vector2(0.0, 0.0);
|
(attrib_type.compare("TEXCOORD_0") != 0)) {
|
||||||
model->vertex_data.vertices[25].uv = Vector2(1.0, 1.0);
|
log(1, "%s: skipping attribute type %s\n", __FUNCTION__, attrib_type.c_str());
|
||||||
model->vertex_data.vertices[26].uv = Vector2(0.0, 1.0);
|
continue;
|
||||||
model->vertex_data.vertices[27].uv = Vector2(0.0, 0.0);
|
}
|
||||||
model->vertex_data.vertices[28].uv = Vector2(1.0, 0.0);
|
|
||||||
model->vertex_data.vertices[29].uv = Vector2(1.0, 1.0);
|
s32 data_size = 1;
|
||||||
|
switch(accessor.type) {
|
||||||
/* bottom */
|
case TINYGLTF_TYPE_SCALAR:
|
||||||
model->vertex_data.vertices[30].position = Vector3( 0.5f, -0.5f, 0.5f);
|
data_size = 1;
|
||||||
model->vertex_data.vertices[31].position = Vector3(-0.5f, -0.5f, 0.5f);
|
break;
|
||||||
model->vertex_data.vertices[32].position = Vector3(-0.5f, -0.5f, -0.5f);
|
case TINYGLTF_TYPE_VEC2:
|
||||||
model->vertex_data.vertices[33].position = Vector3( 0.5f, -0.5f, 0.5f);
|
data_size = 2;
|
||||||
model->vertex_data.vertices[34].position = Vector3(-0.5f, -0.5f, -0.5f);
|
break;
|
||||||
model->vertex_data.vertices[35].position = Vector3( 0.5f, -0.5f, -0.5f);
|
case TINYGLTF_TYPE_VEC3:
|
||||||
|
data_size = 3;
|
||||||
model->vertex_data.vertices[30].color = Vector3(0.5f, 0.5f, 0.0f);
|
break;
|
||||||
model->vertex_data.vertices[31].color = Vector3(0.5f, 0.5f, 0.0f);
|
case TINYGLTF_TYPE_VEC4:
|
||||||
model->vertex_data.vertices[32].color = Vector3(0.5f, 0.5f, 0.0f);
|
data_size = 4;
|
||||||
model->vertex_data.vertices[33].color = Vector3(0.5f, 0.5f, 0.0f);
|
break;
|
||||||
model->vertex_data.vertices[34].color = Vector3(0.5f, 0.5f, 0.0f);
|
default:
|
||||||
model->vertex_data.vertices[35].color = Vector3(0.5f, 0.5f, 0.0f);
|
log(1, "%s error: accessor %i uses data size %i\n", __FUNCTION__, accessor_num, data_size);
|
||||||
|
break;
|
||||||
model->vertex_data.vertices[30].uv = Vector2(0.0, 1.0);
|
}
|
||||||
model->vertex_data.vertices[31].uv = Vector2(0.0, 0.0);
|
|
||||||
model->vertex_data.vertices[32].uv = Vector2(1.0, 0.0);
|
u32 data_type = GL_FLOAT;
|
||||||
model->vertex_data.vertices[33].uv = Vector2(0.0, 1.0);
|
switch(accessor.componentType) {
|
||||||
model->vertex_data.vertices[34].uv = Vector2(1.0, 0.0);
|
case TINYGLTF_COMPONENT_TYPE_FLOAT:
|
||||||
model->vertex_data.vertices[35].uv = Vector2(1.0, 1.0);
|
data_type = GL_FLOAT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log(1, "%s error: accessor %i uses unknown data type %i\n", __FUNCTION__, accessor_num, data_type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGenBuffers(1, &model->vertex_vbo.at(model->attributes.at(attrib_type)));
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, model->vertex_vbo.at(model->attributes.at(attrib_type)));
|
||||||
|
|
||||||
|
glVertexAttribPointer(model->attributes.at(attrib_type), data_size, data_type, GL_FALSE, 0, (void*) 0);
|
||||||
|
glEnableVertexAttribArray(model->attributes.at(attrib_type));
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_model_index_buffer(Model *model) {
|
||||||
|
glGenBuffers(1, &model->index_vbo);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->index_vbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void upload_model_vertex_buffers(Model *model) {
|
||||||
|
for (s32 i = 0; i < 3; ++i) {
|
||||||
|
const tinygltf::Accessor& accessor = model->gltf_model->accessors.at(i);
|
||||||
|
const tinygltf::BufferView& buffer_view = model->gltf_model->bufferViews.at(accessor.bufferView);
|
||||||
|
const tinygltf::Buffer& buffer = model->gltf_model->buffers.at(buffer_view.buffer);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, model->vertex_vbo[i]);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, buffer_view.byteLength, &buffer.data.at(0) + buffer_view.byteOffset, GL_STATIC_DRAW);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void upload_model_index_buffer(Model *model) {
|
||||||
|
const tinygltf::Primitive& primitives = model->gltf_model->meshes.at(0).primitives.at(0);
|
||||||
|
const tinygltf::Accessor& index_accessor = model->gltf_model->accessors.at(primitives.indices);
|
||||||
|
const tinygltf::BufferView& index_buffer_view = model->gltf_model->bufferViews.at(index_accessor.bufferView);
|
||||||
|
const tinygltf::Buffer& index_buffer = model->gltf_model->buffers.at(index_buffer_view.buffer);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model->index_vbo);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_view.byteLength, &index_buffer.data.at(0) + index_buffer_view.byteOffset, GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 get_model_triangle_count(Model *model) {
|
||||||
|
const tinygltf::Primitive& primitives = model->gltf_model->meshes.at(0).primitives.at(0);
|
||||||
|
const tinygltf::Accessor& index_accessor = model->gltf_model->accessors.at(primitives.indices);
|
||||||
|
|
||||||
|
return index_accessor.count;
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/model.h
22
src/model.h
@ -4,10 +4,26 @@
|
|||||||
#include "basic.h"
|
#include "basic.h"
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
#include "renderer.h"
|
#include <tiny_gltf/tiny_gltf.h>
|
||||||
|
#include "texture.h"
|
||||||
|
#include "render_data.h"
|
||||||
|
|
||||||
struct Model {
|
struct Model {
|
||||||
Mesh vertex_data;
|
tinygltf::Model* gltf_model = nullptr;
|
||||||
|
u32 vao = 0;
|
||||||
|
std::vector<u32> vertex_vbo;
|
||||||
|
u32 index_vbo = 0;
|
||||||
|
std::map<string, s32> attributes = {{"POSITION", 0}, {"NORMAL", 1}, {"TEXCOORD_0", 2}};
|
||||||
|
Texture texture;
|
||||||
};
|
};
|
||||||
|
|
||||||
void init_model(Model *model);
|
|
||||||
|
bool load_model(Model *model, Render_Data *render_data, string model_filepath, string texture_filepath);
|
||||||
|
void draw_model(Model *model);
|
||||||
|
void cleanup_model(Model *model);
|
||||||
|
void upload_model_vertex_buffers(Model *model);
|
||||||
|
void upload_model_index_buffer(Model *model);
|
||||||
|
void create_model_vertex_buffers(Model *model);
|
||||||
|
void create_model_index_buffer(Model *model);
|
||||||
|
s32 get_model_triangle_count(Model *model);
|
||||||
|
|
||||||
|
|||||||
@ -19,10 +19,9 @@ struct Render_Data {
|
|||||||
GLFWwindow *glfw_window = nullptr;
|
GLFWwindow *glfw_window = nullptr;
|
||||||
s32 width = 0;
|
s32 width = 0;
|
||||||
s32 height = 0;
|
s32 height = 0;
|
||||||
s32 triangle_count = 0;
|
u32 triangle_count = 0;
|
||||||
f32 frame_time = 0.0f;
|
f32 frame_time = 0.0f;
|
||||||
f32 user_interface_generate_time = 0.0f;
|
f32 user_interface_generate_time = 0.0f;
|
||||||
bool use_alt_shader = false;
|
|
||||||
s32 field_of_view = 90;
|
s32 field_of_view = 90;
|
||||||
|
|
||||||
f32 view_azimuth = 320.0f;
|
f32 view_azimuth = 320.0f;
|
||||||
|
|||||||
@ -7,7 +7,6 @@ bool init_renderer(Renderer *renderer, u32 width, u32 height) {
|
|||||||
renderer->render_data.width = width;
|
renderer->render_data.width = width;
|
||||||
renderer->render_data.height = height;
|
renderer->render_data.height = height;
|
||||||
|
|
||||||
|
|
||||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
||||||
log(1, "%s error: failed to initialize GLAD\n", __FUNCTION__);
|
log(1, "%s error: failed to initialize GLAD\n", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
@ -62,12 +61,15 @@ bool init_renderer(Renderer *renderer, u32 width, u32 height) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
bool success = load_shaders(&renderer->alt_shader, "shaders/alt.vert", "shaders/alt.frag");
|
renderer->model = new Model();
|
||||||
|
string model_filepath = "assets/models/woman.gltf";
|
||||||
|
string model_texture_filepath = "assets/textures/woman.png";
|
||||||
|
bool success = load_model(renderer->model, &renderer->render_data, model_filepath, model_texture_filepath);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
log(1, "%s: alt shader loading failed\n", __FUNCTION__);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
log(1, "%s: alt shaders succesfully loaded\n", __FUNCTION__);
|
upload_model_index_buffer(renderer->model);
|
||||||
|
upload_model_vertex_buffers(renderer->model);
|
||||||
}
|
}
|
||||||
|
|
||||||
init_user_interface(&renderer->user_interface, &renderer->render_data);
|
init_user_interface(&renderer->user_interface, &renderer->render_data);
|
||||||
@ -114,13 +116,9 @@ void draw_renderer(Renderer *renderer) {
|
|||||||
f32 dt = glfwGetTime();
|
f32 dt = glfwGetTime();
|
||||||
Matrix4 model = Matrix4(1.0);
|
Matrix4 model = Matrix4(1.0);
|
||||||
|
|
||||||
if (!renderer->render_data.use_alt_shader) {
|
use_shader(&renderer->shader);
|
||||||
use_shader(&renderer->shader);
|
// model = glm::rotate(Matrix4(1.0f), dt, Vector3(0.0f, 0.0f, 1.0f));
|
||||||
model = glm::rotate(Matrix4(1.0f), dt, Vector3(0.0f, 0.0f, 1.0f));
|
draw_model(renderer->model);
|
||||||
} else {
|
|
||||||
use_shader(&renderer->alt_shader);
|
|
||||||
model = glm::rotate(Matrix4(1.0f), -dt, Vector3(0.0f, 0.0f, 1.0f));
|
|
||||||
}
|
|
||||||
|
|
||||||
renderer->view_matrix = get_camera_view_matrix(&renderer->camera, &renderer->render_data);
|
renderer->view_matrix = get_camera_view_matrix(&renderer->camera, &renderer->render_data);
|
||||||
|
|
||||||
@ -160,45 +158,45 @@ void upload_renderer_data(Renderer *renderer, Mesh *vertex_data) {
|
|||||||
|
|
||||||
void cleanup_renderer(Renderer *renderer) {
|
void cleanup_renderer(Renderer *renderer) {
|
||||||
cleanup_user_interface(&renderer->user_interface);
|
cleanup_user_interface(&renderer->user_interface);
|
||||||
cleanup_shader(&renderer->shader);
|
|
||||||
cleanup_shader(&renderer->alt_shader);
|
|
||||||
cleanup_texture(&renderer->texture);
|
cleanup_texture(&renderer->texture);
|
||||||
|
cleanup_model(renderer->model);
|
||||||
|
cleanup_shader(&renderer->shader);
|
||||||
cleanup_vertex_buffer(&renderer->vertex_buffer);
|
cleanup_vertex_buffer(&renderer->vertex_buffer);
|
||||||
cleanup_frame_buffer(&renderer->frame_buffer);
|
cleanup_frame_buffer(&renderer->frame_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_key_events(Renderer *renderer, s32 key, s32 scancode, s32 action, s32 mods) {
|
void handle_key_events(Renderer *renderer, s32 key, s32 scancode, s32 action, s32 mods) {
|
||||||
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_SPACE) == GLFW_PRESS) {
|
|
||||||
renderer->render_data.use_alt_shader = !renderer->render_data.use_alt_shader;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_movement_keys(Renderer *renderer) {
|
void handle_movement_keys(Renderer *renderer) {
|
||||||
|
u32 movement_speed = 5;
|
||||||
|
|
||||||
renderer->render_data.move_forward = 0;
|
renderer->render_data.move_forward = 0;
|
||||||
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_W) == GLFW_PRESS) {
|
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_W) == GLFW_PRESS) {
|
||||||
renderer->render_data.move_forward += 1;
|
renderer->render_data.move_forward += movement_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_S) == GLFW_PRESS) {
|
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_S) == GLFW_PRESS) {
|
||||||
renderer->render_data.move_forward -= 1;
|
renderer->render_data.move_forward -= movement_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->render_data.move_right = 0;
|
renderer->render_data.move_right = 0;
|
||||||
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_D) == GLFW_PRESS) {
|
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_D) == GLFW_PRESS) {
|
||||||
renderer->render_data.move_right += 1;
|
renderer->render_data.move_right += movement_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_A) == GLFW_PRESS) {
|
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_A) == GLFW_PRESS) {
|
||||||
renderer->render_data.move_right -= 1;
|
renderer->render_data.move_right -= movement_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->render_data.move_up = 0;
|
renderer->render_data.move_up = 0;
|
||||||
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_E) == GLFW_PRESS) {
|
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_E) == GLFW_PRESS) {
|
||||||
renderer->render_data.move_up += 1;
|
renderer->render_data.move_up += movement_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_Q) == GLFW_PRESS) {
|
if (glfwGetKey(renderer->render_data.glfw_window, GLFW_KEY_Q) == GLFW_PRESS) {
|
||||||
renderer->render_data.move_up -= 1;
|
renderer->render_data.move_up -= movement_speed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,6 +226,8 @@ void handle_mouse_button_events(Renderer *renderer, s32 button, s32 action, s32
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_mouse_position_events(Renderer *renderer, f64 x_pos, f64 y_pos) {
|
void handle_mouse_position_events(Renderer *renderer, f64 x_pos, f64 y_pos) {
|
||||||
|
f32 movement_speed = 1.0;
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.AddMousePosEvent((f32)x_pos, (f32)y_pos);
|
io.AddMousePosEvent((f32)x_pos, (f32)y_pos);
|
||||||
|
|
||||||
@ -239,7 +239,7 @@ void handle_mouse_position_events(Renderer *renderer, f64 x_pos, f64 y_pos) {
|
|||||||
s32 mouse_move_rel_y = static_cast<s32>(y_pos) - renderer->mouse_y_position;
|
s32 mouse_move_rel_y = static_cast<s32>(y_pos) - renderer->mouse_y_position;
|
||||||
|
|
||||||
if (renderer->mouse_lock) {
|
if (renderer->mouse_lock) {
|
||||||
renderer->render_data.view_azimuth += mouse_move_rel_x / 10.0;
|
renderer->render_data.view_azimuth += mouse_move_rel_x / movement_speed;
|
||||||
|
|
||||||
if (renderer->render_data.view_azimuth < 0.0) {
|
if (renderer->render_data.view_azimuth < 0.0) {
|
||||||
renderer->render_data.view_azimuth += 360.0;
|
renderer->render_data.view_azimuth += 360.0;
|
||||||
@ -249,7 +249,7 @@ void handle_mouse_position_events(Renderer *renderer, f64 x_pos, f64 y_pos) {
|
|||||||
renderer->render_data.view_azimuth -= 360.0;
|
renderer->render_data.view_azimuth -= 360.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer->render_data.view_elevation -= mouse_move_rel_y / 10.0;
|
renderer->render_data.view_elevation -= mouse_move_rel_y / movement_speed;
|
||||||
|
|
||||||
if (renderer->render_data.view_elevation > 89.0) {
|
if (renderer->render_data.view_elevation > 89.0) {
|
||||||
renderer->render_data.view_elevation = 89.0;
|
renderer->render_data.view_elevation = 89.0;
|
||||||
|
|||||||
@ -12,11 +12,13 @@
|
|||||||
#include "uniform_buffer.h"
|
#include "uniform_buffer.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "shaders.h"
|
#include "shaders.h"
|
||||||
|
#include "model.h"
|
||||||
|
|
||||||
|
|
||||||
struct Renderer {
|
struct Renderer {
|
||||||
|
// @Todo put in the specific gltf shader (just rename the alt shader and use that one)
|
||||||
Shader shader;
|
Shader shader;
|
||||||
Shader alt_shader;
|
Model* model = nullptr;
|
||||||
Frame_Buffer frame_buffer;
|
Frame_Buffer frame_buffer;
|
||||||
Vertex_Buffer vertex_buffer;
|
Vertex_Buffer vertex_buffer;
|
||||||
Uniform_Buffer uniform_buffer;
|
Uniform_Buffer uniform_buffer;
|
||||||
|
|||||||
@ -1,15 +1,18 @@
|
|||||||
#include "shaders.h"
|
#include "shaders.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
|
|
||||||
bool load_shaders(Shader *shader, string vertex_shader_filepath, string fragment_shader_filepath) {
|
bool load_shaders(Shader *shader, string vertex_shader_filepath, string fragment_shader_filepath) {
|
||||||
u32 vertex_shader = load_shader(vertex_shader_filepath, GL_VERTEX_SHADER);
|
u32 vertex_shader = load_shader(vertex_shader_filepath, GL_VERTEX_SHADER);
|
||||||
if (!vertex_shader) {
|
if (!vertex_shader) {
|
||||||
|
log(1, "%s: could not load vertex shader\n", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 fragment_shader = load_shader(fragment_shader_filepath, GL_FRAGMENT_SHADER);
|
u32 fragment_shader = load_shader(fragment_shader_filepath, GL_FRAGMENT_SHADER);
|
||||||
if (!fragment_shader) {
|
if (!fragment_shader) {
|
||||||
|
log(1, "%s: could not load fragment shader\n", __FUNCTION__);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
#define STB_IMAGE_IMPLEMENTATION
|
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
|
|
||||||
bool load_texture(Texture *texture, string filepath) {
|
bool load_texture(Texture *texture, string filepath) {
|
||||||
texture->name = filepath;
|
texture->name = filepath;
|
||||||
|
|
||||||
stbi_set_flip_vertically_on_load(true);
|
// @Cleanup we probably don't need to do this
|
||||||
|
// stbi_set_flip_vertically_on_load(true);
|
||||||
u8* texture_data = stbi_load(filepath.c_str(), &texture->width, &texture->height, &texture->number_of_channels, 0);
|
u8* texture_data = stbi_load(filepath.c_str(), &texture->width, &texture->height, &texture->number_of_channels, 0);
|
||||||
|
|
||||||
if (!texture_data) {
|
if (!texture_data) {
|
||||||
|
|||||||
@ -61,17 +61,6 @@ void create_user_interface_frame(User_Interface *user_interface, Render_Data *re
|
|||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alt shader toggler
|
|
||||||
if (ImGui::Button("Toggle shader")) {
|
|
||||||
render_data->use_alt_shader = !render_data->use_alt_shader;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui::SameLine();
|
|
||||||
if (!render_data->use_alt_shader) {
|
|
||||||
ImGui::Text("Basic shader");
|
|
||||||
} else {
|
|
||||||
ImGui::Text("Alt shader");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Field of view slider
|
// Field of view slider
|
||||||
ImGui::Text("Field of view");
|
ImGui::Text("Field of view");
|
||||||
|
|||||||
@ -62,8 +62,8 @@ bool init_window(Window *window, u32 width, u32 height, string title) {
|
|||||||
handle_mouse_position_events(renderer, x_pos, y_pos);
|
handle_mouse_position_events(renderer, x_pos, y_pos);
|
||||||
});
|
});
|
||||||
|
|
||||||
window->model = new Model();
|
// window->model = new Model();
|
||||||
init_model(window->model);
|
// init_model(window->model);
|
||||||
|
|
||||||
log(1, "%s: Window initialized\n", __FUNCTION__);
|
log(1, "%s: Window initialized\n", __FUNCTION__);
|
||||||
return true;
|
return true;
|
||||||
@ -71,7 +71,7 @@ bool init_window(Window *window, u32 width, u32 height, string title) {
|
|||||||
|
|
||||||
void main_loop(Window *window) {
|
void main_loop(Window *window) {
|
||||||
glfwSwapInterval(1);
|
glfwSwapInterval(1);
|
||||||
upload_renderer_data(window->renderer, &window->model->vertex_data);
|
// upload_renderer_data(window->renderer, &renderer->model->vertex_data);
|
||||||
|
|
||||||
while (!glfwWindowShouldClose(window->glfw_window)) {
|
while (!glfwWindowShouldClose(window->glfw_window)) {
|
||||||
draw_renderer(window->renderer);
|
draw_renderer(window->renderer);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user