精简 OpenGL 测试代码,移除冗余功能
This commit is contained in:
@@ -1,12 +1,10 @@
|
||||
#include <glad/glad.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/scene.h>
|
||||
#include <assimp/postprocess.h>
|
||||
@@ -19,18 +17,6 @@
|
||||
const unsigned int SCR_WIDTH = 800;
|
||||
const unsigned int SCR_HEIGHT = 600;
|
||||
|
||||
enum Camera_Movement {
|
||||
CAMERA_FORWARD,
|
||||
CAMERA_BACKWARD,
|
||||
CAMERA_RIGHT,
|
||||
CAMERA_LEFT
|
||||
};
|
||||
|
||||
class Shader;
|
||||
class Model;
|
||||
class Camera;
|
||||
class Mesh;
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
@@ -38,21 +24,14 @@ public:
|
||||
|
||||
Shader() : ID(0) {}
|
||||
|
||||
Shader(const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr)
|
||||
Shader(const char* vertexPath, const char* fragmentPath)
|
||||
{
|
||||
std::string vertexCode;
|
||||
std::string fragmentCode;
|
||||
std::string geometryCode;
|
||||
std::ifstream vShaderFile;
|
||||
std::ifstream fShaderFile;
|
||||
std::ifstream gShaderFile;
|
||||
std::string vertexCode, fragmentCode;
|
||||
std::ifstream vShaderFile(vertexPath), fShaderFile(fragmentPath);
|
||||
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
gShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
try
|
||||
{
|
||||
vShaderFile.open(vertexPath);
|
||||
fShaderFile.open(fragmentPath);
|
||||
std::stringstream vShaderStream, fShaderStream;
|
||||
vShaderStream << vShaderFile.rdbuf();
|
||||
fShaderStream << fShaderFile.rdbuf();
|
||||
@@ -60,62 +39,37 @@ public:
|
||||
fShaderFile.close();
|
||||
vertexCode = vShaderStream.str();
|
||||
fragmentCode = fShaderStream.str();
|
||||
|
||||
if (geometryPath != nullptr)
|
||||
{
|
||||
gShaderFile.open(geometryPath);
|
||||
std::stringstream gShaderStream;
|
||||
gShaderStream << gShaderFile.rdbuf();
|
||||
gShaderFile.close();
|
||||
geometryCode = gShaderStream.str();
|
||||
}
|
||||
}
|
||||
catch (std::ifstream::failure& e)
|
||||
{
|
||||
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ: " << e.what() << std::endl;
|
||||
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
|
||||
}
|
||||
|
||||
const char* vShaderCode = vertexCode.c_str();
|
||||
const char* fShaderCode = fragmentCode.c_str();
|
||||
unsigned int vertex = 0, fragment;
|
||||
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
|
||||
unsigned int vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
||||
glCompileShader(vertex);
|
||||
checkCompileErrors(vertex, "VERTEX");
|
||||
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
unsigned int fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
||||
glCompileShader(fragment);
|
||||
checkCompileErrors(fragment, "FRAGMENT");
|
||||
unsigned int geometry;
|
||||
if (geometryPath != nullptr)
|
||||
{
|
||||
const char* gShaderCode = geometryCode.c_str();
|
||||
geometry = glCreateShader(GL_GEOMETRY_SHADER);
|
||||
glShaderSource(geometry, 1, &gShaderCode, NULL);
|
||||
glCompileShader(geometry);
|
||||
checkCompileErrors(geometry, "GEOMETRY");
|
||||
}
|
||||
|
||||
ID = glCreateProgram();
|
||||
glAttachShader(ID, vertex);
|
||||
glAttachShader(ID, fragment);
|
||||
if (geometryPath != nullptr)
|
||||
glAttachShader(ID, geometry);
|
||||
glLinkProgram(ID);
|
||||
checkCompileErrors(ID, "PROGRAM");
|
||||
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
if (geometryPath != nullptr)
|
||||
glDeleteShader(geometry);
|
||||
}
|
||||
|
||||
void use()
|
||||
{
|
||||
glUseProgram(ID);
|
||||
}
|
||||
void use() { glUseProgram(ID); }
|
||||
|
||||
void setBool(const std::string& name, bool value) const
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
|
||||
}
|
||||
void setInt(const std::string& name, int value) const
|
||||
{
|
||||
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
|
||||
@@ -124,14 +78,6 @@ public:
|
||||
{
|
||||
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
|
||||
}
|
||||
void setVec2(const std::string& name, const glm::vec2& value) const
|
||||
{
|
||||
glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||
}
|
||||
void setVec2(const std::string& name, float x, float y) const
|
||||
{
|
||||
glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y);
|
||||
}
|
||||
void setVec3(const std::string& name, const glm::vec3& value) const
|
||||
{
|
||||
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||
@@ -140,22 +86,6 @@ public:
|
||||
{
|
||||
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
|
||||
}
|
||||
void setVec4(const std::string& name, const glm::vec4& value) const
|
||||
{
|
||||
glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
|
||||
}
|
||||
void setVec4(const std::string& name, float x, float y, float z, float w)
|
||||
{
|
||||
glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w);
|
||||
}
|
||||
void setMat2(const std::string& name, const glm::mat2& mat) const
|
||||
{
|
||||
glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
void setMat3(const std::string& name, const glm::mat3& mat) const
|
||||
{
|
||||
glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||
}
|
||||
void setMat4(const std::string& name, const glm::mat4& mat) const
|
||||
{
|
||||
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
|
||||
@@ -172,32 +102,26 @@ private:
|
||||
if (!success)
|
||||
{
|
||||
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
||||
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
|
||||
std::cout << "ERROR::SHADER_COMPILATION_ERROR: " << type << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glGetProgramiv(shader, GL_LINK_STATUS, &success);
|
||||
glGetProgramiv(ID, GL_LINK_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetProgramInfoLog(shader, 1024, NULL, infoLog);
|
||||
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
|
||||
glGetProgramInfoLog(ID, 1024, NULL, infoLog);
|
||||
std::cout << "ERROR::PROGRAM_LINKING_ERROR" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#define MAX_BONE_INFLUENCE 4
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
glm::vec3 Position;
|
||||
glm::vec3 Normal;
|
||||
glm::vec2 TexCoords;
|
||||
glm::vec3 Tangent;
|
||||
glm::vec3 Bitangent;
|
||||
int m_BoneIDs[MAX_BONE_INFLUENCE];
|
||||
float m_Weights[MAX_BONE_INFLUENCE];
|
||||
};
|
||||
|
||||
struct Texture
|
||||
@@ -207,8 +131,6 @@ struct Texture
|
||||
std::string path;
|
||||
};
|
||||
|
||||
unsigned int TextureFromFile(const char* path, const std::string& directory, bool gamma = false);
|
||||
|
||||
class Mesh
|
||||
{
|
||||
public:
|
||||
@@ -225,55 +147,26 @@ public:
|
||||
setupMesh();
|
||||
}
|
||||
|
||||
unsigned int defaultTexture = 0;
|
||||
|
||||
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 specularNr = 1;
|
||||
unsigned int normalNr = 1;
|
||||
unsigned int heightNr = 1;
|
||||
|
||||
if (textures.size() == 0) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glUniform1i(glGetUniformLocation(shader->ID, "material.texture_diffuse1"), 0);
|
||||
glBindTexture(GL_TEXTURE_2D, defaultTex);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int i = 0; i < textures.size(); i++)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
std::string number;
|
||||
std::string name = textures[i].type;
|
||||
if (name == "texture_diffuse")
|
||||
number = std::to_string(diffuseNr++);
|
||||
else if (name == "texture_specular")
|
||||
number = std::to_string(specularNr++);
|
||||
else if (name == "texture_normal")
|
||||
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);
|
||||
glBindTexture(GL_TEXTURE_2D, textures[i].id);
|
||||
}
|
||||
for (unsigned int i = 0; i < textures.size(); i++)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
std::string number;
|
||||
std::string name = textures[i].type;
|
||||
if (name == "texture_diffuse")
|
||||
number = std::to_string(diffuseNr++);
|
||||
else if (name == "texture_specular")
|
||||
number = std::to_string(specularNr++);
|
||||
|
||||
glUniform1i(glGetUniformLocation(shader->ID, ("material." + name + number).c_str()), i);
|
||||
glBindTexture(GL_TEXTURE_2D, textures[i].id);
|
||||
}
|
||||
|
||||
glBindVertexArray(VAO);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glDrawElements(GL_TRIANGLES, static_cast<unsigned int>(indices.size()), GL_UNSIGNED_INT, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
@@ -300,24 +193,14 @@ private:
|
||||
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, TexCoords));
|
||||
glEnableVertexAttribArray(3);
|
||||
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Tangent));
|
||||
glEnableVertexAttribArray(4);
|
||||
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, Bitangent));
|
||||
glEnableVertexAttribArray(5);
|
||||
glVertexAttribIPointer(5, 4, GL_INT, sizeof(Vertex), (void*)offsetof(Vertex, m_BoneIDs));
|
||||
glEnableVertexAttribArray(6);
|
||||
glVertexAttribPointer(6, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, m_Weights));
|
||||
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
};
|
||||
|
||||
unsigned int TextureFromFile(const char* path, const std::string& directory, bool gamma)
|
||||
unsigned int TextureFromFile(const char* path, const std::string& directory)
|
||||
{
|
||||
std::string filename = std::string(path);
|
||||
filename = directory + '/' + filename;
|
||||
|
||||
std::string filename = directory + '/' + std::string(path);
|
||||
unsigned int textureID;
|
||||
glGenTextures(1, &textureID);
|
||||
|
||||
@@ -326,50 +209,20 @@ unsigned int TextureFromFile(const char* path, const std::string& directory, boo
|
||||
unsigned char* data = stbi_load(filename.c_str(), &width, &height, &nrComponents, 0);
|
||||
if (data)
|
||||
{
|
||||
std::cout << "Loaded texture: " << filename << " (" << width << "x" << height << ")" << std::endl;
|
||||
GLenum format;
|
||||
if (nrComponents == 1)
|
||||
format = GL_RED;
|
||||
else if (nrComponents == 3)
|
||||
format = GL_RGB;
|
||||
else if (nrComponents == 4)
|
||||
format = GL_RGBA;
|
||||
|
||||
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_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);
|
||||
|
||||
stbi_image_free(data);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Texture not found: " << filename << ", trying earth_d.jpg" << std::endl;
|
||||
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);
|
||||
}
|
||||
stbi_image_free(data);
|
||||
}
|
||||
|
||||
return textureID;
|
||||
}
|
||||
|
||||
@@ -379,29 +232,25 @@ public:
|
||||
std::vector<Texture> textures_loaded;
|
||||
std::vector<Mesh> meshes;
|
||||
std::string directory;
|
||||
bool gammaCorrection;
|
||||
|
||||
Model(std::string const& path, bool gamma = false) : gammaCorrection(gamma)
|
||||
Model(std::string const& path)
|
||||
{
|
||||
loadModel(path);
|
||||
}
|
||||
|
||||
void Draw(Shader* shader)
|
||||
{
|
||||
for (unsigned int i = 0; i < meshes.size(); i++)
|
||||
{
|
||||
meshes[i].Draw(shader);
|
||||
}
|
||||
for (auto& mesh : meshes)
|
||||
mesh.Draw(shader);
|
||||
}
|
||||
|
||||
private:
|
||||
void loadModel(std::string const& path)
|
||||
{
|
||||
Assimp::Importer importer;
|
||||
const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs | aiProcess_CalcTangentSpace);
|
||||
const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs);
|
||||
if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode)
|
||||
{
|
||||
std::cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << std::endl;
|
||||
return;
|
||||
}
|
||||
directory = path.substr(0, path.find_last_of('/'));
|
||||
@@ -416,9 +265,7 @@ private:
|
||||
meshes.push_back(processMesh(mesh, scene));
|
||||
}
|
||||
for (unsigned int i = 0; i < node->mNumChildren; i++)
|
||||
{
|
||||
processNode(node->mChildren[i], scene);
|
||||
}
|
||||
}
|
||||
|
||||
Mesh processMesh(aiMesh* mesh, const aiScene* scene)
|
||||
@@ -430,40 +277,12 @@ private:
|
||||
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;
|
||||
|
||||
if (mesh->HasNormals())
|
||||
{
|
||||
vector.x = mesh->mNormals[i].x;
|
||||
vector.y = mesh->mNormals[i].y;
|
||||
vector.z = mesh->mNormals[i].z;
|
||||
vertex.Normal = vector;
|
||||
}
|
||||
|
||||
vertex.Position = glm::vec3(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
|
||||
vertex.Normal = glm::vec3(mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z);
|
||||
if (mesh->mTextureCoords[0])
|
||||
{
|
||||
glm::vec2 vec;
|
||||
vec.x = mesh->mTextureCoords[0][i].x;
|
||||
vec.y = mesh->mTextureCoords[0][i].y;
|
||||
vertex.TexCoords = vec;
|
||||
|
||||
vector.x = mesh->mTangents[i].x;
|
||||
vector.y = mesh->mTangents[i].y;
|
||||
vector.z = mesh->mTangents[i].z;
|
||||
vertex.Tangent = vector;
|
||||
|
||||
vector.x = mesh->mBitangents[i].x;
|
||||
vector.y = mesh->mBitangents[i].y;
|
||||
vector.z = mesh->mBitangents[i].z;
|
||||
vertex.Bitangent = vector;
|
||||
}
|
||||
vertex.TexCoords = glm::vec2(mesh->mTextureCoords[0][i].x, mesh->mTextureCoords[0][i].y);
|
||||
else
|
||||
vertex.TexCoords = glm::vec2(0.0f, 0.0f);
|
||||
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
|
||||
@@ -475,15 +294,10 @@ private:
|
||||
}
|
||||
|
||||
aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];
|
||||
|
||||
std::vector<Texture> diffuseMaps = loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse");
|
||||
textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());
|
||||
std::vector<Texture> specularMaps = loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular");
|
||||
textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());
|
||||
std::vector<Texture> normalMaps = loadMaterialTextures(material, aiTextureType_HEIGHT, "texture_normal");
|
||||
textures.insert(textures.end(), normalMaps.begin(), normalMaps.end());
|
||||
std::vector<Texture> heightMaps = loadMaterialTextures(material, aiTextureType_AMBIENT, "texture_height");
|
||||
textures.insert(textures.end(), heightMaps.begin(), heightMaps.end());
|
||||
|
||||
return Mesh(vertices, indices, textures);
|
||||
}
|
||||
@@ -496,11 +310,11 @@ private:
|
||||
aiString str;
|
||||
mat->GetTexture(type, i, &str);
|
||||
bool skip = false;
|
||||
for (unsigned int j = 0; j < textures_loaded.size(); j++)
|
||||
for (auto& tex : textures_loaded)
|
||||
{
|
||||
if (std::strcmp(textures_loaded[j].path.data(), str.C_Str()) == 0)
|
||||
if (tex.path == str.C_Str())
|
||||
{
|
||||
textures.push_back(textures_loaded[j]);
|
||||
textures.push_back(tex);
|
||||
skip = true;
|
||||
break;
|
||||
}
|
||||
@@ -508,7 +322,7 @@ private:
|
||||
if (!skip)
|
||||
{
|
||||
Texture texture;
|
||||
texture.id = TextureFromFile(str.C_Str(), this->directory);
|
||||
texture.id = TextureFromFile(str.C_Str(), directory);
|
||||
texture.type = typeName;
|
||||
texture.path = str.C_Str();
|
||||
textures.push_back(texture);
|
||||
@@ -519,197 +333,8 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
float moveSpeed = 1.5f;
|
||||
float mouseSensitivity = 0.1f;
|
||||
|
||||
Camera(glm::vec3 _position, float _yaw = 0.0f, float _pitch = 0.0f, float _fov = 45.0f)
|
||||
{
|
||||
position = _position;
|
||||
yaw = _yaw;
|
||||
pitch = _pitch;
|
||||
zoom = _fov;
|
||||
glm::mat4 translate = glm::translate(identity, position);
|
||||
glm::mat4 rotate = glm::rotate(identity, glm::radians(yaw), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
rotate = glm::rotate(rotate, glm::radians(pitch), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
trans = translate * rotate;
|
||||
}
|
||||
|
||||
void Move(Camera_Movement move, float delta)
|
||||
{
|
||||
glm::vec3 dPosition = glm::vec3(0.0f);
|
||||
switch (move)
|
||||
{
|
||||
case CAMERA_FORWARD:
|
||||
dPosition = front * moveSpeed * delta;
|
||||
break;
|
||||
case CAMERA_BACKWARD:
|
||||
dPosition = back * moveSpeed * delta;
|
||||
break;
|
||||
case CAMERA_LEFT:
|
||||
dPosition = left * moveSpeed * delta;
|
||||
break;
|
||||
case CAMERA_RIGHT:
|
||||
dPosition = right * moveSpeed * delta;
|
||||
break;
|
||||
}
|
||||
|
||||
glm::mat4 translate = glm::translate(identity, dPosition);
|
||||
trans = trans * translate;
|
||||
}
|
||||
|
||||
void Rotate(float xoffset, float yoffset)
|
||||
{
|
||||
float dYaw = 0, dPitch = 0;
|
||||
dYaw = -xoffset * mouseSensitivity;
|
||||
if (pitch < 89.0f && yoffset < 0 || pitch > -89.0 && yoffset > 0)
|
||||
{
|
||||
dPitch = -yoffset * mouseSensitivity;
|
||||
}
|
||||
|
||||
yaw += dYaw;
|
||||
pitch += dPitch;
|
||||
|
||||
glm::mat4 rotate = glm::rotate(identity, glm::radians(dYaw), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||
rotate = glm::rotate(rotate, glm::radians(dPitch), glm::vec3(1.0f, 0.0f, 0.0f));
|
||||
trans = trans * rotate;
|
||||
}
|
||||
|
||||
void Scale(float offset)
|
||||
{
|
||||
if (zoom > 75 || zoom < 1) { return; }
|
||||
zoom -= (float)offset;
|
||||
}
|
||||
|
||||
glm::mat4 GetTrans()
|
||||
{
|
||||
return trans;
|
||||
}
|
||||
|
||||
glm::vec3 GetPos()
|
||||
{
|
||||
glm::vec3 pos(trans[3][0], trans[3][1], trans[3][2]);
|
||||
return pos;
|
||||
}
|
||||
|
||||
private:
|
||||
glm::vec3 position;
|
||||
glm::vec3 rotation;
|
||||
glm::mat4 trans;
|
||||
float pitch;
|
||||
float yaw;
|
||||
float zoom;
|
||||
|
||||
const glm::vec3 front = glm::vec3(0, 0, -1);
|
||||
const glm::vec3 back = glm::vec3(0, 0, 1);
|
||||
const glm::vec3 left = glm::vec3(-1, 0, 0);
|
||||
const glm::vec3 right = glm::vec3(1, 0, 0);
|
||||
const glm::mat4 identity = glm::mat4(1.0f);
|
||||
};
|
||||
|
||||
glm::vec3 lightColor = glm::vec3(1.0, 1.0, 1.0);
|
||||
glm::vec3 lightPosition = glm::vec3(4.0f, 4.0f, -4.0f);
|
||||
|
||||
const glm::mat4 identityGlobal = glm::mat4(1.0f);
|
||||
glm::mat4 origine = identityGlobal;
|
||||
|
||||
int lastMouseX;
|
||||
int lastMouseY;
|
||||
|
||||
float delta = 0.0f;
|
||||
float lastFrame = 0.0f;
|
||||
float currentFrame = 0.0f;
|
||||
|
||||
Model* model;
|
||||
Shader* shader;
|
||||
Camera* camera;
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
||||
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
|
||||
void processInput(GLFWwindow* window);
|
||||
void Initialize();
|
||||
void Render();
|
||||
void Transform();
|
||||
|
||||
int main()
|
||||
{
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "XCRender", NULL, NULL);
|
||||
|
||||
if (window == NULL)
|
||||
{
|
||||
std::cout << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
glfwSetCursorPosCallback(window, mouse_callback);
|
||||
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||
{
|
||||
std::cout << "Failed to initialize GLAD" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Initialize();
|
||||
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
currentFrame = static_cast<float>(glfwGetTime());
|
||||
delta = currentFrame - lastFrame;
|
||||
lastFrame = currentFrame;
|
||||
|
||||
processInput(window);
|
||||
Render();
|
||||
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void processInput(GLFWwindow* window)
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
if (glfwGetMouseButton(window, 1) == GLFW_FALSE)
|
||||
return;
|
||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||
camera->Move(CAMERA_FORWARD, delta);
|
||||
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||
camera->Move(CAMERA_BACKWARD, delta);
|
||||
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||
camera->Move(CAMERA_LEFT, delta);
|
||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||
camera->Move(CAMERA_RIGHT, delta);
|
||||
}
|
||||
|
||||
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
|
||||
{
|
||||
if (glfwGetMouseButton(window, 1) == GLFW_RELEASE)
|
||||
{
|
||||
lastMouseX = (int)xpos;
|
||||
lastMouseY = (int)ypos;
|
||||
return;
|
||||
}
|
||||
|
||||
float xoffset = static_cast<float>(xpos - lastMouseX);
|
||||
float yoffset = static_cast<float>(ypos - lastMouseY);
|
||||
|
||||
lastMouseX = (int)xpos;
|
||||
lastMouseY = (int)ypos;
|
||||
|
||||
camera->Rotate(xoffset, yoffset);
|
||||
}
|
||||
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||
{
|
||||
@@ -722,20 +347,11 @@ void Initialize()
|
||||
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");
|
||||
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");
|
||||
std::cout << "Shader loaded" << std::endl;
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
}
|
||||
|
||||
void Render()
|
||||
@@ -744,7 +360,7 @@ void Render()
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
shader->use();
|
||||
|
||||
|
||||
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));
|
||||
@@ -752,26 +368,52 @@ void Render()
|
||||
shader->setMat4("view", view);
|
||||
shader->setMat4("model", modelMat);
|
||||
shader->setMat4("projection", projection);
|
||||
shader->setVec3("viewPos", glm::vec3(0, 0, 3));
|
||||
|
||||
shader->setVec3("viewPos", 0.0f, 0.0f, 3.0f);
|
||||
shader->setFloat("material.shininess", 32.0f);
|
||||
shader->setVec3("dirLight.direction", 0.0f, -1.0f, 0.0f);
|
||||
shader->setVec3("dirLight.ambient", 0.3f, 0.3f, 0.3f);
|
||||
shader->setVec3("dirLight.diffuse", 0.8f, 0.8f, 0.8f);
|
||||
shader->setVec3("dirLight.specular", 0.5f, 0.5f, 0.5f);
|
||||
shader->setInt("PointLightNum", 0);
|
||||
|
||||
model->Draw(shader);
|
||||
}
|
||||
|
||||
void Transform()
|
||||
int main()
|
||||
{
|
||||
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));
|
||||
glfwInit();
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
|
||||
shader->setMat4("view", view);
|
||||
shader->setMat4("model", modelMat);
|
||||
shader->setMat4("projection", projection);
|
||||
shader->setVec3("viewPos", glm::vec3(0, 0, 3));
|
||||
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "XCRender", NULL, NULL);
|
||||
if (window == NULL)
|
||||
{
|
||||
std::cout << "Failed to create GLFW window" << std::endl;
|
||||
glfwTerminate();
|
||||
return -1;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||
{
|
||||
std::cout << "Failed to initialize GLAD" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
Initialize();
|
||||
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
|
||||
Render();
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user