渲染纹理问题

发布于 2024-12-25 02:14:55 字数 2811 浏览 0 评论 0原文

我很努力让纹理渲染工作正常,但遇到了一些麻烦。我正在尝试在屏幕上渲染一个简单的四边形,以确保一切正常。

    target->enable();

    glBegin(GL_QUADS);

    glColor4f(1.f, 0.f, 0.f, 1.f);
    glVertex3f(0.f, 0.f, 0.f);

    glColor4f(0.f, 1.f, 0.f, 1.f);
    glVertex3f(16.f, 0.f, 0.f);

    glColor4f(0.f, 0.f, 1.f, 1.f);
    glVertex3f(0.f, 16.f, 0.f);

    glColor4f(1.f, 1.f, 0.f, 1.f);
    glVertex3f(16.f, 16.f, 0.f);

    glEnd();

    target->disable();

当我正常将四边形绘制到屏幕上时,四边形将按预期渲染。但是,当我在启用渲染目标的情况下绘制四边形时,四边形将在屏幕的左下角渲染,并且最终不会渲染到目标。

RenderTarget::RenderTarget(GraphicsDevice *graphics, GLuint width, GLuint height) {

    mWidth = width;
    mHeight = height;

    // First create the depth buffer
    glGenRenderbuffers(1, &mDepth);
    glBindRenderbuffer(GL_RENDERBUFFER_EXT, mDepth);

    // Tell OpenGL that this renderbuffer is going to be a depth buffer
    glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, mWidth, mHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);

    glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);

    // Create the frame buffer texture
    glGenTextures(1, &mTexture);
    glBindTexture(GL_TEXTURE_2D, mTexture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glBindTexture(GL_TEXTURE_2D, 0);

    // Create the frame buffer
    glGenFramebuffers(1, &mFbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);

    // Attach the texture
    glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexture, 0);

    //Attach the depth buffer
    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mFbo);

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);


}

RenderTarget::~RenderTarget() {
    glDeleteBuffers(1, &mFbo);
    glDeleteBuffers(1, &mDepth);
    glDeleteTextures(1, &mTexture);
    mFbo = 0;
    mDepth = 0;
    mTexture = 0;
}

void RenderTarget::enable() {
    // Bind the frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);
    // store the glViewport and glEnable states
    //glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);

    glClearColor(1.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.f, 0.f, 0.f, 0.f);

    glLoadIdentity();
}

void RenderTarget::disable() {
    // Restore glViewport and glEnable states
    glPopAttrib();
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}

I'm tyring to get rendering to texture working, but am having a bit of trouble. I'm trying to render a simple quad to the screen to make sure everything is working.

    target->enable();

    glBegin(GL_QUADS);

    glColor4f(1.f, 0.f, 0.f, 1.f);
    glVertex3f(0.f, 0.f, 0.f);

    glColor4f(0.f, 1.f, 0.f, 1.f);
    glVertex3f(16.f, 0.f, 0.f);

    glColor4f(0.f, 0.f, 1.f, 1.f);
    glVertex3f(0.f, 16.f, 0.f);

    glColor4f(1.f, 1.f, 0.f, 1.f);
    glVertex3f(16.f, 16.f, 0.f);

    glEnd();

    target->disable();

When I draw the quad to the screen normally, the quad renders as expected. However, when I draw the quad with the render target enabled, the quad gets rendered at the bottom left corner of the screen and ends up not being rendered to the target.

RenderTarget::RenderTarget(GraphicsDevice *graphics, GLuint width, GLuint height) {

    mWidth = width;
    mHeight = height;

    // First create the depth buffer
    glGenRenderbuffers(1, &mDepth);
    glBindRenderbuffer(GL_RENDERBUFFER_EXT, mDepth);

    // Tell OpenGL that this renderbuffer is going to be a depth buffer
    glRenderbufferStorage(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, mWidth, mHeight);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);

    glBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);

    // Create the frame buffer texture
    glGenTextures(1, &mTexture);
    glBindTexture(GL_TEXTURE_2D, mTexture);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, mWidth, mHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glBindTexture(GL_TEXTURE_2D, 0);

    // Create the frame buffer
    glGenFramebuffers(1, &mFbo);
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);

    // Attach the texture
    glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, mTexture, 0);

    //Attach the depth buffer
    glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mFbo);

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);


}

RenderTarget::~RenderTarget() {
    glDeleteBuffers(1, &mFbo);
    glDeleteBuffers(1, &mDepth);
    glDeleteTextures(1, &mTexture);
    mFbo = 0;
    mDepth = 0;
    mTexture = 0;
}

void RenderTarget::enable() {
    // Bind the frame buffer
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);
    // store the glViewport and glEnable states
    //glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);

    glClearColor(1.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.f, 0.f, 0.f, 0.f);

    glLoadIdentity();
}

void RenderTarget::disable() {
    // Restore glViewport and glEnable states
    glPopAttrib();
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

蓝眼睛不忧郁 2025-01-01 02:14:55

您的启用正在使用 glLoadIdentity 重置当前矩阵(最有可能是模型视图)。这解释了为什么您的方块被移动到屏幕的角落。

您已注释掉对 glPushAttrib 的调用,但未注释掉对 glPopAttrib 的匹配调用。如果您不在其他任何地方使用 glPushAttrib ,这应该设置一个错误标志并单独保留 GL 状态,但我不知道情况是这样,并且假设属性堆栈是并且是自找麻烦永远都会是空的。

文档glBindFrameBuffer 建议您应该使用 GL_FRAMEBUFFERGL_DRAW_FRAMEBUFFER 作为第一个参数:

target 必须是 GL_DRAW_FRAMEBUFFER、GL_READ_FRAMEBUFFER 或
GL_帧缓冲。如果帧缓冲区对象绑定到
GL_DRAW_FRAMEBUFFER 或 GL_READ_FRAMEBUFFER,它成为目标
分别进行渲染或读回操作,直到被删除或
另一个帧缓冲区绑定到相应的绑定点。呼唤
目标设置为 GL_FRAMEBUFFER 的 glBindFramebuffer 绑定 framebuffer
读取和绘制帧缓冲区目标。

代码中带有 _EXT 后缀的枚举可能属于此处记录的版本之前的 OpenGL 版本。教程很容易让这样的细节过时。

检查您的环境&依赖于与您的 OpenGL 版本相匹配的文档。如果由于某种原因您无法轻松确定 OpenGL 版本,请在调用 glBindFrameBuffer 后检查 GL_INVALID_ENUM 错误。

Your enable is resetting the current matrix (most likely modelview) with glLoadIdentity. This explains why your square is being moved to the corner of the screen.

You've commented out the call to glPushAttrib but not the matching call to glPopAttrib. If you don't use glPushAttrib anywhere else this should set an error flag and leave GL state alone, but I don't know that's the case and it's asking for trouble to assume that the attribute stack is and always will be empty.

This documentation for glBindFrameBuffer suggests that you ought to be using GL_FRAMEBUFFER or GL_DRAW_FRAMEBUFFER as the first argument:

target must be either GL_DRAW_FRAMEBUFFER, GL_READ_FRAMEBUFFER or
GL_FRAMEBUFFER. If a framebuffer object is bound to
GL_DRAW_FRAMEBUFFER or GL_READ_FRAMEBUFFER, it becomes the target for
rendering or readback operations, respectively, until it is deleted or
another framebuffer is bound to the corresponding bind point. Calling
glBindFramebuffer with target set to GL_FRAMEBUFFER binds framebuffer
to both the read and draw framebuffer targets.

The enums with _EXT suffix in your code likely pertain to a version of OpenGL previous to the version documented there. Tutorials are prone to allowing details like this to fall out of date.

Check your environment & rely on the documentation that matches your version of OpenGL. If for some reason you can't easily determine your version of OpenGL, check for the GL_INVALID_ENUM error after calling glBindFrameBuffer.

森林很绿却致人迷途 2025-01-01 02:14:55

这段代码似乎是错误的:

//Attach the depth buffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mFbo);

您在这里所做的是尝试将 mFbo 作为渲染缓冲区附加到 mFbo。但是,您已经正确附加了渲染缓冲区(这是在第一次调用 glFramebufferRenderbuffer() 时完成的)。我认为删除该代码应该可以解决您的问题。

This code seems wrong:

//Attach the depth buffer
glFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mFbo);

What you are doing here is that you are trying to attach mFbo as a render buffer to mFbo. However, you already have your render buffer attached correctly (which is done in the first call to glFramebufferRenderbuffer()). I think removing that code should fix your problem.

池木 2025-01-01 02:14:55

正如我怀疑的那样,我的问题是在渲染 FBO 时正确设置 glViewport 和 glOrtho。这段代码需要清理,但这是我修复它的方法。

void RenderTarget::enable() {
    // Bind the frame buffer

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);
    // store the glViewport and glEnable states
    //glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);

    glViewport(0, 0, mWidth, mHeight);
    // projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // orthographic projection
    glOrtho(0, mWidth, 0, mHeight, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClearColor(1.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.f, 0.f, 0.f, 0.f);

    glLoadIdentity();
}

void RenderTarget::disable() {
    // Restore glViewport and glEnable states
    //glPopAttrib();
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
    glViewport(0, 0, 1024, 768);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // orthographic projection
    glOrtho(0, 1024, 768, 0, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

As I suspected, my problem was setting glViewport, and glOrtho correctly when rendering the FBO. This code needs to be cleaned up, but here is how I fixed it.

void RenderTarget::enable() {
    // Bind the frame buffer

    glBindFramebuffer(GL_FRAMEBUFFER_EXT, mFbo);
    // store the glViewport and glEnable states
    //glPushAttrib(GL_VIEWPORT_BIT | GL_ENABLE_BIT);

    glViewport(0, 0, mWidth, mHeight);
    // projection matrix
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // orthographic projection
    glOrtho(0, mWidth, 0, mHeight, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClearColor(1.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glClearColor(0.f, 0.f, 0.f, 0.f);

    glLoadIdentity();
}

void RenderTarget::disable() {
    // Restore glViewport and glEnable states
    //glPopAttrib();
    glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
    glViewport(0, 0, 1024, 768);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    // orthographic projection
    glOrtho(0, 1024, 768, 0, -1, 1);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文