我正在创建一个大小为1920 X 1080的自定义帧缓冲区,然后将此帧缓冲区的纹理映射到大小为800 X 600的默认帧缓冲区中的全屏矩形。
我在自定义帧缓冲区的屏幕中央绘制了一个矩形,并且在映射纹理后,我期望该矩形出现在中央。
但是矩形显示在左下角。
当我在自定义缓冲区中绘制全屏矩形并将其映射到大小为800 X 600的默认帧缓冲区中的全屏矩形时,而不是全屏显示时,它覆盖了整个左下角。
SCR_WIDTH = 800;
SCR_HEIGHT = 600;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
cont.SetName("RootItem");
TreeModel* model = new TreeModel("RootElement", &cont);
WavefrontRenderer w(model);
w.show();
glfwInit();
int return_code;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Renderer", nullptr, nullptr); // Create the render window
glfwSetWindowPos(window, 1120, 480);
glfwFocusWindow(window);
glfwMakeContextCurrent(window);
GLenum GlewInitResult;
glewExperimental = GL_TRUE;
GlewInitResult = glewInit();
glEnable(GL_MULTISAMPLE);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
ResourceManager::LoadShader("C:\\Shaders\\Test\\Vert.txt", "C:\\Shaders\\Test\\Frag.txt", nullptr, "ScreenShader");
//create a texture object
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1920, 1080, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
// create a renderbuffer object for depthbuffer
glGenRenderbuffers(1, &rboDepthId);
glBindRenderbuffer(GL_RENDERBUFFER, rboDepthId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, 1920, 1080);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// create a framebuffer
glGenFramebuffers(1, &fboMsaaId);
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);
// attach colorbuffer image to FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureId , 0);
// attach depthbuffer image to FBO
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboDepthId);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
while (!glfwWindowShouldClose(window))
{
glBindFramebuffer(GL_FRAMEBUFFER, fboMsaaId);
glClearColor(1.0, 0.0, 0.0, 1.0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
w.render(); // Do rendering here
ResourceManager::GetShader("ScreenShader").Use();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDisable(GL_DEPTH_TEST);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
ResourceManager::GetShader("ScreenShader").Use();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textureId);
renderQuad();
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return a.exec();
}
///////////////////////////////////////////////// ///////////////////////////////////////////////////// /渲染四边形功能定义
unsigned int quadVAO = 0;
unsigned int quadVBO;
void renderQuad()
{
if (quadVAO == 0)
{
float quadVertices[] = { // vertex attributes for a quad that fills the entire screen in Normalized Device Coordinates.
// positions // texCoords
-1.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f,
1.0f, -1.0f, 1.0f, 0.0f,
-1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f, 1.0f
};
// VAO
glGenVertexArrays(1, &quadVAO);
glGenBuffers(1, &quadVBO);
glBindVertexArray(quadVAO);
glBindBuffer(GL_ARRAY_BUFFER, quadVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)(2 * sizeof(float)));
}
glBindVertexArray(quadVAO);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
glBindVertexArray(0);
}
glViewport
设置视口。可以通过glViewport
获得默认帧缓冲区的大小(更改窗口大小时,窗口帧缓冲区的大小也会更改)。此外,OpenGL是一个状态引擎。状态是持久的,直到再次更改,甚至超出框架为止。如果第一遍使用glfwGetFramebufferSize
,但第二遍没有使用glfwGetFramebufferSize
,则深度测试必须在循环中bs开启和关闭: