From 6cc31a24ac1f51da7b12df2c84ba26dd63fe46eb Mon Sep 17 00:00:00 2001 From: izenynn Date: Thu, 20 Feb 2025 14:38:57 +0100 Subject: [PATCH] wip: practica1 --- lib/glew/GL/glew.h | 2 +- .../Debug/Practica3D.tlog/CL.command.1.tlog | Bin 3032 -> 3786 bytes .../x64/Debug/Practica3D.tlog/CL.read.1.tlog | Bin 112940 -> 151758 bytes .../x64/Debug/Practica3D.tlog/CL.write.1.tlog | Bin 5266 -> 6788 bytes .../Debug/Practica3D.tlog/unsuccessfulbuild | 0 project/x64/Debug/ugine3d.log | 12 +- src/buffer.cpp | 31 ++-- src/buffer.h | 4 +- src/main.cpp | 77 +++++---- src/shader.cpp | 147 ++++++++++++++---- src/shader.h | 23 ++- src/vertex.h | 1 + 12 files changed, 216 insertions(+), 81 deletions(-) delete mode 100644 project/x64/Debug/Practica3D.tlog/unsuccessfulbuild diff --git a/lib/glew/GL/glew.h b/lib/glew/GL/glew.h index b5b6987..ade7c8e 100644 --- a/lib/glew/GL/glew.h +++ b/lib/glew/GL/glew.h @@ -210,7 +210,7 @@ typedef _W64 int ptrdiff_t; #else /* _UNIX */ /* - * Needed for ptrdiff_t in turn needed by VBO. This is defined by ISO + * Needed for ptrdiff_t in turn needed by vbo_. This is defined by ISO * C. On my system, this amounts to _3 lines_ of included code, all of * them pretty much harmless. If you know of a way of detecting 32 vs * 64 _targets_ at compile time you are free to replace this with diff --git a/project/x64/Debug/Practica3D.tlog/CL.command.1.tlog b/project/x64/Debug/Practica3D.tlog/CL.command.1.tlog index 651e310516f1b07680f9f1296ebee6908b87cb32..249d67ac298ea0f0c0267a372e683095401ce0d2 100644 GIT binary patch delta 63 zcmca1eoA(O6Z2*pwmGbm?{P#-KEo=p*^je`3CJj5_hoQo@MQ4Y?8sTqBm(6y=rK4m L1OOo~0~Z4Th>j2p delta 30 kcmX>ldqaGK6Z7N)+!CApI3F=hKEn!P6ftc+!z#oK0Jo0{!vFvP diff --git a/project/x64/Debug/Practica3D.tlog/CL.read.1.tlog b/project/x64/Debug/Practica3D.tlog/CL.read.1.tlog index a5383a81d5f849c21e56c593c3723a99504d2f1e..e1f513538f9a7259a104696b06d67edc39985e27 100644 GIT binary patch delta 451 zcma)2O(=r_7=B;-e9X^U`7g1HTpV_i)b!2#Y_eJQSu3Ks5KT_X(h^P%TD{A6CI?At z>y5F{I7reAU$c>S%TR zl)fI%$awqC_m1lPM79@GNOhkg#~ylhWE#HU@KZ!j?tsA0uPH$VVj?tv<#}wn9zrr- ziS%MWqO+Wt?j56C^tB*T>R8~~!>N4Qoowd$Kv2h~?sHVaJ*cIXkTI8JY0Qh1n>eD} z^f|B2Y#}e7q>7cM9o!_z7G--{b-&*Kpv;oYZL?8n6*1noQ1mIDu^%!XQUy^@$P+L8* X7spnlgGD>Jq(UWYL4#I%_$BRPXUoV5mf*H diff --git a/project/x64/Debug/Practica3D.tlog/CL.write.1.tlog b/project/x64/Debug/Practica3D.tlog/CL.write.1.tlog index ea26fe303cf3abf96df7d1729c3260898f489cb5..ea6e4838c7fc329a19094dbc81a45625474e22ef 100644 GIT binary patch delta 127 zcmbQF*#W{MK%YpCNY5+lLJ^ICZA&x*!)ZI8{_74OiWCZ`S|8d=3)xi z81#c_@; C:\Users\rabil\git\utad-programacion3d\project\x64\Debug\Practica3D.exe diff --git a/src/buffer.cpp b/src/buffer.cpp index 7c47d8b..7d51f1c 100644 --- a/src/buffer.cpp +++ b/src/buffer.cpp @@ -9,23 +9,36 @@ Buffer::Buffer(const std::vector& vertices, const std::vector& indices) { - glGenVertexArrays(1, &VAO); - glGenBuffers(1, &VBO); - glGenBuffers(1, &EBO); + index_count_ = indices.size(); - glBindVertexArray(VAO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); + glGenVertexArrays(1, &vao_); + glGenBuffers(1, &vbo_); + glGenBuffers(1, &ebo_); + + glBindVertexArray(vao_); + + glBindBuffer(GL_ARRAY_BUFFER, vbo_); glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(uint16_t), indices.data(), GL_STATIC_DRAW); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)0); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), nullptr); glEnableVertexAttribArray(0); } +Buffer::~Buffer() +{ + glDeleteVertexArrays(1, &vao_); + glDeleteBuffers(1, &vbo_); + glDeleteBuffers(1, &ebo_); +} + void Buffer::Draw(const Shader& shader) const { - glBindVertexArray(VAO); - glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0); + glBindVertexArray(vao_); + glBindBuffer(GL_ARRAY_BUFFER, vbo_); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo_); + shader.SetupAttribs(); + glDrawElements(GL_TRIANGLES, index_count_, GL_UNSIGNED_SHORT, nullptr); } \ No newline at end of file diff --git a/src/buffer.h b/src/buffer.h index 09af19d..972d3c2 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -11,11 +11,13 @@ class Buffer { public: Buffer(const std::vector& vertices, const std::vector& indices); + ~Buffer(); void Draw(const Shader& shader) const; private: - uint32_t VAO, VBO, EBO; + uint32_t vao_, vbo_, ebo_; + GLsizei index_count_; }; #endif // BUFFER_H_ \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index ab954a4..617f07f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,6 @@ -#ifdef _MSC_VER +/*#ifdef _MSC_VER #pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup") -#endif +#endif*/ #include @@ -19,79 +19,96 @@ #define SCREEN_HEIGHT 600 int main() { - // init glfw + // Initialize OpenGL if (!glfwInit()) { std::cerr << "Failed to initialize glfw\n"; return 1; } - // create window - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - //glfwWindowHint(GLFW_RESIZABLE, false); + glfwWindowHint(GLFW_RESIZABLE, false); glfwWindowHint(GLFW_SAMPLES, 8); + + //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); GLFWwindow* win = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "Daniel Poveda", nullptr, nullptr); - if (!win) { + if (win == nullptr) { std::cerr << "Failed to create opengl window\n"; glfwTerminate(); return 1; } glfwMakeContextCurrent(win); + glEnable(GL_DEPTH_TEST); + glEnable(GL_SCISSOR_TEST); + + std::cout << "OpenGL initialized, version: " << glGetString(GL_VERSION) << "\n"; + + // Initialize GLEW glewExperimental = GL_TRUE; - if (glewInit() != GLEW_OK) { - std::cerr << "Failed to initialize GLEW\n"; + GLenum err = glewInit(); + if (err != GLEW_OK) { + std::cerr << "Failed to initialize GLEW: " << glewGetErrorString(err) << "\n"; glfwTerminate(); return 1; } - glEnable(GL_DEPTH_TEST); - Shader shader("data/vertex.glsl", "data/fragment.glsl"); - + // Logic std::vector vertices = { {{-0.5f, -0.5f, 0.0f}}, {{0.5f, -0.5f, 0.0f}}, {{0.0f, 0.5f, 0.0f}} }; std::vector indices = { 0, 1, 2 }; + Buffer buffer(vertices, indices); + Shader shader("data/vertex.glsl", "data/fragment.glsl"); + if (std::strlen(shader.getError()) > 0) { + std::cerr << "Failed to initialize shaders: " << shader.getError() << "\n"; + } glm::mat4 projection = glm::perspective(glm::radians(45.0f), static_cast(SCREEN_WIDTH) / SCREEN_HEIGHT, 0.1f, 100.0f); glm::mat4 view = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, 6)); // main loop - float angle = 0; + double angle = 0; double lastTime = glfwGetTime(); - while ( !glfwWindowShouldClose(win) && !glfwGetKey(win, GLFW_KEY_ESCAPE) ) { - // get delta time - float delta = static_cast(glfwGetTime() - lastTime); + while (!glfwWindowShouldClose(win) && !glfwGetKey(win, GLFW_KEY_ESCAPE)) { + // Delta + double delta_time = glfwGetTime() - lastTime; - // get window size - //int screenWidth, screenHeight; - //glfwGetWindowSize(win, &screenWidth, &screenHeight); + // Reset window + int screenWidth, screenHeight; + glfwGetWindowSize(win, &screenWidth, &screenHeight); + glViewport(0, 0, screenWidth, screenHeight); + + glClearColor(0.3f, 0.3f, 0.3f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + shader.Use(); // Logic - glm::mat4 model = glm::rotate(glm::mat4(1.0f), glm::radians(delta * 32.0f), glm::vec3(0, 1, 0)); + angle += 32.0 * delta_time; + + glm::mat4 model = glm::translate(glm::mat4(1.0), glm::vec3(-3.0f + 0.0f * 3.0f, 0.0f, -0.0f * 3.0f)); + model = glm::rotate(model, glm::radians(static_cast(angle)), glm::vec3(0, 1, 0)); + glm::mat4 mvp = projection * view * model; - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - //glClearColor(0, 255, 0, 255); - shader.use(); - uint32_t mvpLoc = glGetUniformLocation(shader.getId(), "MVP"); - glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, &mvp[0][0]); + Shader::setMat4(shader.getLocation("mvp"), mvp); + buffer.Draw(shader); - // refresh screen + // Refresh screen glfwSwapBuffers(win); glfwPollEvents(); - // Set last time + // Delta lastTime = glfwGetTime(); } - // shutdown + // Shutdown glfwTerminate(); return 0; diff --git a/src/shader.cpp b/src/shader.cpp index 4e49246..a4b07d6 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -3,41 +3,134 @@ #include #include #include +#include #include "../lib/glew/GL/glew.h" #include "../lib/glfw/glfw3.h" -namespace { - std::string readShaderFile(const std::string& filename) { - std::ifstream file(filename); - if (!file) - throw std::runtime_error("Failed to open shader file: " + filename); - std::stringstream buffer; - buffer << file.rdbuf(); - return buffer.str(); - } -} // namespace +#include "vertex.h" Shader::Shader(const std::string& vertexPath, const std::string& fragmentPath) { - std::string vertexCode = readShaderFile(vertexPath); - std::string fragmentCode = readShaderFile(fragmentPath); - const char* vShaderCode = vertexCode.c_str(); - const char* fShaderCode = fragmentCode.c_str(); + const uint32_t vshader = CompileShader(GL_VERTEX_SHADER, vertexPath); + const uint32_t fshader = CompileShader(GL_FRAGMENT_SHADER, fragmentPath); - const uint32_t vertex = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertex, 1, &vShaderCode, NULL); - glCompileShader(vertex); + if (vshader == 0 || fshader == 0) { + program_id_ = 0; + return; + } - const uint32_t fragment = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragment, 1, &fShaderCode, NULL); - glCompileShader(fragment); + program_id_ = glCreateProgram(); + glAttachShader(program_id_, vshader); + glAttachShader(program_id_, fshader); + glLinkProgram(program_id_); - program = glCreateProgram(); - glAttachShader(program, vertex); - glAttachShader(program, fragment); - glLinkProgram(program); + // Error handling + int ret; + glGetProgramiv(program_id_, GL_LINK_STATUS, &ret); + if (ret == GL_FALSE) { + char buffer[1024]; + glGetProgramInfoLog(program_id_, sizeof(buffer), nullptr, buffer); + error_ = buffer; + glDeleteProgram(program_id_); + program_id_ = 0; + } - glDeleteShader(vertex); - glDeleteShader(fragment); -} \ No newline at end of file + glDeleteShader(vshader); + glDeleteShader(fshader); +} + +void Shader::Use() const +{ + if (program_id_ != 0) + glUseProgram(program_id_); +} + +void Shader::SetupAttribs() const +{ + int loc = glGetAttribLocation(program_id_, "vpos"); + if (loc != -1) { + glEnableVertexAttribArray(loc); + glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, position))); + } + + loc = glGetAttribLocation(program_id_, "vcolor"); + if (loc != -1) { + glEnableVertexAttribArray(loc); + glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast(offsetof(Vertex, color))); + } +} + +int Shader::getLocation(const char* key) const +{ + return glGetUniformLocation(program_id_, key); +} + +void Shader::setInt(int loc, int value) +{ + if (loc != -1) + glUniform1i(loc, value); +} + +void Shader::setFloat(int loc, float value) +{ + if (loc != -1) + glUniform1f(loc, value); +} + +void Shader::setVec3(int loc, const glm::vec3& value) +{ + if (loc != -1) + glUniform3fv(loc, 1, &value[0]); +} + +void Shader::setVec4(int loc, const glm::vec4& value) +{ + if (loc != -1) + glUniform4fv(loc, 1, &value[0]); +} + +void Shader::setMat4(int loc, const glm::mat4& value) +{ + if (loc != -1) + glUniformMatrix4fv(loc, 1, GL_FALSE, &value[0][0]); +} + +std::string Shader::ReadShaderFile(const std::string& filename) +{ + std::ifstream file(filename); + if (!file) { + error_ = "Failed to open shader file: " + filename + "\n"; + return std::string{0}; + } + + std::stringstream buffer; + buffer << file.rdbuf(); + return buffer.str(); +} + +uint32_t Shader::CompileShader(uint32_t type, const std::string& source_path) +{ + std::string source = ReadShaderFile(source_path); + if (source.empty()) + return 0; + + const uint32_t shader = glCreateShader(type); + const char* shader_code = source.c_str(); + + glShaderSource(shader, 1, &shader_code, nullptr); + glCompileShader(shader); + + // Error handling + int ret; + glGetShaderiv(shader, GL_COMPILE_STATUS, &ret); + if (ret == GL_FALSE) { + char buffer[1024]; + glGetShaderInfoLog(shader, sizeof(buffer), nullptr, buffer); + error_ = buffer; + glDeleteShader(shader); + return 0; + } + + return shader; +} diff --git a/src/shader.h b/src/shader.h index eb304f4..a0232d0 100644 --- a/src/shader.h +++ b/src/shader.h @@ -9,13 +9,28 @@ class Shader { public: - Shader(const std::string& vertexPath, const std::string& fragmentPath); + Shader(const std::string& vertex_path, const std::string& fragment_path); - void use() const { glUseProgram(program); } - uint32_t getId() const { return program; } + void Use() const; + void SetupAttribs() const; + + uint32_t getId() const { return program_id_; } + const char* getError() const { return error_.c_str(); } + + int getLocation(const char* key) const; + + static void setInt(int loc, int value); + static void setFloat(int loc, float value); + static void setVec3(int loc, const glm::vec3& value); + static void setVec4(int loc, const glm::vec4& value); + static void setMat4(int loc, const glm::mat4& value); private: - uint32_t program; + uint32_t program_id_; + std::string error_; + + std::string ReadShaderFile(const std::string& filename); + uint32_t CompileShader(uint32_t type, const std::string& source_path); }; diff --git a/src/vertex.h b/src/vertex.h index d90c5d8..7ecc077 100644 --- a/src/vertex.h +++ b/src/vertex.h @@ -5,6 +5,7 @@ struct Vertex { glm::vec3 position{ 0.0f, 0.0f, 0.0f }; + glm::vec3 color{ 0.0f, 0.0f, 0.0f }; }; #endif // VERTEX_H_ \ No newline at end of file