OpenGL - 将渲染结果输出到纹理中

5
我希望能够将某些内容渲染到OpenGL的纹理中,以便在需要时可以随时使用,而无需重新渲染所有内容。这个网站给了我实现它的指南,而不使用FrameBuffer。由于这台老机器不支持FrameBuffer Object,我不想使用它来实现。我已经编写了一些代码,用于创建我的纹理、渲染场景,并在其上创建一个Quad以渲染纹理。唯一的问题是,纹理被渲染成“Alpha Mask”的样子,这意味着看起来只考虑了Alpha值,使我的矩形始终保持相同的颜色,但只是改变像素的透明度。以下是我目前编写的一些代码:
void CreateTexture ()
{
    xSize = 512;
    ySize = 512; //size of texture
//new array
    char* colorBits = new char[ xSize * ySize * 3 ];
//texture creation..
    glGenTextures(1,&texture);
    glBindTexture(GL_TEXTURE_2D,texture);
    glTexImage2D(GL_TEXTURE_2D,0 ,3 , xSize,
                 ySize, 0 , GL_RGB,
                 GL_UNSIGNED_BYTE, colorBits);
//you can set other texture parameters if you want
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//clean up
    delete[] colorBits;
}

然后:

int viewport[4];
    glGetIntegerv(GL_VIEWPORT,(int*)viewport);
    glViewport(0,0,xSize,ySize);


    DrawScene(hDC);

    //save data to texture using glCopyTexImage2D
    glBindTexture(GL_TEXTURE_2D,texture);

    glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
                     0,0, xSize, ySize, 0);
    glClearColor(.0f, 0.5f, 0.5f, 1.0f);                // Set The Clear Color To Medium Blue
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glViewport(viewport[0],viewport[1],viewport[2],viewport[3]);
    // glBindTexture(GL_TEXTURE_2D,texture);

最后:
glEnable(GL_TEXTURE_2D);                    // Enable 2D Texture Mapping
        glBlendFunc(GL_DST_COLOR,GL_ONE);               // Set Blending Mode
        glEnable(GL_BLEND);

        glClear(GL_COLOR_BUFFER_BIT);
        glBindTexture(GL_TEXTURE_2D,texture);

        glRotatef(theta, 0.0f, 0.0f, 0.01f);
        glBegin(GL_QUADS);
         //Front Face
        glTexCoord2f(0.0f, 0.0f);
        glVertex3f(-0.5, -0.5f,  0.5f);
        glTexCoord2f(1.0f, 0.0f);
        glVertex3f( 0.5f, -0.5f,  0.5f);
        glTexCoord2f(1.0f, 1.0f);
        glVertex3f( 0.5f,  0.5f,  0.5f);
        glTexCoord2f(0.0f, 1.0f);
        glVertex3f(-0.5f,  0.5f,  0.5f);
        glEnd();
        SwapBuffers(hDC);

DrawScene()函数只是简单地渲染一个矩形,上面有一个三角形,每个顶点的颜色都不同.. 没什么特别的。
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT );//| GL_DEPTH_BUFFER_BIT);

glPushMatrix();
//    glRotatef(theta, 0.0f, 0.0f, 1.0f);

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

glBegin(GL_TRIANGLES);

glColor3f(1.0f, 0.0f, 0.0f);
glVertex2f(0.0f,   1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex2f(0.87f,  -0.5f);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex2f(-0.87f, -0.5f);
glEnd();
glPopMatrix();

请编辑您的文本,在所有情况下都将可渲染表面称为FrameBuffer对象,而不仅仅是framebuffer,这会误导人。 - Ani
你在渲染时似乎出现了混合。这是你的意图吗?你是否调用了swapBuffers来查看实际渲染的内容? - Ani
2个回答

4

我在 nVidia 网站上找到了一些有用的东西,适用于那些无法使用 FBO 进行离屏渲染的人:

http://developer.download.nvidia.com/SDK/9.5/Samples/samples.html

这个网站包含一个名为“Simple P-Buffer”的项目,基本上包含了一个P-buffer的实现。样例的想法是,在您想要在离屏模式下绘制像素时,将上下文切换到pBuffer。使用正常渲染函数绘制场景后,我们使用glReadPixels将数据从pBuffer读取到一个无符号字节(GLubyte)数组中。之后,我们再次进行上下文切换,将其设置回屏幕上下文,这样您就可以使用glReadPixels从我们的数组中读取内容。

0

Ben Voigt,感谢您的回答,我会在周一尝试并在此发布结果,如果成功解决问题,也会附上解决方案。 - filipehd
辅助缓冲区比FBOs的支持还要少。最广泛支持的方法是使用PBuffer设备上下文/渲染上下文作为渲染目标(与主OpenGL上下文共享对象),并将渲染的图像复制到纹理中。请搜索“PBuffer render to texture”。 - datenwolf
datenwolf,谢谢您的回答。正是因为这个答案,我才能够得出一些有趣的结果,如我在下面的回答中所发布的。 - filipehd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接