Simple and short question but I don't know why it is not working. When I call glViewport in the window frame buffer callback nothing changes. Error code is 1282 (0x502). I already googled and found no helpful article. Some said I should use glScissor in addition but does not work either.
Here an MCVE with an oscillating quad for visualization:
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#include "glm/vec3.hpp"
#include <thread>
#include <iostream>
#include <vector>
#include <chrono>
#include <Windows.h>
#include <wingdi.h>
int createShaders() {
const char* vertex = R"(
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
uniform float scale;
void main() {
gl_Position = vec4(vertexPosition_modelspace, 1.0) * vec4(vec3(scale), 1.0f);
}
)";
const char* fragment = R"(
#version 330 core
void main() {
gl_FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}
)";
int vertexID, fragmentID, pid;
vertexID = glCreateShader(GL_VERTEX_SHADER);
const GLchar* source = (const GLchar*)vertex;
glShaderSource(vertexID, 1, &source, 0);
glCompileShader(vertexID);
int isCompiled = 0;
glGetShaderiv(vertexID, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
int maxLength = 0;
glGetShaderiv(vertexID, GL_INFO_LOG_LENGTH, &maxLength);
char* infoLog = new char[maxLength];
glGetShaderInfoLog(vertexID, maxLength, &maxLength, infoLog);
std::cout << infoLog << std::endl;
glDeleteShader(vertexID);
return 0;
}
fragmentID = glCreateShader(GL_FRAGMENT_SHADER);
source = (const GLchar*)fragment;
glShaderSource(fragmentID, 1, &source, 0);
glCompileShader(fragmentID);
glGetShaderiv(fragmentID, GL_COMPILE_STATUS, &isCompiled);
if (isCompiled == GL_FALSE)
{
int maxLength = 0;
glGetShaderiv(fragmentID, GL_INFO_LOG_LENGTH, &maxLength);
char* infoLog = new char[maxLength];
glGetShaderInfoLog(fragmentID, maxLength, &maxLength, infoLog);
std::cout << infoLog << std::endl;
glDeleteShader(fragmentID);
glDeleteShader(vertexID);
return 0;
}
pid = glCreateProgram();
glAttachShader(pid, vertexID);
glAttachShader(pid, fragmentID);
glLinkProgram(pid);
int isLinked = 0;
glGetProgramiv(pid, GL_LINK_STATUS, (int*)&isLinked);
if (isLinked == GL_FALSE)
{
int maxLength = 0;
glGetProgramiv(pid, GL_INFO_LOG_LENGTH, &maxLength);
std::vector<GLchar> infoLog(maxLength);
glGetProgramInfoLog(pid, maxLength, &maxLength, &infoLog[0]);
glDeleteProgram(pid);
glDeleteShader(vertexID);
glDeleteShader(fragmentID);
return 0;
}
glDetachShader(pid, vertexID);
glDetachShader(pid, fragmentID);
return pid;
}
unsigned int createVertexArray() {
std::vector<glm::vec3> vertices = {
glm::vec3(0.5f, 0.5f, 0.0f),
glm::vec3(0.5f, -0.5f, 0.0f),
glm::vec3(-0.5f, -0.5f, 0.0f),
glm::vec3(-0.5f, 0.5f, 0.0f)
};
unsigned int arrayID, id;
glGenVertexArrays(1, &arrayID);
glBindVertexArray(arrayID);
glGenBuffers(1, &id);
glBindBuffer(GL_ARRAY_BUFFER, id);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
return arrayID;
}
int main() {
if (!glfwInit())
return 1;
GLFWwindow* window = glfwCreateWindow(960, 520, "MCVE", NULL, NULL);
glfwSetFramebufferSizeCallback(window, [](GLFWwindow* window, int width, int height) {
glViewport(0, 0, width, height);
});
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
return 1;
wglMakeCurrent(NULL, NULL);
std::thread mainLoopThread([window]() {
glfwMakeContextCurrent(window);
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
int shaderID = createShaders();
int vertexID = createVertexArray();
while (!glfwWindowShouldClose(window)) {
std::chrono::steady_clock::time_point current = std::chrono::steady_clock::now();
std::chrono::microseconds time = std::chrono::duration_cast<std::chrono::microseconds>(current - start);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shaderID);
float s = sin(time.count() / 1000000.0f * 2.0f);
glUniform1f(glGetUniformLocation(shaderID, "scale"), s);
glBindVertexArray(vertexID);
glDrawArrays(GL_QUADS, 0, 4);
glfwSwapBuffers(window);
}
});
while (!glfwWindowShouldClose(window))
glfwWaitEvents();
mainLoopThread.join();
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}