我正在尝试实现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语言中。
任何有关如何做到这一点的技巧都将受到赞赏!