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 651e310..249d67a 100644 Binary files a/project/x64/Debug/Practica3D.tlog/CL.command.1.tlog and b/project/x64/Debug/Practica3D.tlog/CL.command.1.tlog differ diff --git a/project/x64/Debug/Practica3D.tlog/CL.read.1.tlog b/project/x64/Debug/Practica3D.tlog/CL.read.1.tlog index a5383a8..e1f5135 100644 Binary files a/project/x64/Debug/Practica3D.tlog/CL.read.1.tlog and b/project/x64/Debug/Practica3D.tlog/CL.read.1.tlog differ diff --git a/project/x64/Debug/Practica3D.tlog/CL.write.1.tlog b/project/x64/Debug/Practica3D.tlog/CL.write.1.tlog index ea26fe3..ea6e483 100644 Binary files a/project/x64/Debug/Practica3D.tlog/CL.write.1.tlog and b/project/x64/Debug/Practica3D.tlog/CL.write.1.tlog differ diff --git a/project/x64/Debug/Practica3D.tlog/unsuccessfulbuild b/project/x64/Debug/Practica3D.tlog/unsuccessfulbuild deleted file mode 100644 index e69de29..0000000 diff --git a/project/x64/Debug/ugine3d.log b/project/x64/Debug/ugine3d.log index 7de5d45..8281ef2 100644 --- a/project/x64/Debug/ugine3d.log +++ b/project/x64/Debug/ugine3d.log @@ -1,9 +1,3 @@ - buffer.cpp - main.cpp - Generating Code... -C:\Users\rabil\git\utad-programacion3d\src\main.cpp(84,9): error C2660: 'Buffer::Draw': function does not take 0 arguments - C:\Users\rabil\git\utad-programacion3d\src\buffer.h(15,7): - see declaration of 'Buffer::Draw' - C:\Users\rabil\git\utad-programacion3d\src\main.cpp(84,9): - while trying to match the argument list '()' - + main.cpp +LINK : warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library + ugine3d.vcxproj -> 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