与设置为相同尺寸的窗口相比,OpenGL 视口的尺寸不正确

问题描述 投票:0回答:1

我有一个 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) 系统上完成的。

我相信这可能是我的一个矩阵的问题,无论是投影还是模型。但是我不确定问题是什么或如何解决它。

opengl graphics 2d glfw glad
1个回答
0
投票

窗口可以缩放。您必须使用帧缓冲区大小作为视口大小:

int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
© www.soinside.com 2019 - 2024. All rights reserved.