Я пытаюсь реализовать алгоритм IBFVS , и у меня возникают проблемы с одним из шагов, который заключается в сохранении смешанного изображения, находящегося в буфере кадров, в массив текстуры.
Мой объект на экране - это трехмерный кролик, который был наложен на текстуру с серым изображением, а затем смешан с изображением шума.Мне нужно сохранить только эту смешанную текстуру в исходном текстурном изображении, чтобы я мог использовать ее в следующем кадре.
Проблема в том, что если я использую 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.
Любые советы о том, как это сделать, очень ценятся!