我有一个 600x400 的窗口,OpenGL 渲染的视口似乎要小得多(如下图所示)。
我期待的视口和我得到的视口的图片,请注意大部分正方形都被剪掉了。
下面的代码能够重现我所看到的。此代码也与 learnopengl.com 在其“实践”部分中显示的精灵渲染器几乎完全相同。
main.cpp
#include <iostream>
#include <fstream>
#include <sstream>
#include <GLFW/glfw3.h>
#include <glad/glad.h>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
int main() {
if (glfwInit()) { // initialise GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
} else {
std::cout << "glfw failed to initialise" << std::endl;
}
GLFWwindow *window = glfwCreateWindow(600, 400, "window", NULL, NULL); // creates window of 600x400
if (window == NULL) {
std::cout << "Window creation failed" << std::endl;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { // load glad
std::cout << "Failed to initialise glad" << std::endl;
}
glViewport(0, 0, 600, 400); // set viewport to 600x400 with (0,0) on the lower left corner
// initialise the rendering objects
unsigned int VAO, VBO;
float vertices[] = {
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f, 0.0f
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void *)0);
// Unbind the VAO and VBO
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// load the vertex and fragment shdaer
unsigned int shaderID;
std::string vertexCode;
std::string fragmentCode;
std::ifstream vertexShaderFile;
std::ifstream fragmentShaderFile;
vertexShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fragmentShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
vertexShaderFile.open(".../SpriteShader.vs");
fragmentShaderFile.open(".../SpriteShader.fs");
std::stringstream vertexShaderStream, fragmentShaderStream;
vertexShaderStream << vertexShaderFile.rdbuf();
fragmentShaderStream << fragmentShaderFile.rdbuf();
vertexShaderFile.close();
fragmentShaderFile.close();
vertexCode = vertexShaderStream.str();
fragmentCode = fragmentShaderStream.str();
} catch (std::ifstream::failure e) {
std::cout << "Shader file could not be successfully read " << e.what() << std::endl;
}
const char *vertexShaderCode = vertexCode.c_str();
const char *fragmentShaderCode = fragmentCode.c_str();
unsigned int vertexShader, fragmentShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderCode, NULL);
glCompileShader(vertexShader);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderCode, NULL);
glCompileShader(fragmentShader);
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "Vertex Shader could not be compiled " << infoLog << std::endl;
}
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "Fragment Shader could not be compiled " << infoLog
<< std::endl;
}
shaderID = glCreateProgram();
glAttachShader(shaderID, vertexShader);
glAttachShader(shaderID, fragmentShader);
glLinkProgram(shaderID);
glGetProgramiv(shaderID, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderID, 512, NULL, infoLog);
std::cout << "Could not link program " << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderID);
glm::mat4 model = glm::mat4(1.0f);
model = glm::translate(model, glm::vec3(580.0f, 380.0f, 0.0f));
model = glm::scale(model, glm::vec3(50.0f, 50.0f, 1.0f));
glUniformMatrix4fv(glGetUniformLocation(shaderID, "model"), 1, GL_FALSE,
glm::value_ptr(model));
glm::mat4 projection = glm::ortho(0.0f, 600.0f, 0.0f, 400.0f, -1.0f, 1.0f);
glUniformMatrix4fv(glGetUniformLocation(shaderID, "projection"), 1, GL_FALSE,
glm::value_ptr(projection));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwDestroyWindow(window);
glfwTerminate();
std::cout << "Destroyed" << std::endl;
}
SpriteShader.vs
#version 400 core
layout (location = 0) in vec4 vertex;
out vec2 TexCoords;
uniform mat4 model;
uniform mat4 projection;
void main()
{
TexCoords = vertex.zw;
gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0);
}
SpriteShader.fs
#version 400 core
in vec2 TexCoords;
out vec4 FragColour;
void main()
{
FragColour = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
我正在使用 GLFW 进行窗口管理,很高兴将其作为我的 OpenGL 库。这是使用 wayland 在 Linux (KDE Neon) 系统上完成的。
我相信这可能是我的一个矩阵的问题,无论是投影还是模型。但是我不确定问题是什么或如何解决它。
窗口可以缩放。您必须使用帧缓冲区大小作为视口大小:
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);