Add model loading and simple phong color shading
This commit is contained in:
parent
8238e94eea
commit
4893a36197
@ -7,10 +7,11 @@ find_package(glm REQUIRED)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(EPOXY REQUIRED epoxy)
|
||||
pkg_check_modules(SDL2 REQUIRED sdl2)
|
||||
pkg_check_modules(ASSIMP REQUIRED assimp)
|
||||
|
||||
#find_package(OpenCL REQUIRED)
|
||||
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/imgui-submodule/imgui/examples" "${CMAKE_CURRENT_SOURCE_DIR}/imgui-submodule/imgui" ${EPOXY_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS})
|
||||
include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/imgui-submodule/imgui/examples" "${CMAKE_CURRENT_SOURCE_DIR}/imgui-submodule/imgui" ${EPOXY_INCLUDE_DIRS} ${ASSIMP_INCLUDE_DIRS} ${SDL2_INCLUDE_DIRS})
|
||||
|
||||
|
||||
configure_file("shaders/2d-passthrough-vertex.glsl" "shaders/2d-passthrough-vertex.glsl" COPYONLY)
|
||||
@ -19,10 +20,12 @@ configure_file("shaders/triangle-gen-geometry.glsl" "shaders/triangle-gen-geomet
|
||||
configure_file("shaders/triangle-gen-zoomed-geometry.glsl" "shaders/triangle-gen-zoomed-geometry.glsl" COPYONLY)
|
||||
configure_file("shaders/textured-rectangle-vertex.glsl" "shaders/textured-rectangle-vertex.glsl" COPYONLY)
|
||||
configure_file("shaders/textured-rectangle-fragment.glsl" "shaders/textured-rectangle-fragment.glsl" COPYONLY)
|
||||
|
||||
|
||||
configure_file("shaders/2d-zoom-translate-vertex.glsl" "shaders/2d-zoom-translate-vertex.glsl" COPYONLY)
|
||||
|
||||
|
||||
configure_file("shaders/mesh-vertex.glsl" "shaders/mesh-vertex.glsl" COPYONLY)
|
||||
configure_file("shaders/mesh-fragment.glsl" "shaders/mesh-fragment.glsl" COPYONLY)
|
||||
|
||||
set(IMGUI_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/imgui-submodule/imgui/imgui.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/imgui-submodule/imgui/imgui_draw.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/imgui-submodule/imgui/imgui_demo.cpp"
|
||||
@ -36,5 +39,5 @@ aux_source_directory("src" SOURCES)
|
||||
add_compile_options(-Wall)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCES} ${IMGUI_SOURCES})
|
||||
target_link_libraries(${PROJECT_NAME} m pthread ${EPOXY_LIBRARIES} ${SDL2_LIBRARIES} glm)
|
||||
target_link_libraries(${PROJECT_NAME} m pthread ${EPOXY_LIBRARIES} ${SDL2_LIBRARIES} ${ASSIMP_LIBRARIES} glm)
|
||||
install (TARGETS ${PROJECT_NAME} DESTINATION bin)
|
||||
|
@ -11,11 +11,14 @@ class GlobalCanvasSettings
|
||||
static const glm::mat4 &getViewMatrix();
|
||||
static const glm::mat4 &getProjectionMatrix();
|
||||
static const glm::mat4 &getPVMatrix();
|
||||
static const glm::vec3 &getCameraPosition();
|
||||
static void setCameraPosition(const glm::vec3 &cam_pos);
|
||||
private:
|
||||
static void calculatePVMatrix();
|
||||
static glm::mat4 m_proj;
|
||||
static glm::mat4 m_view;
|
||||
static glm::mat4 m_proj_view;
|
||||
static glm::vec3 m_cam_pos;
|
||||
};
|
||||
|
||||
#endif // GLOBALCANVASSETTINGS_H
|
||||
|
28
include/opengl-playground/mesh.hpp
Normal file
28
include/opengl-playground/mesh.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef MESH_H
|
||||
#define MESH_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <vector>
|
||||
#include <opengl-playground/vertex.hpp>
|
||||
#include <opengl-playground/opengltexture.hpp>
|
||||
#include <opengl-playground/openglgraphics.hpp>
|
||||
|
||||
class Mesh : public OpenGlGraphics
|
||||
{
|
||||
public:
|
||||
Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices,
|
||||
std::vector<std::shared_ptr<OpenGlTexture>> textures,
|
||||
std::shared_ptr<OpenGlShaderProgram> shader);
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
std::vector<std::shared_ptr<OpenGlTexture>> textures;
|
||||
void realize();
|
||||
void render();
|
||||
void render(const glm::mat4 &model_matrix, const glm::mat4 &normal_matrix);
|
||||
private:
|
||||
unsigned int vao;
|
||||
unsigned int vbo;
|
||||
unsigned int ebo;
|
||||
};
|
||||
|
||||
#endif // MESH_H
|
30
include/opengl-playground/model.hpp
Normal file
30
include/opengl-playground/model.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef MODEL_H
|
||||
#define MODEL_H
|
||||
|
||||
#include <opengl-playground/openglgraphics.hpp>
|
||||
#include <opengl-playground/mesh.hpp>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
|
||||
class Model : public OpenGlGraphics
|
||||
{
|
||||
public:
|
||||
Model(const std::string &path, const glm::vec4 &static_color, std::shared_ptr<OpenGlShaderProgram> shader);
|
||||
void render();
|
||||
void realize();
|
||||
private:
|
||||
std::string model_path;
|
||||
glm::vec4 static_color;
|
||||
/* Model Data */
|
||||
std::vector<Mesh> meshes;
|
||||
std::vector<std::shared_ptr<OpenGlTexture>> allocated_textures;
|
||||
std::string directory;
|
||||
std::vector<std::shared_ptr<OpenGlTexture>> loadMaterialTextures(aiMaterial *mat, aiTextureType type, TextureType tex_type);
|
||||
void processNode(aiNode *node, const aiScene *scene);
|
||||
Mesh processMesh(aiMesh *mesh, const aiScene *scene);
|
||||
};
|
||||
|
||||
#endif // MODEL_H
|
@ -16,9 +16,11 @@ class OpenGlGraphics
|
||||
virtual void render() = 0;
|
||||
void setModelMatrix(const glm::mat4 &model_matrix);
|
||||
glm::mat4 getModelMatrix();
|
||||
glm::mat4 getNormalMatrix();
|
||||
protected:
|
||||
std::shared_ptr<OpenGlShaderProgram> shaderprog;
|
||||
glm::mat4 model_matrix;
|
||||
glm::mat4 normal_matrix;
|
||||
};
|
||||
|
||||
#endif // OPENGLGRAPHICS_H
|
||||
|
@ -19,6 +19,7 @@ class OpenGlShaderProgram
|
||||
void setUniformFloat(const std::string &uniform, float value);
|
||||
void setUniformInt(const std::string &uniform, int value);
|
||||
void setUniformVec2(const std::string &uniform, float *vector);
|
||||
void setUniformVec3(const std::string &uniform, const glm::vec3 &vector);
|
||||
void setUniformMat4(const std::string &uniform, const glm::mat4 &matrix);
|
||||
void setUniformVec4(const std::string &uniform, const glm::vec4 &vector);
|
||||
private:
|
||||
|
@ -2,17 +2,28 @@
|
||||
#define OPENGLTEXTURE_HPP
|
||||
|
||||
#include <epoxy/gl.h>
|
||||
#include <string>
|
||||
|
||||
typedef enum {TEXTURE_DIFFUSE, TEXTURE_SPECULAR} TextureType;
|
||||
|
||||
class OpenGlTexture
|
||||
{
|
||||
public:
|
||||
OpenGlTexture(TextureType type, const std::string &texture_path);
|
||||
OpenGlTexture();
|
||||
OpenGlTexture(const OpenGlTexture &tex) = delete;
|
||||
OpenGlTexture(const OpenGlTexture &&tex) = delete;
|
||||
~OpenGlTexture();
|
||||
void setRGBDataFromBytes(unsigned int width, unsigned int height, char *buffer);
|
||||
void loadFromImagePath(const std::string &base_directory);
|
||||
void use(unsigned int slot);
|
||||
void use();
|
||||
const std::string &getPath();
|
||||
TextureType getType();
|
||||
|
||||
private:
|
||||
std::string texture_path;
|
||||
TextureType type;
|
||||
|
||||
protected:
|
||||
GLuint texture;
|
||||
|
13
include/opengl-playground/vertex.hpp
Normal file
13
include/opengl-playground/vertex.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef VERTEX_H
|
||||
#define VERTEX_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
glm::vec3 Position;
|
||||
glm::vec3 Normal;
|
||||
glm::vec2 TextureCoords;
|
||||
};
|
||||
|
||||
#endif // VERTEX_H
|
7656
include/stb/stb_image.h
Normal file
7656
include/stb/stb_image.h
Normal file
File diff suppressed because it is too large
Load Diff
46
shaders/mesh-fragment.glsl
Normal file
46
shaders/mesh-fragment.glsl
Normal file
@ -0,0 +1,46 @@
|
||||
#version 330 core
|
||||
|
||||
struct Material {
|
||||
sampler2D diffuse0;
|
||||
sampler2D diffuse1;
|
||||
sampler2D diffuse2;
|
||||
sampler2D diffuse3;
|
||||
sampler2D specular0;
|
||||
sampler2D specular1;
|
||||
sampler2D specular2;
|
||||
sampler2D specular3;
|
||||
};
|
||||
|
||||
out vec4 fragmentColor;
|
||||
in vec3 Normal;
|
||||
in vec3 FragPos;
|
||||
in vec2 TexCoord;
|
||||
in vec3 ViewPos;
|
||||
uniform Material material;
|
||||
|
||||
void main()
|
||||
{
|
||||
const vec3 light_direction = vec3(-1.0, -1.0, -1.0);
|
||||
const vec3 light_color = vec3(1.0, 1.0, 1.0);
|
||||
const float light_amb = 0.1;
|
||||
const float light_spec = 0.4;
|
||||
const float light_diff = 0.7;
|
||||
|
||||
vec3 diffuseTexCol = vec3(texture(material.diffuse0, TexCoord));
|
||||
vec3 specularTexCol = vec3(texture(material.specular0, TexCoord));
|
||||
|
||||
vec3 normal_n = normalize(Normal);
|
||||
vec3 light_dir_n = normalize(light_direction);
|
||||
|
||||
vec3 view_dir = normalize(ViewPos - FragPos);
|
||||
vec3 reflect_dir = reflect(light_dir_n, normal_n);
|
||||
float shine = pow(max(dot(view_dir, reflect_dir), 0.0), 35);
|
||||
|
||||
vec3 ambient_light = light_amb * diffuseTexCol * light_color;
|
||||
vec3 diffuse_light = max(dot(normal_n, -light_dir_n), 0.0) *light_diff * diffuseTexCol * light_color;
|
||||
vec3 specular_light = shine * light_spec * specularTexCol * light_color;
|
||||
|
||||
vec3 color = ambient_light + diffuse_light + specular_light;
|
||||
|
||||
fragmentColor = vec4(color, 1.0);
|
||||
}
|
24
shaders/mesh-vertex.glsl
Normal file
24
shaders/mesh-vertex.glsl
Normal file
@ -0,0 +1,24 @@
|
||||
#version 330 core
|
||||
|
||||
layout (location = 0) in vec3 aInputPosition;
|
||||
layout (location = 1) in vec3 aInputNormal;
|
||||
layout (location = 2) in vec2 aTextureCoord;
|
||||
|
||||
uniform mat4 model_matrix;
|
||||
uniform mat4 normal_matrix;
|
||||
uniform mat4 projection_view_matrix;
|
||||
uniform vec3 camera_position;
|
||||
|
||||
out vec3 Normal;
|
||||
out vec3 FragPos;
|
||||
out vec2 TexCoord;
|
||||
out vec3 ViewPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection_view_matrix * model_matrix * vec4(aInputPosition, 1.0);
|
||||
Normal = vec3(normal_matrix * vec4(aInputNormal, 0.0));
|
||||
FragPos = vec3(model_matrix * vec4(aInputPosition, 1.0));
|
||||
TexCoord = aTextureCoord;
|
||||
ViewPos = camera_position;
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
glm::mat4 GlobalCanvasSettings::m_proj = glm::mat4(1.0f);
|
||||
glm::mat4 GlobalCanvasSettings::m_view = glm::mat4(1.0f);
|
||||
glm::mat4 GlobalCanvasSettings::m_proj_view = glm::mat4(1.0f);
|
||||
glm::vec3 GlobalCanvasSettings::m_cam_pos = glm::vec3(0.0f);
|
||||
|
||||
void GlobalCanvasSettings::setProjectionMatrix(const glm::mat4 &proj)
|
||||
{
|
||||
@ -31,6 +32,16 @@ const glm::mat4 &GlobalCanvasSettings::getPVMatrix()
|
||||
return GlobalCanvasSettings::m_proj_view;
|
||||
}
|
||||
|
||||
const glm::vec3 &GlobalCanvasSettings::getCameraPosition()
|
||||
{
|
||||
return GlobalCanvasSettings::m_cam_pos;
|
||||
}
|
||||
|
||||
void GlobalCanvasSettings::setCameraPosition(const glm::vec3 &cam_pos)
|
||||
{
|
||||
GlobalCanvasSettings::m_cam_pos = cam_pos;
|
||||
}
|
||||
|
||||
void GlobalCanvasSettings::calculatePVMatrix()
|
||||
{
|
||||
GlobalCanvasSettings::m_proj_view = GlobalCanvasSettings::m_proj * GlobalCanvasSettings::m_view;
|
||||
|
144
src/main.cpp
144
src/main.cpp
@ -6,6 +6,7 @@
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <opengl-playground/model.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <imgui_impl_sdl.h>
|
||||
@ -14,29 +15,15 @@
|
||||
#define WINDOW_WIDTH 1200
|
||||
#define WINDOW_HEIGHT 800
|
||||
|
||||
unsigned char tex[4*10000] = {255};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
SdlMainWindow *window;
|
||||
bool run = true;
|
||||
glm::mat4 view_matrix;
|
||||
glm::mat4 projection_matrix;
|
||||
glm::vec4 color = glm::vec4(1.0f);
|
||||
float y_rotation = 0.0f;
|
||||
bool proj_ortho = true;
|
||||
|
||||
float nav_point[2] = {0.0f, 0.0f};
|
||||
float zoom = 1.0;
|
||||
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
tex[i*4] = 0xff;
|
||||
tex[i*4+1] = 0x00;
|
||||
tex[i*4+2] = 0x00;
|
||||
tex[i*4+3] = 0xFF;
|
||||
}
|
||||
float fov_angle = 45.0f;
|
||||
|
||||
|
||||
window = new SdlMainWindow(WINDOW_HEIGHT, WINDOW_WIDTH);
|
||||
@ -49,20 +36,9 @@ int main(int argc, char **argv)
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
std::shared_ptr<OpenGlShaderProgram> textured_rect_prog =
|
||||
std::make_shared<OpenGlShaderProgram>("shaders/textured-rectangle-vertex.glsl", "",
|
||||
"shaders/textured-rectangle-fragment.glsl");
|
||||
|
||||
projection_matrix = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -1.0f, 1.0f);
|
||||
projection_matrix = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -10.0f, 10.0f);
|
||||
GlobalCanvasSettings::setProjectionMatrix(projection_matrix);
|
||||
GlobalCanvasSettings::setViewMatrix(glm::mat4(1.0f));
|
||||
textured_rect_prog->compile();
|
||||
|
||||
std::shared_ptr<OpenGlTexture> texture = std::make_shared<OpenGlTexture>();
|
||||
texture->setRGBDataFromBytes(100,100, (char*)tex);
|
||||
|
||||
TexturedRectangle rect = TexturedRectangle(-3, -3, 3, 3, textured_rect_prog, texture);
|
||||
rect.realize();
|
||||
|
||||
// Setup Dear ImGui context
|
||||
IMGUI_CHECKVERSION();
|
||||
@ -79,30 +55,42 @@ int main(int argc, char **argv)
|
||||
ImGui_ImplSDL2_InitForOpenGL(window->getWindow(), window->getContext());
|
||||
ImGui_ImplOpenGL3_Init("#version 330");
|
||||
|
||||
auto shader = std::make_shared<OpenGlShaderProgram>("shaders/mesh-vertex.glsl", "", "shaders/mesh-fragment.glsl");
|
||||
shader->compile();
|
||||
Model m("nanosuit/nanosuit.obj", glm::vec4(1.0f, 0.0f, 0.0f, 1.0f), shader);
|
||||
|
||||
m.realize();
|
||||
m.setModelMatrix(glm::scale(glm::mat4(1.0f), glm::vec3(0.2f, 0.2f, 0.2f)));
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
while (run) {
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
if (event.type == SDL_MOUSEWHEEL) {
|
||||
if (event.wheel.y > 0) {
|
||||
zoom += 0.1;
|
||||
} else {
|
||||
zoom -= 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImGui_ImplSDL2_ProcessEvent(&event);
|
||||
if (event.type == SDL_QUIT)
|
||||
run = false;
|
||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window->getWindow()))
|
||||
run = false;
|
||||
|
||||
if (event.type == SDL_MOUSEWHEEL) {
|
||||
if (event.wheel.y > 0) {
|
||||
fov_angle -= 0.1;
|
||||
if (fov_angle <= 1.0f)
|
||||
fov_angle = 1.0f;
|
||||
} else if (event.wheel.y < 0) {
|
||||
fov_angle += 0.1;
|
||||
if (fov_angle >= 60.0f)
|
||||
fov_angle = 60.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
// Start the Dear ImGui frame
|
||||
ImGui_ImplOpenGL3_NewFrame();
|
||||
@ -110,37 +98,76 @@ int main(int argc, char **argv)
|
||||
ImGui::NewFrame();
|
||||
|
||||
|
||||
view_matrix = glm::scale(glm::mat4(1.0f), glm::vec3(zoom, zoom, 1.0));
|
||||
view_matrix = glm::translate(view_matrix, glm::vec3(-nav_point[0], -nav_point[1], -10.0f));
|
||||
ImGui::Begin("Camera");
|
||||
|
||||
GlobalCanvasSettings::setViewMatrix(view_matrix);
|
||||
|
||||
rect.render();
|
||||
|
||||
ImGui::Begin("Rectangle");
|
||||
ImGui::Text("Change the color of the rectangle below");
|
||||
ImGui::NewLine();
|
||||
ImGui::SliderFloat4("Rectangle Color", &color.r, 0.0f, 1.0f, "%.3f", 1.0f);
|
||||
ImGui::Text("Rectangle Rotation:");
|
||||
ImGui::NewLine();
|
||||
ImGui::SliderAngle("Y Rotation", &y_rotation, -180.0f, +180.0f);
|
||||
static int e = 0;
|
||||
static int e = 1;
|
||||
ImGui::RadioButton("Orthographic", &e, 0); ImGui::SameLine();
|
||||
ImGui::RadioButton("Perspective", &e, 1);
|
||||
|
||||
static float view_z = 10.0f, view_x = 0.0f, view_y = 0.0f;
|
||||
ImGui::SliderFloat("Camera x", &view_x, -20.0f, 20.0f);
|
||||
ImGui::SliderFloat("Camera y", &view_y, -20.0f, 20.0f);
|
||||
ImGui::SliderFloat("Camera z", &view_z, 0.0f, 20.0f);
|
||||
ImGui::SliderFloat("Camera FOV", &fov_angle, 1.0f, 60.0f);
|
||||
ImGui::Text("Framerate: %.01f Hz", io.Framerate);
|
||||
|
||||
GlobalCanvasSettings::setCameraPosition(glm::vec3(view_x, view_y, view_z));
|
||||
const glm::mat4 view = glm::lookAt(GlobalCanvasSettings::getCameraPosition(),
|
||||
glm::vec3(view_x, view_y, 0.0f),
|
||||
glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
|
||||
GlobalCanvasSettings::setViewMatrix(view);
|
||||
|
||||
if(!e) {
|
||||
GlobalCanvasSettings::setProjectionMatrix(glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, -1.0f, 20.0f));
|
||||
//GlobalCanvasSettings::setProjectionMatrix(glm::mat4(1.0f));
|
||||
GlobalCanvasSettings::setProjectionMatrix(glm::ortho(-5.0f, 5.0f, -5.0f, 5.0f, -5.0f, 5.0f));
|
||||
} else {
|
||||
|
||||
GlobalCanvasSettings::setProjectionMatrix(glm::perspective(glm::radians(120.0f), (float)1200/(float)800, 1.0f, 30.0f));
|
||||
GlobalCanvasSettings::setProjectionMatrix(glm::perspective(glm::radians(fov_angle), (float)1200/(float)800, 0.2f, 30.0f));
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
|
||||
{
|
||||
ImGui::Begin("Model Matrix");
|
||||
glm::mat4 mat = m.getModelMatrix();
|
||||
static float x_pos = 0.0f;
|
||||
static float y_rot = 0.0f, z_rot =0.0f, x_rot = 0.0f;
|
||||
ImGui::Text("%.2f %.2f %.2f %.2f", mat[0][0], mat[1][0], mat[2][0], mat[3][0]);
|
||||
ImGui::Text("%.2f %.2f %.2f %.2f", mat[0][1], mat[1][1], mat[2][1], mat[3][1]);
|
||||
ImGui::Text("%.2f %.2f %.2f %.2f", mat[0][2], mat[1][2], mat[2][2], mat[3][2]);
|
||||
ImGui::Text("%.2f %.2f %.2f %.2f", mat[0][3], mat[1][3], mat[2][3], mat[3][3]);
|
||||
ImGui::SliderFloat("X Pos", &x_pos, -5, 5);
|
||||
ImGui::SliderFloat("X Rotation", &x_rot, -180.0f, 180.0f);
|
||||
ImGui::SliderFloat("Y Rotation", &y_rot, -180.0f, 180.0f);
|
||||
ImGui::SliderFloat("Z Rotation", &z_rot, -180.0f, 180.0f);
|
||||
mat = glm::scale(glm::mat4(1.0f), glm::vec3(0.2f, 0.2f, 0.2f));
|
||||
mat = glm::rotate(mat, glm::radians(x_rot), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
mat = glm::rotate(mat, glm::radians(y_rot), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
mat = glm::rotate(mat, glm::radians(z_rot), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||
mat = glm::translate(glm::mat4(1.0), glm::vec3(x_pos, 0.0f, 0.0f)) * mat;
|
||||
m.setModelMatrix(mat);
|
||||
ImGui::End();
|
||||
}
|
||||
{
|
||||
ImGui::Begin("Normal Matrix");
|
||||
glm::mat4 mat = m.getNormalMatrix();
|
||||
ImGui::Text("%.2f %.2f %.2f %.2f", mat[0][0], mat[1][0], mat[2][0], mat[3][0]);
|
||||
ImGui::Text("%.2f %.2f %.2f %.2f", mat[0][1], mat[1][1], mat[2][1], mat[3][1]);
|
||||
ImGui::Text("%.2f %.2f %.2f %.2f", mat[0][2], mat[1][2], mat[2][2], mat[3][2]);
|
||||
ImGui::Text("%.2f %.2f %.2f %.2f", mat[0][3], mat[1][3], mat[2][3], mat[3][3]);
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
m.render();
|
||||
|
||||
glm::mat4 current_model_matrix = m.getModelMatrix();
|
||||
current_model_matrix = glm::translate(glm::mat4(1.0f), glm::vec3(3.0f, 0.0f, 0.0f)) * current_model_matrix;
|
||||
m.setModelMatrix(current_model_matrix);
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
m.render();
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
glm::mat4 model_matrix = glm::rotate(glm::mat4(1.0f), y_rotation, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
rect.setModelMatrix(model_matrix);
|
||||
rect.setBaseColor(color);
|
||||
ImGui::Render();
|
||||
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
@ -152,6 +179,7 @@ int main(int argc, char **argv)
|
||||
ImGui_ImplSDL2_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
textured_rect_prog->unload();
|
||||
shader->unload();
|
||||
|
||||
delete window;
|
||||
}
|
||||
|
82
src/mesh.cpp
Normal file
82
src/mesh.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include <opengl-playground/mesh.hpp>
|
||||
#include <opengl-playground/globalcanvassettings.hpp>
|
||||
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <iostream>
|
||||
|
||||
Mesh::Mesh(std::vector<Vertex> vertices, std::vector<unsigned int> indices,
|
||||
std::vector<std::shared_ptr<OpenGlTexture> > textures,
|
||||
std::shared_ptr<OpenGlShaderProgram> shader) :
|
||||
OpenGlGraphics(shader)
|
||||
{
|
||||
this->vertices = vertices;
|
||||
this->indices = indices;
|
||||
this->textures = textures;
|
||||
}
|
||||
|
||||
void Mesh::realize()
|
||||
{
|
||||
glGenVertexArrays(1, &this->vao);
|
||||
glGenBuffers(1, &this->vbo);
|
||||
glGenBuffers(1, &this->ebo);
|
||||
|
||||
glBindVertexArray(this->vao);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), &vertices[0], GL_STATIC_DRAW);
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->ebo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)0);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, Normal));
|
||||
glEnableVertexAttribArray(2);
|
||||
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)offsetof(Vertex, TextureCoords));
|
||||
|
||||
glBindVertexArray(0);
|
||||
std::cout << "Realizing Mesh" << std::endl;
|
||||
}
|
||||
|
||||
void Mesh::render()
|
||||
{
|
||||
this->render(this->model_matrix, this->normal_matrix);
|
||||
}
|
||||
|
||||
void Mesh::render(const glm::mat4 &model_matrix, const glm::mat4 &normal_matrix)
|
||||
{
|
||||
this->shaderprog->use();
|
||||
this->shaderprog->setUniformMat4("model_matrix", model_matrix);
|
||||
this->shaderprog->setUniformMat4("normal_matrix", normal_matrix);
|
||||
this->shaderprog->setUniformMat4("projection_view_matrix", GlobalCanvasSettings::getPVMatrix());
|
||||
this->shaderprog->setUniformVec3("camera_position", GlobalCanvasSettings::getCameraPosition());
|
||||
|
||||
int spec_num = 0;
|
||||
int diff_num = 0;
|
||||
/* Setup the texture samplers */
|
||||
for (unsigned int i = 0; i < this->textures.size(); i++) {
|
||||
std::string uniform_name;
|
||||
textures[i]->use(i);
|
||||
switch (textures[i]->getType()) {
|
||||
case TEXTURE_DIFFUSE:
|
||||
uniform_name = "material.diffuse" + std::to_string(diff_num++);
|
||||
this->shaderprog->setUniformInt(uniform_name, i);
|
||||
break;
|
||||
case TEXTURE_SPECULAR:
|
||||
uniform_name = "material.specular" + std::to_string(spec_num++);
|
||||
this->shaderprog->setUniformInt(uniform_name, i);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(this->vao);
|
||||
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
129
src/model.cpp
Normal file
129
src/model.cpp
Normal file
@ -0,0 +1,129 @@
|
||||
#include <opengl-playground/model.hpp>
|
||||
#include <iostream>
|
||||
|
||||
Model::Model(const std::string &path, const glm::vec4 &static_color, std::shared_ptr<OpenGlShaderProgram> shader)
|
||||
: OpenGlGraphics(shader)
|
||||
{
|
||||
this->model_path = path;
|
||||
this->static_color = static_color;
|
||||
}
|
||||
|
||||
void Model::render()
|
||||
{
|
||||
for (unsigned int i = 0; i < meshes.size(); i++) {
|
||||
meshes[i].render(this->model_matrix, this->normal_matrix);
|
||||
}
|
||||
}
|
||||
|
||||
void Model::realize()
|
||||
{
|
||||
Assimp::Importer importer;
|
||||
|
||||
const aiScene *scene = importer.ReadFile(this->model_path, aiProcess_Triangulate | aiProcess_FlipUVs);
|
||||
|
||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
|
||||
std::cout << "Error: Assimp: " << importer.GetErrorString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
this->directory = this->model_path.substr(0, this->model_path.find_last_of('/'));
|
||||
this->processNode(scene->mRootNode, scene);
|
||||
|
||||
importer.FreeScene();
|
||||
}
|
||||
|
||||
void Model::processNode(aiNode *node, const aiScene *scene)
|
||||
{
|
||||
for(unsigned int i = 0; i < node->mNumMeshes; i++)
|
||||
{
|
||||
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
|
||||
this->meshes.push_back(this->processMesh(mesh, scene));
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < node->mNumChildren; i++)
|
||||
{
|
||||
this->processNode(node->mChildren[i], scene);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::shared_ptr<OpenGlTexture>> Model::loadMaterialTextures(aiMaterial *mat, aiTextureType type,
|
||||
TextureType tex_type)
|
||||
{
|
||||
std::vector<std::shared_ptr<OpenGlTexture>> tex_vector;
|
||||
|
||||
for (unsigned int i = 0; i < mat->GetTextureCount(type); i++) {
|
||||
aiString str;
|
||||
mat->GetTexture(type, i, &str);
|
||||
bool already_loaded = false;
|
||||
for (unsigned int j = 0; j < this->allocated_textures.size(); j++) {
|
||||
if (std::strcmp(this->allocated_textures[j]->getPath().c_str(), str.C_Str()) == 0) {
|
||||
/* texture already loaded */
|
||||
tex_vector.push_back(this->allocated_textures[j]);
|
||||
already_loaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!already_loaded) {
|
||||
auto new_texture = std::make_shared<OpenGlTexture>(tex_type, str.C_Str());
|
||||
new_texture->loadFromImagePath(this->directory);
|
||||
tex_vector.push_back(new_texture);
|
||||
this->allocated_textures.push_back(new_texture);
|
||||
}
|
||||
}
|
||||
|
||||
return tex_vector;
|
||||
}
|
||||
|
||||
Mesh Model::processMesh(aiMesh *mesh, const aiScene *scene)
|
||||
{
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
std::vector<std::shared_ptr<OpenGlTexture>> textures;
|
||||
|
||||
for(unsigned int i = 0; i < mesh->mNumVertices; i++)
|
||||
{
|
||||
Vertex vertex;
|
||||
glm::vec3 vector;
|
||||
vector.x = mesh->mVertices[i].x;
|
||||
vector.y = mesh->mVertices[i].y;
|
||||
vector.z = mesh->mVertices[i].z;
|
||||
vertex.Position = vector;
|
||||
vector.x = mesh->mNormals[i].x;
|
||||
vector.y = mesh->mNormals[i].y;
|
||||
vector.z = mesh->mNormals[i].z;
|
||||
vertex.Normal = vector;
|
||||
|
||||
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);
|
||||
}
|
||||
// process indices
|
||||
for(unsigned int i = 0; i < mesh->mNumFaces; i++)
|
||||
{
|
||||
aiFace face = mesh->mFaces[i];
|
||||
for(unsigned int j = 0; j < face.mNumIndices; j++)
|
||||
indices.push_back(face.mIndices[j]);
|
||||
}
|
||||
|
||||
if(mesh->mMaterialIndex >= 0)
|
||||
{
|
||||
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
auto diffuseTextures = loadMaterialTextures(material, aiTextureType_DIFFUSE, TEXTURE_DIFFUSE);
|
||||
auto specularTextures = loadMaterialTextures(material, aiTextureType_SPECULAR, TEXTURE_SPECULAR);
|
||||
textures.insert(textures.end(), diffuseTextures.begin(), diffuseTextures.end());
|
||||
textures.insert(textures.end(), specularTextures.begin(), specularTextures.end());
|
||||
}
|
||||
|
||||
|
||||
Mesh my_mesh = Mesh(vertices, indices, textures, this->shaderprog);
|
||||
my_mesh.realize();
|
||||
return my_mesh;
|
||||
}
|
@ -16,9 +16,15 @@ OpenGlGraphics::~OpenGlGraphics()
|
||||
void OpenGlGraphics::setModelMatrix(const glm::mat4 &model_matrix)
|
||||
{
|
||||
this->model_matrix = model_matrix;
|
||||
this->normal_matrix = glm::transpose(glm::inverse(model_matrix));
|
||||
}
|
||||
|
||||
glm::mat4 OpenGlGraphics::getModelMatrix()
|
||||
{
|
||||
return this->model_matrix;
|
||||
}
|
||||
|
||||
glm::mat4 OpenGlGraphics::getNormalMatrix()
|
||||
{
|
||||
return this->normal_matrix;
|
||||
}
|
||||
|
@ -184,6 +184,14 @@ void OpenGlShaderProgram::setUniformVec2(const std::string &uniform, float *vect
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGlShaderProgram::setUniformVec3(const std::string &uniform, const glm::vec3 &vector)
|
||||
{
|
||||
int loc = this->getUniformLoc(uniform);
|
||||
if (loc >= 0) {
|
||||
glUniform3fv(loc, 1, &vector.x);
|
||||
}
|
||||
}
|
||||
|
||||
void OpenGlShaderProgram::setUniformMat4(const std::string &uniform, const glm::mat4 &matrix)
|
||||
{
|
||||
int loc = this->getUniformLoc(uniform);
|
||||
|
@ -1,6 +1,10 @@
|
||||
#include <opengl-playground/opengltexture.hpp>
|
||||
|
||||
OpenGlTexture::OpenGlTexture()
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include <stb/stb_image.h>
|
||||
#include <iostream>
|
||||
|
||||
OpenGlTexture::OpenGlTexture(TextureType type, const std::string &texture_path)
|
||||
{
|
||||
glGenTextures(1, &this->texture);
|
||||
glBindTexture(GL_TEXTURE_2D, this->texture);
|
||||
@ -8,6 +12,13 @@ OpenGlTexture::OpenGlTexture()
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
this->type = type;
|
||||
this->texture_path = texture_path;
|
||||
}
|
||||
|
||||
OpenGlTexture::OpenGlTexture() : OpenGlTexture(TEXTURE_DIFFUSE, "")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
OpenGlTexture::~OpenGlTexture()
|
||||
@ -22,6 +33,36 @@ void OpenGlTexture::setRGBDataFromBytes(unsigned int width, unsigned int height,
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void OpenGlTexture::loadFromImagePath(const std::string &base_directory)
|
||||
{
|
||||
int width, height, nrChannels;
|
||||
std::string filename = this->texture_path;
|
||||
filename = base_directory + '/' + filename;
|
||||
|
||||
unsigned char *data = stbi_load(filename.c_str(), &width, &height, &nrChannels, 0);
|
||||
if (data) {
|
||||
GLenum format = 0;
|
||||
if (nrChannels == 1)
|
||||
format = GL_RED;
|
||||
else if (nrChannels == 3)
|
||||
format = GL_RGB;
|
||||
else if (nrChannels == 4)
|
||||
format = GL_RGBA;
|
||||
|
||||
this->use();
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
|
||||
} else {
|
||||
std::cout << "Texture loading of " << this->getPath() << " failed" << std::endl;
|
||||
}
|
||||
stbi_image_free(data);
|
||||
}
|
||||
|
||||
void OpenGlTexture::use(unsigned int slot)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
@ -32,3 +73,13 @@ void OpenGlTexture::use()
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, this->texture);
|
||||
}
|
||||
|
||||
const std::string &OpenGlTexture::getPath()
|
||||
{
|
||||
return this->texture_path;
|
||||
}
|
||||
|
||||
TextureType OpenGlTexture::getType()
|
||||
{
|
||||
return this->type;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@ SdlMainWindow::~SdlMainWindow()
|
||||
|
||||
void SdlMainWindow::show()
|
||||
{
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 16);
|
||||
this->window = SDL_CreateWindow("OpenGL Playground", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
this->width, this->height, SDL_WINDOW_OPENGL);
|
||||
return;
|
||||
@ -40,8 +39,6 @@ void SdlMainWindow::activateGlContext()
|
||||
this->context = SDL_GL_CreateContext(this->window);
|
||||
else
|
||||
SDL_GL_MakeCurrent(this->window, this->context);
|
||||
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
}
|
||||
|
||||
SDL_Window *SdlMainWindow::getWindow()
|
||||
|
1
src/vertex.cpp
Normal file
1
src/vertex.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include <opengl-playground/vertex.hpp>
|
Loading…
Reference in New Issue
Block a user