I have a window of 600x400, the viewport on which OpenGL is rendering appears to be much smaller (pictured below).
The below code is able to reproduce what I am seeing. This code is also almost the exact same as the sprite renderer shown by learnopengl.com in their In Practice section.
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);
}
I am using GLFW for window management and glad as my library for OpenGL. This was done on a Linux (KDE Neon) system using wayland.
I believe this is likely a problem with one of my matrices, be it the projection or model. I am however unsure of what the problem is or how to fix it.
The window can be scaled. You have to use the size of the frame buffer for the size of the viewport:
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);