当我在 OpenGL 中调整 window 大小时,有没有一种方法可以防止 window 的内容来自 "moving"
Is there a way to prevent the contents of my window from "moving" when i resize the window in OpenGL
我希望我的 window 内容在 window 调整大小时保持居中。 OpenGL(或 GLFW)——我不确定哪个——在水平调整大小时确实能达到预期的效果,但是当我垂直调整 window 大小时,window 似乎显示了立方体底部的更多部分.我希望它能像水平调整大小时那样切断立方体,
这是水平调整大小
这是垂直调整大小
注意:我没有做任何 glViewPort()
否则 window 内容会调整到新的宽度和高度。
有什么办法可以改变这种行为吗?这个问题可能是相关的,但我不认为这能解决我的问题。 How to keep the OpenGL viewport in an SDL window stationary ...
#include <iostream>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GLFW/glfw3.h>
#include "../includes/Shader.h"
#include "../includes/Texture.h"
#include "../includes/glm/glm.hpp"
const int SCR_WIDTH = 800;
const int SCR_HEIGHT = 600;
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
void processInput(GLFWwindow *window);
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, "OpenGL", nullptr, nullptr);
if (window == nullptr) {
std::cout << "Failed to create window! " << std::endl;
glfwTerminate();
return -1;
}
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) {
std::cout << "Failed to initialize GLEW! " << std::endl;
glfwTerminate();
return -1;
}
float vertices[] = {
...
};
unsigned int VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (GLvoid *) nullptr);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (GLvoid *) (sizeof(float) * 3));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Texture texture1("../images/container.jpg");
Texture texture2("../images/awesomeface.png");
Shader shader("../shaders/shader.vs", "../shaders/shader.fs");
shader.use();
shader.setUniform1i("texture1", 0);
shader.setUniform1i("texture2", 1);
while (!glfwWindowShouldClose(window)) {
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
texture1.bind(0);
texture2.bind(1);
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);
model = glm::rotate(model, (float) glfwGetTime(), glm::vec3(1.0f, 0.5f, 0.5f));
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
projection = glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f);
shader.setUniformMat4("model", model);
shader.setUniformMat4("view", view);
shader.setUniformMat4("projection", projection);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
//glViewport(0, 0, width, height);
}
void processInput(GLFWwindow *window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
Note: I do not make any glViewPort() otherwise the window contents would adjust to the new width and height.
这就是问题所在。您需要调整视口。根据视口调整视野:
const float defaultHeight = 600.0f;
const float defaultFov = glm::radians(45.0f);
while (!glfwWindowShouldClose(window)) {
// [...]
int vpSize[2];
glfwGetFramebufferSize(window, &vpSize[0], &vpSize[1]);
glViewport(0, 0, vpSize[0], vpSize[1]);
float aspect = (float)vpSize[0] / (float)vpSize[1];
float fov = asin(sin(defaultFov / 2.0f) * vpSize[1] / defaultHeight) * 2.0f;
glm::mat4 projection = glm::perspective(fov, aspect, 0.1f, 100.0f);
// [...]
}
我希望我的 window 内容在 window 调整大小时保持居中。 OpenGL(或 GLFW)——我不确定哪个——在水平调整大小时确实能达到预期的效果,但是当我垂直调整 window 大小时,window 似乎显示了立方体底部的更多部分.我希望它能像水平调整大小时那样切断立方体,
这是水平调整大小
这是垂直调整大小
注意:我没有做任何 glViewPort()
否则 window 内容会调整到新的宽度和高度。
有什么办法可以改变这种行为吗?这个问题可能是相关的,但我不认为这能解决我的问题。 How to keep the OpenGL viewport in an SDL window stationary ...
#include <iostream>
#include <GL/glew.h>
#include <GL/gl.h>
#include <GLFW/glfw3.h>
#include "../includes/Shader.h"
#include "../includes/Texture.h"
#include "../includes/glm/glm.hpp"
const int SCR_WIDTH = 800;
const int SCR_HEIGHT = 600;
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
void processInput(GLFWwindow *window);
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, "OpenGL", nullptr, nullptr);
if (window == nullptr) {
std::cout << "Failed to create window! " << std::endl;
glfwTerminate();
return -1;
}
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) {
std::cout << "Failed to initialize GLEW! " << std::endl;
glfwTerminate();
return -1;
}
float vertices[] = {
...
};
unsigned int VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (GLvoid *) nullptr);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 5, (GLvoid *) (sizeof(float) * 3));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
Texture texture1("../images/container.jpg");
Texture texture2("../images/awesomeface.png");
Shader shader("../shaders/shader.vs", "../shaders/shader.fs");
shader.use();
shader.setUniform1i("texture1", 0);
shader.setUniform1i("texture2", 1);
while (!glfwWindowShouldClose(window)) {
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
texture1.bind(0);
texture2.bind(1);
glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);
model = glm::rotate(model, (float) glfwGetTime(), glm::vec3(1.0f, 0.5f, 0.5f));
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
projection = glm::perspective(glm::radians(45.0f), 800.0f/600.0f, 0.1f, 100.0f);
shader.setUniformMat4("model", model);
shader.setUniformMat4("view", view);
shader.setUniformMat4("projection", projection);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 36);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
//glViewport(0, 0, width, height);
}
void processInput(GLFWwindow *window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
glfwSetWindowShouldClose(window, true);
}
}
Note: I do not make any glViewPort() otherwise the window contents would adjust to the new width and height.
这就是问题所在。您需要调整视口。根据视口调整视野:
const float defaultHeight = 600.0f;
const float defaultFov = glm::radians(45.0f);
while (!glfwWindowShouldClose(window)) {
// [...]
int vpSize[2];
glfwGetFramebufferSize(window, &vpSize[0], &vpSize[1]);
glViewport(0, 0, vpSize[0], vpSize[1]);
float aspect = (float)vpSize[0] / (float)vpSize[1];
float fov = asin(sin(defaultFov / 2.0f) * vpSize[1] / defaultHeight) * 2.0f;
glm::mat4 projection = glm::perspective(fov, aspect, 0.1f, 100.0f);
// [...]
}