Draws cubes instead of triangles now
This commit is contained in:
1 parent
2067d5c18c
commit
45e2a5f4cc
441 files changed
+67481
-78
No files matched your search
+100
@@ -0,0 +1,100 @@
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
const float CAMERA_HEIGHT = 1.7f;
|
||||
const float GRAVITY = 18.6f; // Should be in m/s^2 but it doesn't really work out with 9.8 so we double it
|
||||
|
||||
class Camera
|
||||
{
|
||||
public:
|
||||
glm::vec3 position;
|
||||
glm::vec3 target;
|
||||
glm::vec3 direction;
|
||||
glm::vec3 up;
|
||||
|
||||
// Movement
|
||||
glm::vec3 horizontal_velocity;
|
||||
glm::vec3 forward_velocity;
|
||||
glm::vec3 vertical_velocity;
|
||||
|
||||
float speed;
|
||||
|
||||
glm::vec3 worldUp;
|
||||
|
||||
Camera(float speed, glm::vec3 pos)
|
||||
{
|
||||
this->speed = speed;
|
||||
this->vertical_velocity = glm::vec3(0.0f);
|
||||
|
||||
this->horizontal_velocity = glm::vec3(0.0f);
|
||||
this->forward_velocity = glm::vec3(0.0f);
|
||||
|
||||
this->position = pos;
|
||||
this->target = glm::vec3(0.0f, 0.0f, -1.0f);
|
||||
|
||||
this->direction = glm::normalize(this->position);
|
||||
this->worldUp = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
|
||||
glm::vec3 right = glm::normalize(glm::cross(up, this->direction));
|
||||
this->up = glm::cross(this->direction, right);
|
||||
}
|
||||
|
||||
Camera(glm::vec3 pos, glm::vec3 target, float speed)
|
||||
{
|
||||
this->speed = speed;
|
||||
this->vertical_velocity = glm::vec3(0.0f);
|
||||
|
||||
this->horizontal_velocity = glm::vec3(0.0f);
|
||||
this->forward_velocity = glm::vec3(0.0f);
|
||||
|
||||
this->position = pos;
|
||||
this->target = target;
|
||||
|
||||
this->direction = glm::normalize(this->position - this->target);
|
||||
this->worldUp = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
|
||||
glm::vec3 right = glm::normalize(glm::cross(up, this->direction));
|
||||
this->up = glm::cross(this->direction, right);
|
||||
}
|
||||
|
||||
glm::mat4 getView()
|
||||
{
|
||||
glm::mat4 v = glm::lookAt(this->position,
|
||||
this->target + this->position,
|
||||
this->worldUp);
|
||||
|
||||
v = glm::translate(v, glm::vec3(0.0f, -CAMERA_HEIGHT, 0.0f));
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
void move(float time) // time passed in seconds since last move
|
||||
{
|
||||
bool in_air = this->position.y > 0;
|
||||
|
||||
if (this->position.y > 0)
|
||||
this->vertical_velocity.y -= (GRAVITY * time); // no way! physics reference?
|
||||
|
||||
glm::vec3 velocity = this->forward_velocity + this->horizontal_velocity + this->vertical_velocity;
|
||||
|
||||
glm::vec3 movement = (velocity * time);
|
||||
this->position += movement;
|
||||
|
||||
// Don't want to clip into the ground right
|
||||
if (this->position.y <= 0 && in_air)
|
||||
{
|
||||
this->position.y = 0.0f;
|
||||
this->vertical_velocity.y = 0.0f;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
#include "Object3D.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <strstream>
|
||||
|
||||
Object3D::Object3D() = default;
|
||||
|
||||
Object3D::Object3D(const std::string &file_path)
|
||||
{
|
||||
this->loadFromOBJ(file_path);
|
||||
}
|
||||
|
||||
bool Object3D::loadFromOBJ(const std::string& file_path)
|
||||
{
|
||||
std::ifstream f(file_path);
|
||||
if (!f.is_open())
|
||||
return false;
|
||||
|
||||
std::vector<float> temp_vertices;
|
||||
std::vector<unsigned int> temp_indices;
|
||||
std::vector<float> temp_normals;
|
||||
|
||||
while (!f.eof())
|
||||
{
|
||||
char line[128];
|
||||
f.getline(line, 128);
|
||||
|
||||
std::string l(line);
|
||||
|
||||
// std::cout << "LINE: " << l << std::endl;
|
||||
|
||||
if (line[0] == 'f')
|
||||
{
|
||||
l.erase(0, 2); // Erase the "f "
|
||||
size_t pos1 = 0;
|
||||
std::string token1;
|
||||
|
||||
// Split by space
|
||||
while ((pos1 = l.find(' ')) != std::string::npos)
|
||||
{
|
||||
token1 = l.substr(0, pos1);
|
||||
int face_vert;
|
||||
|
||||
if (l.find("//") != std::string::npos)
|
||||
{
|
||||
size_t pos2 = 0;
|
||||
std::string token2;
|
||||
bool face = true;
|
||||
|
||||
while ((pos2 = token1.find("//")) != std::string::npos)
|
||||
{
|
||||
token2 = token1.substr(0, pos2);
|
||||
// std::cout << token1 << std::endl;
|
||||
|
||||
if (face)
|
||||
{
|
||||
face_vert = std::stoi(token2) - 1;
|
||||
temp_indices.push_back(face_vert);
|
||||
face = false;
|
||||
|
||||
}
|
||||
|
||||
token1.erase(0, pos2 + 2);
|
||||
}
|
||||
|
||||
// The Normal paired with the face is here
|
||||
if (!face) {
|
||||
// std::cout << "thisg" << std::endl;
|
||||
int face_normal = std::stoi(token1) - 1;
|
||||
// std::cout << "f " << face_vert + 1 << "//" << face_normal + 1 << std::endl;
|
||||
|
||||
bool VBO_el_found = false;
|
||||
|
||||
// If Vertice AND correct normal are already in VBO buffer just refernce that
|
||||
for (unsigned int i = 0; i < this->VBO_buffer.size(); i += 6)
|
||||
{
|
||||
bool vert_equal = true;
|
||||
bool normal_equal = true;
|
||||
|
||||
// Since each Vertice & Normal are 3 elements we need to do a little looping
|
||||
for (int a = 0; a < 3; a++)
|
||||
{
|
||||
if (this->VBO_buffer[i + a] != temp_vertices[(face_vert * 3) + a]) {
|
||||
vert_equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 3; a < 6; a++)
|
||||
{
|
||||
if (this->VBO_buffer[i + a] != temp_normals[(face_normal * 3) + a - 3]) {
|
||||
normal_equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vert_equal && normal_equal) {
|
||||
this->EBO_buffer.push_back(i / 6);
|
||||
VBO_el_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If not we need to add it to the VBO buffer
|
||||
if (!VBO_el_found)
|
||||
{
|
||||
// Again we need to add all three elements for each
|
||||
for (int a = 0; a < 3; a++)
|
||||
this->VBO_buffer.push_back(temp_vertices[face_vert * 3 + a]);
|
||||
|
||||
|
||||
for (int a = 0; a < 3; a++)
|
||||
this->VBO_buffer.push_back(temp_normals[face_normal * 3 + a]);
|
||||
|
||||
this->EBO_buffer.push_back(this->VBO_buffer.size() / 6 - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// std::cout << l << std::endl;
|
||||
|
||||
// temp_indices.push_back(std::stoi(token1) - 1);
|
||||
|
||||
}
|
||||
|
||||
l.erase(0, pos1 + 1);
|
||||
}
|
||||
|
||||
// std::cout << "thing" << std::endl;
|
||||
// std::cout << l << std::endl;
|
||||
|
||||
if (l.find("//") != std::string::npos)
|
||||
{
|
||||
size_t pos2 = 0;
|
||||
std::string token2;
|
||||
bool face = true;
|
||||
int face_vert;
|
||||
|
||||
while ((pos2 = l.find("//")) != std::string::npos)
|
||||
{
|
||||
token2 = l.substr(0, pos2);
|
||||
face_vert = std::stoi(token2) - 1;
|
||||
|
||||
|
||||
if (face)
|
||||
{
|
||||
temp_indices.push_back(face_vert);
|
||||
face = false;
|
||||
}
|
||||
// Else case if I want to add normals for the faces
|
||||
|
||||
l.erase(0, pos2 + 2);
|
||||
}
|
||||
|
||||
// The Normal paired with the face is here
|
||||
if (!face) {
|
||||
// std::cout << "thisg" << std::endl;
|
||||
int face_normal = std::stoi(l) - 1;
|
||||
// std::cout << "f " << face_vert + 1 << "//" << face_normal + 1 << std::endl;
|
||||
|
||||
bool VBO_el_found = false;
|
||||
|
||||
// If Vertice AND correct normal are already in VBO buffer just refernce that
|
||||
for (unsigned int i = 0; i < this->VBO_buffer.size(); i += 6)
|
||||
{
|
||||
bool vert_equal = true;
|
||||
bool normal_equal = true;
|
||||
|
||||
// Since each Vertice & Normal are 3 elements we need to do a little looping
|
||||
for (int a = 0; a < 3; a++)
|
||||
{
|
||||
if (this->VBO_buffer[i + a] != temp_vertices[(face_vert * 3) + a]) {
|
||||
vert_equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 3; a < 6; a++)
|
||||
{
|
||||
if (this->VBO_buffer[i + a] != temp_normals[(face_normal * 3) + a - 3]) {
|
||||
normal_equal = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (vert_equal && normal_equal) {
|
||||
this->EBO_buffer.push_back(i / 6);
|
||||
VBO_el_found = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If not we need to add it to the VBO buffer
|
||||
if (!VBO_el_found)
|
||||
{
|
||||
// Again we need to add all three elements for each
|
||||
for (int a = 0; a < 3; a++)
|
||||
this->VBO_buffer.push_back(temp_vertices[face_vert * 3 + a]);
|
||||
|
||||
|
||||
for (int a = 0; a < 3; a++)
|
||||
this->VBO_buffer.push_back(temp_normals[face_normal * 3 + a]);
|
||||
|
||||
this->EBO_buffer.push_back(this->VBO_buffer.size() / 6 - 1);
|
||||
}
|
||||
}
|
||||
|
||||
// std::cout << l << std::endl;
|
||||
|
||||
// temp_indices.push_back(std::stoi(token1) - 1);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else if (line[0] == 'v')
|
||||
{
|
||||
|
||||
|
||||
size_t pos1 = 0;
|
||||
std::string token1;
|
||||
bool normal = line[1] == 'n';
|
||||
|
||||
if (normal)
|
||||
{
|
||||
l.erase(0, 3); // Get rid of the "vn "
|
||||
}
|
||||
else
|
||||
{
|
||||
l.erase(0, 2); // Get rid of the "v "
|
||||
}
|
||||
|
||||
|
||||
// Split by space
|
||||
while ((pos1 = l.find(' ')) != std::string::npos)
|
||||
{
|
||||
token1 = l.substr(0, pos1);
|
||||
|
||||
if (normal)
|
||||
{
|
||||
temp_normals.push_back(std::stof(token1));
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_vertices.push_back(std::stof(token1));
|
||||
}
|
||||
|
||||
|
||||
l.erase(0, pos1 + 1);
|
||||
}
|
||||
|
||||
// Last point is still left after the loop
|
||||
if (normal)
|
||||
{
|
||||
temp_normals.push_back(std::stof(l));
|
||||
}
|
||||
else
|
||||
{
|
||||
temp_vertices.push_back(std::stof(l));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->vertices = temp_vertices;
|
||||
this->indices = temp_indices;
|
||||
this->normals = temp_normals;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<float> Object3D::getVBOBuffer()
|
||||
{
|
||||
std::vector<float> temp_VBO_buffer;
|
||||
|
||||
for (int i = 0; i < this->vertices.size() / 3; i++)
|
||||
{
|
||||
for (int a = 0; a < 3; a++)
|
||||
temp_VBO_buffer.push_back(this->vertices[(i * 3) + a]);
|
||||
for (int a = 0; a < 3; a++)
|
||||
temp_VBO_buffer.push_back(this->normals[(i * 3) + a]);
|
||||
}
|
||||
|
||||
return temp_VBO_buffer;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef OBJECT3D_H
|
||||
#define OBJECT3D_H
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
||||
class Object3D {
|
||||
public:
|
||||
std::vector<float> vertices;
|
||||
std::vector<unsigned int> indices;
|
||||
std::vector<float> normals;
|
||||
|
||||
std::vector<unsigned int> EBO_buffer;
|
||||
std::vector<float> VBO_buffer;
|
||||
|
||||
Object3D();
|
||||
Object3D(const std::string &file_path);
|
||||
|
||||
bool loadFromOBJ(const std::string& file_path);
|
||||
std::vector<float> getVBOBuffer();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //OBJECT3D_H
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
#ifndef SHADER_H
|
||||
#define SHADER_H
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
class Shader
|
||||
{
|
||||
public:
|
||||
unsigned int ID;
|
||||
// constructor generates the shader on the fly
|
||||
// ------------------------------------------------------------------------
|
||||
Shader(const std::string &vertexPath, const std::string &fragmentPath)
|
||||
{
|
||||
// 1. retrieve the vertex/fragment source code from filePath
|
||||
std::string vertexCode;
|
||||
std::string fragmentCode;
|
||||
std::ifstream vShaderFile;
|
||||
std::ifstream fShaderFile;
|
||||
// ensure ifstream objects can throw exceptions:
|
||||
// vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||
// fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
|
||||
try
|
||||
{
|
||||
// open files
|
||||
|
||||
vShaderFile.open(vertexPath);
|
||||
|
||||
if (!vShaderFile.is_open())
|
||||
std::cout << "ERROR:SHADER::VERTEX::FILE_NOT_READ" << std::endl;
|
||||
|
||||
fShaderFile.open(fragmentPath);
|
||||
|
||||
if (!fShaderFile.is_open())
|
||||
std::cout << "ERROR:SHADER::FRAGMENT::FILE_NOT_READ" << std::endl;
|
||||
|
||||
|
||||
|
||||
std::stringstream vShaderStream, fShaderStream;
|
||||
// read file's buffer contents into streams
|
||||
vShaderStream << vShaderFile.rdbuf();
|
||||
fShaderStream << fShaderFile.rdbuf();
|
||||
// close file handlers
|
||||
vShaderFile.close();
|
||||
fShaderFile.close();
|
||||
// convert stream into string
|
||||
vertexCode = vShaderStream.str();
|
||||
fragmentCode = fShaderStream.str();
|
||||
}
|
||||
catch (std::ifstream::failure& e)
|
||||
{
|
||||
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
std::cout << fragmentCode << std::endl;
|
||||
|
||||
const char* vShaderCode = vertexCode.c_str();
|
||||
const char * fShaderCode = fragmentCode.c_str();
|
||||
// 2. compile shaders
|
||||
unsigned int vertex, fragment;
|
||||
// vertex shader
|
||||
vertex = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex, 1, &vShaderCode, NULL);
|
||||
glCompileShader(vertex);
|
||||
checkCompileErrors(vertex, "VERTEX");
|
||||
// fragment Shader
|
||||
fragment = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment, 1, &fShaderCode, NULL);
|
||||
glCompileShader(fragment);
|
||||
checkCompileErrors(fragment, "FRAGMENT");
|
||||
// shader Program
|
||||
ID = glCreateProgram();
|
||||
glAttachShader(ID, vertex);
|
||||
glAttachShader(ID, fragment);
|
||||
glLinkProgram(ID);
|
||||
checkCompileErrors(ID, "PROGRAM");
|
||||
// delete the shaders as they're linked into our program now and no longer necessary
|
||||
glDeleteShader(vertex);
|
||||
glDeleteShader(fragment);
|
||||
}
|
||||
// activate the shader
|
||||
// ------------------------------------------------------------------------
|
||||
void use()
|
||||
{
|
||||
glUseProgram(ID);
|
||||
}
|
||||
// utility uniform functions
|
||||
// ------------------------------------------------------------------------
|
||||
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);
|
||||
}
|
||||
// ------------------------------------------------------------------------
|
||||
void setFloat(const std::string &name, float value) const
|
||||
{
|
||||
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]);
|
||||
}
|
||||
void setVec3(const std::string &name, float x, float y, float z) const
|
||||
{
|
||||
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) const
|
||||
{
|
||||
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]);
|
||||
}
|
||||
|
||||
private:
|
||||
// utility function for checking shader compilation/linking errors.
|
||||
// ------------------------------------------------------------------------
|
||||
void checkCompileErrors(unsigned int shader, std::string type)
|
||||
{
|
||||
int success;
|
||||
char infoLog[1024];
|
||||
if (type != "PROGRAM")
|
||||
{
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success)
|
||||
{
|
||||
glGetShaderInfoLog(shader, 1024, NULL, infoLog);
|
||||
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glGetProgramiv(shader, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
+50
-77
@@ -2,30 +2,27 @@
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <iostream>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include "Shader.h"
|
||||
#include "Camera.h"
|
||||
#include "Object3D.h"
|
||||
|
||||
// Window dimensions
|
||||
const unsigned int SCR_WIDTH = 800;
|
||||
const unsigned int SCR_HEIGHT = 600;
|
||||
|
||||
// Shaders (in GLSL - OpenGL Shading Language)
|
||||
// Vertex Shader: Positions the vertices
|
||||
const char *vertexShaderSource = R"glsl(
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
|
||||
}
|
||||
)glsl";
|
||||
const float CAMERA_SPEED = 1.0f;
|
||||
const float MAX_CAMERA_SPEED = 2.0f;
|
||||
const float LOOK_SENSITIVITY = 0.1f;
|
||||
|
||||
// Fragment Shader: Colors the pixels (fragments)
|
||||
const char *fragmentShaderSource = R"glsl(
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f); // An orange color
|
||||
}
|
||||
)glsl";
|
||||
const float Z_FAR = 1000.0f;
|
||||
const float Z_NEAR = 0.1f;
|
||||
bool WIREFRAME_MODE = true;
|
||||
const float FOV = 90.0f;
|
||||
|
||||
glm::mat4 projection = glm::mat4(1.0f);
|
||||
Camera camera = Camera(CAMERA_SPEED, glm::vec3(0.0f, 0.0f, 3.0f));
|
||||
|
||||
// Callback function for when the window is resized
|
||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
|
||||
@@ -41,9 +38,6 @@ int main() {
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
#ifdef __APPLE__
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // For macOS
|
||||
#endif
|
||||
|
||||
// 2. --- Create a Window ---
|
||||
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "HelloTriangle", NULL, NULL);
|
||||
@@ -61,86 +55,66 @@ int main() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 4. --- Compile Shaders ---
|
||||
|
||||
// Vertex Shader
|
||||
unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
|
||||
glCompileShader(vertexShader);
|
||||
// Check for compilation errors
|
||||
int success;
|
||||
char infoLog[512];
|
||||
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
|
||||
std::cerr << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||
}
|
||||
|
||||
// Fragment Shader
|
||||
unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
|
||||
glCompileShader(fragmentShader);
|
||||
// Check for compilation errors
|
||||
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
|
||||
std::cerr << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
|
||||
}
|
||||
|
||||
// Link shaders into a Shader Program
|
||||
unsigned int shaderProgram = glCreateProgram();
|
||||
glAttachShader(shaderProgram, vertexShader);
|
||||
glAttachShader(shaderProgram, fragmentShader);
|
||||
glLinkProgram(shaderProgram);
|
||||
// Check for linking errors
|
||||
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
|
||||
if (!success) {
|
||||
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
|
||||
std::cerr << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
|
||||
}
|
||||
glDeleteShader(vertexShader); // Shaders are linked, we can delete them
|
||||
glDeleteShader(fragmentShader);
|
||||
// 4. Shader Setup
|
||||
Shader shader("shaders/cube_vert.glsl", "shaders/cube_frag.glsl");
|
||||
|
||||
// 5. --- Set up Vertex Data and Buffers ---
|
||||
// A triangle has 3 vertices, each with 3 coordinates (x, y, z)
|
||||
float vertices[] = {
|
||||
-0.5f, -0.5f, 0.0f, // left
|
||||
0.5f, -0.5f, 0.0f, // right
|
||||
0.0f, 0.5f, 0.0f // top
|
||||
};
|
||||
|
||||
unsigned int VBO, VAO;
|
||||
// Load Cube OBJ
|
||||
Object3D cube = Object3D("objs/cube.obj");
|
||||
|
||||
unsigned int VBO, VAO, EBO;
|
||||
glGenVertexArrays(1, &VAO); // 1. Create Vertex Array Object (VAO)
|
||||
glGenBuffers(1, &VBO); // 2. Create Vertex Buffer Object (VBO)
|
||||
glGenBuffers(1, &EBO);
|
||||
|
||||
glBindVertexArray(VAO); // 3. Bind the VAO
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, VBO); // 4. Bind the VBO
|
||||
// 5. Copy vertex data into VBO's memory
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||
glBufferData(GL_ARRAY_BUFFER, cube.VBO_buffer.size() * sizeof(float), &cube.VBO_buffer.front(), GL_STATIC_DRAW);
|
||||
|
||||
// 6. Tell OpenGL how to interpret the vertex data
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
|
||||
|
||||
// Position Attribute
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_TRUE, 6 * sizeof(float), (void*)0);
|
||||
glEnableVertexAttribArray(0); // Enable the vertex attribute (location 0)
|
||||
|
||||
// Normal Attribute
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||
glEnableVertexAttribArray(1);
|
||||
|
||||
// 6.5 Setup EBO
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, cube.EBO_buffer.size() * sizeof(unsigned int), &cube.EBO_buffer.front(), GL_STATIC_DRAW);
|
||||
|
||||
// Unbind VBO and VAO (optional, but good practice)
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
if (WIREFRAME_MODE)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
// Setup projection matrix
|
||||
projection = glm::perspective(glm::radians(FOV), (float)SCR_WIDTH / (float)SCR_HEIGHT, Z_NEAR, Z_FAR); // This doesn't need to be recalculated every frame
|
||||
|
||||
glm::mat4 view = camera.getView();
|
||||
|
||||
// 6. --- The Render Loop ---
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
// Input (e.g., close window on ESC)
|
||||
// processInput(window);
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||
glfwSetWindowShouldClose(window, true);
|
||||
|
||||
// Rendering
|
||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f); // Set background color
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Clear screen
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Z-Buffer
|
||||
|
||||
// Draw the triangle
|
||||
glUseProgram(shaderProgram); // Use our shader program
|
||||
glBindVertexArray(VAO); // Bind the VAO (our triangle's "recipe")
|
||||
glDrawArrays(GL_TRIANGLES, 0, 3); // Draw it!
|
||||
shader.use();
|
||||
shader.setMat4("u_mvp", projection * view);
|
||||
glBindVertexArray(VAO); // Bind the VAO (our triangle's "recipe")
|
||||
glDrawElements(GL_TRIANGLES, cube.EBO_buffer.size(), GL_UNSIGNED_INT, nullptr); // Draw it!
|
||||
|
||||
// Swap buffers and poll for events
|
||||
glfwSwapBuffers(window);
|
||||
@@ -150,7 +124,6 @@ int main() {
|
||||
// 7. --- Cleanup ---
|
||||
glDeleteVertexArrays(1, &VAO);
|
||||
glDeleteBuffers(1, &VBO);
|
||||
glDeleteProgram(shaderProgram);
|
||||
|
||||
glfwTerminate(); // Clean up GLFW
|
||||
return 0;
|
||||
|
||||
Reference in new issue
Block a user