From 1bcfb49b7add714ce6fccca6670671eccdc16273 Mon Sep 17 00:00:00 2001 From: lenn Date: Thu, 5 Feb 2026 16:50:06 +0800 Subject: [PATCH] update --- camera.h | 17 +++++- main.cpp | 162 +++++++++++++++++++++++++++++++++++++++---------------- 2 files changed, 133 insertions(+), 46 deletions(-) diff --git a/camera.h b/camera.h index 80f8815..7f9658d 100644 --- a/camera.h +++ b/camera.h @@ -45,7 +45,7 @@ public: updateCameraVectors(); } - void mouseCallback(float xoffset, float yoffset, GLboolean constrainPitch = true) { + void mouseMoveCallback(float xoffset, float yoffset, GLboolean constrainPitch = true) { xoffset *= mouseSensitivity_; yoffset *= mouseSensitivity_; @@ -63,10 +63,25 @@ public: updateCameraVectors(); } + void mouseScrollCallback(float yoffset) { + zoom_ -= yoffset; + if (zoom_ < 1.0f) { + zoom_ = 1.0; + } + if (zoom_ > 45.0f) { + zoom_ = 45.0; + } + updateCameraVectors(); + } + glm::mat4 getViewMatrix() { return glm::lookAt(position_, position_ + front_, up_); } + bool firstMouse() const { return firstMouse_; } + + void triggleFirstMouse() { firstMouse_ = !firstMouse_; } + private: void updateCameraVectors() { glm::vec3 front; diff --git a/main.cpp b/main.cpp index 113061d..b46dcf5 100644 --- a/main.cpp +++ b/main.cpp @@ -21,16 +21,29 @@ public: window_(nullptr, [](GLFWwindow* w){if(w) glfwDestroyWindow(w);}) { lastX_ = port.width / 2; lastY_ = port.height / 2; + initGeometry(); + } + ~GLWidget() { + if (bgVao_) { + glDeleteVertexArrays(1, &bgVao_); + } + if (bgVbo_) { + glDeleteBuffers(1, &bgVbo_); + } } - ~GLWidget() {} - void setViewPort(int width, int height) { viewport_ = {width, height}; } bool initGeometry() { - // window_ = std::make_unique(glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL)); + glfwInit(); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); +#if __APPLE__ + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); +#endif window_.reset(glfwCreateWindow(800, 600, "3dviewer", nullptr, nullptr)); if (!window_) { std::cout << "Failed to create GLFW window" << std::endl; @@ -44,31 +57,30 @@ public: } glViewport(0, 0, 800, 600); - glfwSetFramebufferSizeCallback(window_.get(), &GLWidget::framebuffer_size_callback); + glfwSetWindowUserPointer(window_.get(), this); + glfwSetFramebufferSizeCallback(window_.get(), &GLWidget::framebufferSizeCallback); + glfwSetCursorPosCallback(window_.get(), &GLWidget::mouseCallback); } -public: - bool initBgProgram(const std::string& vpath, const std::string fpath) { - auto vshader = std::make_unique(LOpenGLShader::ShaderType::Vertex); - auto fshader = std::make_unique(LOpenGLShader::ShaderType::Fragment); - vshader->compileShaderFromFile(vpath); - fshader->compileShaderFromFile(fpath); - bgProg_ = std::make_unique(); - bgProg_->addShader(std::move(vshader)); - bgProg_->addShader(std::move(fshader)); - bool ret = bgProg_->Link(); - if (!ret) { - return false; + + void setBgShaderPath(std::string vp, std::string fp) { + bgVertShaderPath_ = vp; + bgFragShaderPath_ = fp; + } +private: + void initBgGeometry() { + if (bgVbo_) { + glDeleteBuffers(1, &bgVbo_); + bgVbo_ = 0; } + if (bgVao_) { + glDeleteVertexArrays(1, &bgVao_); + bgVao_ = 0; + } + const float verts[] = { -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, }; - if (bgVao_) { - glDeleteVertexArrays(1, &bgVao_); - } - if (bgVbo_) { - glDeleteBuffers(1, &bgVbo_); - } glGenVertexArrays(1, &bgVao_); glBindVertexArray(bgVao_); @@ -83,7 +95,27 @@ public: } + bool initBgProgram() { + auto vshader = std::make_unique(LOpenGLShader::ShaderType::Vertex); + auto fshader = std::make_unique(LOpenGLShader::ShaderType::Fragment); + vshader->compileShaderFromFile(bgVertShaderPath_); + fshader->compileShaderFromFile(bgFragShaderPath_); + bgProg_ = std::make_unique(); + bgProg_->addShader(std::move(vshader)); + bgProg_->addShader(std::move(fshader)); + bool ret = bgProg_->Link(); + if (!ret) { + return false; + } + + return true; + } + void drawBg() { + if (!bgProg_ || !bgVao_ || !bgVbo_) { + std::cout << "check !bgProg_ || !bgVao_ || !bgVbo_ failed\n"; + return; + } bgProg_->Use(); bgProg_->setUniformValue("uViewport", glm::vec2(viewport_.width, viewport_.height)); bgProg_->setUniformValue("uMajorStep", 120.0f); @@ -96,28 +128,80 @@ public: glEnable(GL_DEPTH_TEST); } - void mouseCallback(GLFWwindow* window, double x, double y) { - float xpos = static_cast(x); - float ypos = static_cast(y); - - if (camera_.fir) { +public: + void eventLoop() { + initBgGeometry(); + initBgProgram(); + while (!glfwWindowShouldClose(window_.get())) { + processInput(window_.get()); + drawBg(); } } private: - void framebuffer_size_callback(GLFWwindow* window, int width, int height) { - glViewport(0, 0, viewport_.width, viewport_.height); + static void framebufferSizeCallback(GLFWwindow* window, int width, int height) { + auto* self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) { + return; + } + self->onFramebufferSize(width, height); } - void process_input(GLFWwindow* window) { + void onFramebufferSize(int width, int height) { + glViewport(0, 0, width, height); + } + + void processInput(GLFWwindow* window) { if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) { glfwSetWindowShouldClose(window, true); } } + + static void mouseCallback(GLFWwindow* window, double x, double y) { + auto* self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) { + return; + } + self->onMouseMove(x, y); + } + + void onMouseMove(double x, double y) { + float xpos = static_cast(x); + float ypos = static_cast(y); + + if (camera_.firstMouse()) { + lastX_ = x; + lastY_ = y; + camera_.triggleFirstMouse(); + } + + float xoffset = xpos - lastX_; + float yoffset = lastY_ - ypos; + + lastX_ = xpos; + lastY_ = ypos; + + camera_.mouseMoveCallback(xoffset, yoffset); + } + + static void scrollCallback(GLFWwindow* window, double xoffset, double yoffset) { + auto* self = static_cast(glfwGetWindowUserPointer(window)); + if (!self) { + return; + } + self->onScrollRoll(xoffset, yoffset); + } + + void onScrollRoll(double xoffset, double yoffset) { + camera_.mouseScrollCallback(yoffset); + } + private: std::unique_ptr bgProg_; std::unique_ptr> window_; + std::string bgFragShaderPath_; + std::string bgVertShaderPath_; unsigned int bgVao_; unsigned int bgVbo_; ViewPort viewport_{800, 600}; @@ -129,23 +213,11 @@ private: }; int main() { - glfwInit(); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); -#if __APPLE__ - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); -#endif - + GLWidget glw({600, 800}); + glw.setBgShaderPath("bg.vert", "bg.frag"); - GLWidget glw; - glw.initBgProgram("bg.vert", "bg.frag"); - - while (!glfwWindowShouldClose(window)) { - - glw.drawBg(); - } + glw.eventLoop(); glfwTerminate(); return 0;