Opengl渲染到纹理,但纹理为空

Posted

技术标签:

【中文标题】Opengl渲染到纹理,但纹理为空【英文标题】:Opengl render to texture, but the texture is null 【发布时间】:2017-10-24 15:14:24 【问题描述】:

我正在尝试渲染到纹理,然后将其渲染到正方形上。但结果是一个粉红色的正方形。

我创建纹理、帧缓冲区等

texture renderTexture = texture();
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1000, 600, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0);

unsigned int fb;
glGenFramebuffers(1, &fb);
glBindRenderbuffer(GL_RENDERBUFFER, fb);
glFramebufferTexture2D(GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, renderTexture.getId(), 0);

然后在游戏循环中我称之为:

show(fb);
showMenu(renderTexture.getId());

void game::show(unsigned int fb)

    glBindFramebuffer(GL_FRAMEBUFFER, fb);
    glViewport(0, 0, 1000, 600);

    glClearColor(0.5, 0.5, 0.5, 1.0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(0.0f, 0.0f, -7.0f);

    glBegin(GL_QUADS);
      glColor3f(0.0f, 1.0f, 0.0f);
      glVertex3f( 1.0f, 1.0f, -1.0f);
      glVertex3f(-1.0f, 1.0f, -1.0f);
      glVertex3f(-1.0f, 1.0f,  1.0f);
      glVertex3f( 1.0f, 1.0f,  1.0f);
   glEnd();

   // Render a pyramid consists of 4 triangles
   glLoadIdentity();                  // Reset the model-view matrix
   glTranslatef(-1.5f, 0.0f, -6.0f);  // Move left and into the screen


void game::showMenu(unsigned int renderTexture)

    bindWindowAsRenderTarget();
    glViewport(0, 0, 1000, 600);

    glClearColor(0.5, 0.5, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

    glOrtho(0.0, 1000.0, 0.0, 600.0, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);

    glLoadIdentity();

    glBindTexture(GL_TEXTURE_2D, renderTexture);
    glTranslatef(0.0,0.0,-5.0);
    glBegin(GL_QUADS);
        glTexCoord2f(0.0,2.0);
        glVertex3f(-2.0,2.0,0.0);
        glTexCoord2f(0.0,0.0);
        glVertex3f(-2.0,-2.0,0.0);
        glTexCoord2f(2.0,0.0);
        glVertex3f(2.0,-2.0,0.0);
        glTexCoord2f(2.0,2.0);
        glVertex3f(2.0,2.0,0.0);
    glEnd();

    glLoadIdentity();


void game::bindWindowAsRenderTarget()
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
    glViewport(0, 0, 1000, 600);

这是纹理类:

#include "texture.h"

texture::texture()
    glGenTextures(1, &id);
    glBindTexture(GL_TEXTURE_2D, id);


texture::~texture()
    glDeleteTextures(1, &id);


void texture::loadImage(const char* filename)
    SDL_Surface* img = SDL_LoadBMP(filename);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, img->w, img->h, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, img->pixels);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    SDL_FreeSurface(img);


unsigned int texture::getId()
    return id;

我在编译时没有任何错误...

我有什么遗漏吗? 有人知道怎么解决吗?

非常感谢。

【问题讨论】:

texture renderTexture = texture() 看起来很不对劲。如果您希望它存在于堆上,那么它应该是texture renderTexture();。但我想主要的问题是纹理在你尝试使用它之前就超出了范围。 【参考方案1】:

问题出在这里

texture renderTexture = texture();

您缺少new 关键字。这样可以防止调用您的纹理构造函数,这似乎正在执行您的纹理生成。

替换为

texture* renderTexture = new texture();

【讨论】:

然后出现这个错误:error: conversion from ‘texture*’ to non-scalar type ‘texture’ requested 那是因为他忘了说你必须使用指针(texture* renderTexture = new texture(); 对此......但如果这对你来说是新的,我建议在开始使用 OpenGL 之前阅读一个好的 C++ 教程。 谢谢,我忘了。我对 c++ 并不陌生,但这是我的第一个“项目”。但是问题仍然存在......当我运行它时程序崩溃...... 那么请提供一个最小但完整的代码示例。 Atm,不清楚这些代码部分是如何相互关联的。并在析构函数中设置断点以查看您的纹理是否过早删除。然后确保您设置了适当的过滤器。 现在我更详细地查看了它:您的四边形是否可见?对于从 0 到 1000(或 0 到 600)的可见区域,从 -2 到 2 的四边形听起来相当小。深度值看起来也很奇怪。您在 z = -5 处绘制,但将投影设置为从 -1 到 1 的可见范围。为什么您的纹理坐标从 0 变为 2?

以上是关于Opengl渲染到纹理,但纹理为空的主要内容,如果未能解决你的问题,请参考以下文章

将 CIFilter 应用于 OpenGL 渲染到纹理

OpenGL 试图渲染 2 个纹理,但只有 1 个?

在 OpenGL 中将深度渲染到纹理时出现奇怪的结果

无法使用 OpenGL 渲染 FBX 导入的纹理模型

OpenGL(FBO)中的普通后台缓冲区+渲染到深度纹理

OpenGL ES 2.0 Framebuffer 渲染到纹理 iOS:没有显示