OpenGL-仅从屏幕读取非黑色像素

时间:2018-12-02 20:39:39

标签: c opengl textures

我正在尝试实现IBFVS算法,但在其中一个步骤中遇到了麻烦,该步骤是将帧缓冲区中的混合图像存储到纹理数组中。

我在屏幕上的对象是3D兔子,该兔子已用灰色图像进行纹理映射,然后与噪声图像混合。我只需要将此混合纹理存储到原始纹理图像中,以便可以在下一帧中使用它。

问题是,如果我使用glReadPixels()glCopyTexImage2D()读取像素,则会得到整个屏幕,其中包括黑色背景以及兔子,这对我没有用,因为我只是寻找兔子表面的混合纹理。

有什么方法可以选择性地从屏幕上读取像素,使得我只能得到非黑色值?

我的代码来生成基本纹理:

glGenTextures(1, &FtTex);
for (int i = 0; i < 512; i++) {
    for (int j = 0; j < 512; j++) {
        baseTex[i][j][0] =
            baseTex[i][j][1] =
            baseTex[i][j][2] = (GLubyte)128;
    }
}
glBindTexture(GL_TEXTURE_2D, FtTex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 512, 512, 0, GL_RGB, GL_UNSIGNED_BYTE, baseTex);

产生噪音:

glGenTextures(32, noiseTexImg);

int lut[256]; // lookup table to store dynamic profiles
int phase[NRES][NRES]; // stores the phase for each pixel in the noise pattern
int t;

for (int i = 0; i < 256; i++) lut[i] = i < 127 ? 0 : 255; // fill lookup table with block pulse

for (int i = 0; i < NRES; i++)
    for (int j = 0; j < NRES; j++) phase[i][j] = rand() % 256;

for (int i = 0; i < NNoise; i++) {
    t = i * 256 / NNoise;
    for (int j = 0; j < NRES; j++) {
        for (int k = 0; k < NRES; k++) {
            noiseTex[j][k][0] =
                noiseTex[j][k][1] =
                noiseTex[j][k][2] = (GLubyte)lut[(t + phase[j][k]) % 255];
            noiseTex[j][k][3] = (GLubyte)(alpha * 255);
        }
    }
    glBindTexture(GL_TEXTURE_2D, noiseTexImg[i]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, NRES, NRES, 0, GL_RGBA, GL_UNSIGNED_BYTE, noiseTex);
}

具有基本纹理的绘图对象:

glPushMatrix();
glBindTexture(GL_TEXTURE_2D, FtTex);
for (int i = 0; i < poly->ntris; i++) {
    Triangle* t = poly->tlist[i];
    glBegin(GL_TRIANGLES);
    for (int j = 0; j < 3; j++) {
        Vertex *v = t->verts[j];
        glColor3f(1., 1., 0.);
        glTexCoord2dv(v->tx); glVertex3f(v->x, v->y, v->z);
    }
    glEnd();
}
glPopMatrix();

混合噪声:

glPushMatrix();
glLoadIdentity();
glTranslatef(-1.5, -1.5, 0);
glScalef(3, 3, 3);
glBindTexture(GL_TEXTURE_2D, noiseTexImg[fctr % NNoise]);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthFunc(GL_GREATER);
glBegin(GL_QUAD_STRIP);
glTexCoord2f(0, 0);       glVertex3f(0, 0, -40);
glTexCoord2f(0, tmax);    glVertex3f(0, 1, -40);
glTexCoord2f(tmax, 0);    glVertex3f(1, 0, -40);
glTexCoord2f(tmax, tmax); glVertex3f(1, 1, -40);
glEnd();
glDisable(GL_BLEND);
glDepthFunc(GL_LESS);
fctr++;
glPopMatrix();

显示功能的相关部分:

drawObjectWithFt(); // draw with base image

/* blend noise */
blendNoise();

glReadPixels(0, 0, BRES, BRES, GL_RGB, GL_UNSIGNED_BYTE, baseTex);
glBindTexture(GL_TEXTURE_2D, FtTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BRES, BRES, 0, GL_RGB, GL_UNSIGNED_BYTE, baseTex);

我在OpenGL 4.5上,大多数代码都在C语言中。

任何有关如何做到这一点的技巧都将受到赞赏!

0 个答案:

没有答案