Add OpenGL test project with backpack model and textures
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
const unsigned int SCR_WIDTH = 800;
|
const unsigned int SCR_WIDTH = 800;
|
||||||
const unsigned int SCR_HEIGHT = 600;
|
const unsigned int SCR_HEIGHT = 600;
|
||||||
@@ -35,6 +36,8 @@ class Shader
|
|||||||
public:
|
public:
|
||||||
unsigned int ID;
|
unsigned int ID;
|
||||||
|
|
||||||
|
Shader() : ID(0) {}
|
||||||
|
|
||||||
Shader(const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr)
|
Shader(const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr)
|
||||||
{
|
{
|
||||||
std::string vertexCode;
|
std::string vertexCode;
|
||||||
@@ -222,28 +225,51 @@ public:
|
|||||||
setupMesh();
|
setupMesh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int defaultTexture = 0;
|
||||||
|
|
||||||
void Draw(Shader* shader)
|
void Draw(Shader* shader)
|
||||||
{
|
{
|
||||||
|
static unsigned int defaultTex = 0;
|
||||||
|
static bool defaultTexCreated = false;
|
||||||
|
if (!defaultTexCreated) {
|
||||||
|
glGenTextures(1, &defaultTex);
|
||||||
|
unsigned char white[] = {200, 200, 200, 255};
|
||||||
|
glBindTexture(GL_TEXTURE_2D, defaultTex);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, white);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
defaultTexCreated = true;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int diffuseNr = 1;
|
unsigned int diffuseNr = 1;
|
||||||
unsigned int specularNr = 1;
|
unsigned int specularNr = 1;
|
||||||
unsigned int normalNr = 1;
|
unsigned int normalNr = 1;
|
||||||
unsigned int heightNr = 1;
|
unsigned int heightNr = 1;
|
||||||
for (unsigned int i = 0; i < textures.size(); i++)
|
|
||||||
|
if (textures.size() == 0) {
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glUniform1i(glGetUniformLocation(shader->ID, "material.texture_diffuse1"), 0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, defaultTex);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE0 + i);
|
for (unsigned int i = 0; i < textures.size(); i++)
|
||||||
std::string number;
|
{
|
||||||
std::string name = textures[i].type;
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
if (name == "texture_diffuse")
|
std::string number;
|
||||||
number = std::to_string(diffuseNr++);
|
std::string name = textures[i].type;
|
||||||
else if (name == "texture_specular")
|
if (name == "texture_diffuse")
|
||||||
number = std::to_string(specularNr++);
|
number = std::to_string(diffuseNr++);
|
||||||
else if (name == "texture_normal")
|
else if (name == "texture_specular")
|
||||||
number = std::to_string(normalNr++);
|
number = std::to_string(specularNr++);
|
||||||
else if (name == "texture_height")
|
else if (name == "texture_normal")
|
||||||
number = std::to_string(heightNr++);
|
number = std::to_string(normalNr++);
|
||||||
|
else if (name == "texture_height")
|
||||||
|
number = std::to_string(heightNr++);
|
||||||
|
|
||||||
glUniform1i(glGetUniformLocation(shader->ID, ("material." + name + number).c_str()), i);
|
glUniform1i(glGetUniformLocation(shader->ID, ("material." + name + number).c_str()), i);
|
||||||
glBindTexture(GL_TEXTURE_2D, textures[i].id);
|
glBindTexture(GL_TEXTURE_2D, textures[i].id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindVertexArray(VAO);
|
glBindVertexArray(VAO);
|
||||||
@@ -300,6 +326,7 @@ unsigned int TextureFromFile(const char* path, const std::string& directory, boo
|
|||||||
unsigned char* data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0);
|
unsigned char* data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0);
|
||||||
if (data)
|
if (data)
|
||||||
{
|
{
|
||||||
|
std::cout << "Loaded texture: " << filename << " (" << width << "x" << height << ")" << std::endl;
|
||||||
GLenum format;
|
GLenum format;
|
||||||
if (nrComponents == 1)
|
if (nrComponents == 1)
|
||||||
format = GL_RED;
|
format = GL_RED;
|
||||||
@@ -321,8 +348,26 @@ unsigned int TextureFromFile(const char* path, const std::string& directory, boo
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Texture failed to load at path: " << path << std::endl;
|
std::cout << "Texture not found: " << filename << ", trying earth_d.jpg" << std::endl;
|
||||||
stbi_image_free(data);
|
std::string fallback = directory + "/earth_d.jpg";
|
||||||
|
data = stbi_load(fallback.c_str(), &width, &height, &nrComponents, 0);
|
||||||
|
if (data) {
|
||||||
|
std::cout << "Loaded fallback: " << fallback << " (" << width << "x" << height << ")" << std::endl;
|
||||||
|
GLenum format = nrComponents == 4 ? GL_RGBA : GL_RGB;
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
stbi_image_free(data);
|
||||||
|
} else {
|
||||||
|
std::cout << "Fallback also failed, using white" << std::endl;
|
||||||
|
unsigned char white[] = {200, 200, 200, 255};
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, white);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return textureID;
|
return textureID;
|
||||||
@@ -673,36 +718,48 @@ void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
|||||||
|
|
||||||
void Initialize()
|
void Initialize()
|
||||||
{
|
{
|
||||||
camera = new Camera(glm::vec3(-1, 0, 3), 0, 0);
|
char exePath[MAX_PATH];
|
||||||
|
GetModuleFileNameA(NULL, exePath, MAX_PATH);
|
||||||
|
std::string exeDir = std::string(exePath);
|
||||||
|
exeDir = exeDir.substr(0, exeDir.find_last_of("\\/"));
|
||||||
|
|
||||||
|
SetCurrentDirectoryA(exeDir.c_str());
|
||||||
|
|
||||||
|
std::cout << "Working directory: " << exeDir << std::endl;
|
||||||
|
|
||||||
|
camera = new Camera(glm::vec3(0, 0, 3), 0, 0);
|
||||||
|
std::cout << "Loading model..." << std::endl;
|
||||||
model = new Model("res/models/backpack/backpack.obj");
|
model = new Model("res/models/backpack/backpack.obj");
|
||||||
|
std::cout << "Model loaded, meshes: " << model->meshes.size() << std::endl;
|
||||||
|
std::cout << "Textures loaded: " << model->textures_loaded.size() << std::endl;
|
||||||
shader = new Shader("Shaders/vertexshader.glsl", "Shaders/fragmentshader.glsl");
|
shader = new Shader("Shaders/vertexshader.glsl", "Shaders/fragmentshader.glsl");
|
||||||
|
std::cout << "Shader loaded" << std::endl;
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Render()
|
void Render()
|
||||||
{
|
{
|
||||||
glClearColor(0, 0, 0, 1.0f);
|
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
shader->use();
|
shader->use();
|
||||||
Transform();
|
|
||||||
|
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
|
||||||
|
glm::mat4 modelMat = glm::mat4(1.0f);
|
||||||
|
glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 3), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
|
||||||
|
|
||||||
|
shader->setMat4("view", view);
|
||||||
|
shader->setMat4("model", modelMat);
|
||||||
|
shader->setMat4("projection", projection);
|
||||||
|
shader->setVec3("viewPos", glm::vec3(0, 0, 3));
|
||||||
|
|
||||||
shader->setFloat("material.shininess", 32.0f);
|
shader->setFloat("material.shininess", 32.0f);
|
||||||
|
|
||||||
shader->setVec3("dirLight.direction", 0.0f, -1.0f, 0.0f);
|
shader->setVec3("dirLight.direction", 0.0f, -1.0f, 0.0f);
|
||||||
shader->setVec3("dirLight.ambient", 0.1f, 0.1f, 0.1f);
|
shader->setVec3("dirLight.ambient", 0.3f, 0.3f, 0.3f);
|
||||||
shader->setVec3("dirLight.diffuse", 0.4f, 0.4f, 0.4f);
|
shader->setVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f);
|
||||||
shader->setVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
|
shader->setVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
|
||||||
|
shader->setInt("PointLightNum", 0);
|
||||||
shader->setInt("PointLightNum", 3);
|
|
||||||
|
|
||||||
shader->setVec3("pointLights[0].position", glm::vec3(0.0f, -1.0f, 0.0f));
|
|
||||||
shader->setVec3("pointLights[0].ambient", 0.05f, 0.05f, 0.05f);
|
|
||||||
shader->setVec3("pointLights[0].diffuse", 0.8f, 0.8f, 0.8f);
|
|
||||||
shader->setVec3("pointLights[0].specular", 1.0f, 1.0f, 1.0f);
|
|
||||||
shader->setFloat("pointLights[0].constant", 1.0f);
|
|
||||||
shader->setFloat("pointLights[0].linear", 0.09f);
|
|
||||||
shader->setFloat("pointLights[0].quadratic", 0.032f);
|
|
||||||
|
|
||||||
model->Draw(shader);
|
model->Draw(shader);
|
||||||
}
|
}
|
||||||
@@ -710,13 +767,11 @@ void Render()
|
|||||||
void Transform()
|
void Transform()
|
||||||
{
|
{
|
||||||
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
|
glm::mat4 projection = glm::perspective(glm::radians(45.0f), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
|
||||||
origine = glm::rotate(origine, glm::radians(-0.01f), glm::vec3(1.0f, 1.0f, 1.0f));
|
glm::mat4 modelMat = glm::mat4(1.0f);
|
||||||
glm::mat4 modelMat = origine;
|
glm::mat4 view = glm::lookAt(glm::vec3(0, 0, 3), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
|
||||||
glm::mat4 cameraTrans = camera->GetTrans();
|
|
||||||
glm::mat4 view = glm::inverse(cameraTrans);
|
|
||||||
|
|
||||||
shader->setMat4("view", view);
|
shader->setMat4("view", view);
|
||||||
shader->setMat4("model", modelMat);
|
shader->setMat4("model", modelMat);
|
||||||
shader->setMat4("projection", projection);
|
shader->setMat4("projection", projection);
|
||||||
shader->setVec3("viewPos", camera->GetPos());
|
shader->setVec3("viewPos", glm::vec3(0, 0, 3));
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
tests/OpenGL/res/models/backpack/ao.jpg
Normal file
BIN
tests/OpenGL/res/models/backpack/ao.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 MiB |
16
tests/OpenGL/res/models/backpack/backpack.mtl
Normal file
16
tests/OpenGL/res/models/backpack/backpack.mtl
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# Blender MTL File: 'None'
|
||||||
|
# Material Count: 1
|
||||||
|
|
||||||
|
newmtl Scene_-_Root
|
||||||
|
Ns 225.000000
|
||||||
|
Ka 1.000000 1.000000 1.000000
|
||||||
|
Kd 0.800000 0.800000 0.800000
|
||||||
|
Ks 0.500000 0.500000 0.500000
|
||||||
|
Ke 0.0 0.0 0.0
|
||||||
|
Ni 1.450000
|
||||||
|
d 1.000000
|
||||||
|
illum 2
|
||||||
|
map_Kd diffuse.jpg
|
||||||
|
map_Bump normal.png
|
||||||
|
map_Ks specular.jpg
|
||||||
|
|
||||||
BIN
tests/OpenGL/res/models/backpack/diffuse.jpg
Normal file
BIN
tests/OpenGL/res/models/backpack/diffuse.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.8 MiB |
BIN
tests/OpenGL/res/models/backpack/normal.png
Normal file
BIN
tests/OpenGL/res/models/backpack/normal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 MiB |
BIN
tests/OpenGL/res/models/backpack/roughness.jpg
Normal file
BIN
tests/OpenGL/res/models/backpack/roughness.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 MiB |
3
tests/OpenGL/res/models/backpack/source_attribution.txt
Normal file
3
tests/OpenGL/res/models/backpack/source_attribution.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Model by Berk Gedik, from: https://sketchfab.com/3d-models/survival-guitar-backpack-low-poly-799f8c4511f84fab8c3f12887f7e6b36
|
||||||
|
|
||||||
|
Modified material assignment (Joey de Vries) for easier load in OpenGL model loading chapter, and renamed albedo to diffuse and metallic to specular to match non-PBR lighting setup.
|
||||||
BIN
tests/OpenGL/res/models/backpack/specular.jpg
Normal file
BIN
tests/OpenGL/res/models/backpack/specular.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 MiB |
Reference in New Issue
Block a user