我正在尝试使用 OpenGL 的立方体映射,但由于某种原因,y 图像被反转并且正在搞砸结果,并且正在执行的反射和折射无法正常工作。
这是我的代码。
void initCubeMap()
{
GLbyte *pBytes;
GLint eFormat, iComponents;
GLint width, height;
// Cull backs of polygons
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_CULL_FACE);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
// Set up texture maps
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
// Load Cube Map images
for(int i=0; i<6; i++)
{
// Load this texture map
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_GENERATE_MIPMAP, GL_TRUE);
pBytes = utilities.loadTGA(cubeFaces[i], &width, &height, &iComponents, &eFormat);
glTexImage2D(cube[i], 0, GL_RGB8, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
}
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
// Enable cube mapping, and set texture environment to decal
glEnable(GL_TEXTURE_CUBE_MAP);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
}
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
camera.RenderCam();
camera.MoveCamMouse();
// Sky Box is manually textured
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
drawSkyBox();
// Use texgen to apply cube map
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glPushMatrix();
glMatrixMode(GL_TEXTURE);
glPushMatrix();
GLfloat m[16];
glGetFloatv(GL_MODELVIEW_MATRIX, m);
camera.getCameraInverse(m);
glMultMatrixf(m);
glUseProgram(glassProgram);
utilities.setUniform("Cubemap", 0);
glutSolidSphere(5.0, 100, 100);
glUseProgram(0);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glPopMatrix();
// FPS
frame++;
time = glutGet(GLUT_ELAPSED_TIME);
if (time - timebase > 1000)
{
sprintf(s,"Template | FPS: %4.2f",frame*1000.0/(time-timebase));
timebase = time;
frame = 0;
}
glutSetWindowTitle((const char*)&s);
// Swap double buffer for flicker-free animation
glutSwapBuffers();
}
void Camera::getCameraInverse(GLfloat *result)
{
GLfloat resultTemp[16];
float tmp[12]; //temporary pair storage
float det; //determinant
//calculate pairs for first 8 elements (cofactors)
tmp[0] = result[10] * result[15];
tmp[1] = result[11] * result[14];
tmp[2] = result[9] * result[15];
tmp[3] = result[11] * result[13];
tmp[4] = result[9] * result[14];
tmp[5] = result[10] * result[13];
tmp[6] = result[8] * result[15];
tmp[7] = result[11] * result[12];
tmp[8] = result[8] * result[14];
tmp[9] = result[10] * result[12];
tmp[10] = result[8] * result[13];
tmp[11] = result[9] * result[12];
//calculate first 8 elements (cofactors)
resultTemp[0] = tmp[0]*result[5] + tmp[3]*result[6] + tmp[4]*result[7] - tmp[1]*result[5] - tmp[2]*result[6] - tmp[5]*result[7];
resultTemp[1] = tmp[1]*result[4] + tmp[6]*result[6] + tmp[9]*result[7] - tmp[0]*result[4] - tmp[7]*result[6] - tmp[8]*result[7];
resultTemp[2] = tmp[2]*result[4] + tmp[7]*result[5] + tmp[10]*result[7] - tmp[3]*result[4] - tmp[6]*result[5] - tmp[11]*result[7];
resultTemp[3] = tmp[5]*result[4] + tmp[8]*result[5] + tmp[11]*result[6] - tmp[4]*result[4] - tmp[9]*result[5] - tmp[10]*result[6];
resultTemp[4] = tmp[1]*result[1] + tmp[2]*result[2] + tmp[5]*result[3] - tmp[0]*result[1] - tmp[3]*result[2] - tmp[4]*result[3];
resultTemp[5] = tmp[0]*result[0] + tmp[7]*result[2] + tmp[8]*result[3] - tmp[1]*result[0] - tmp[6]*result[2] - tmp[9]*result[3];
resultTemp[6] = tmp[3]*result[0] + tmp[6]*result[1] + tmp[11]*result[3] - tmp[2]*result[0] - tmp[7]*result[1] - tmp[10]*result[3];
resultTemp[7] = tmp[4]*result[0] + tmp[9]*result[1] + tmp[10]*result[2] - tmp[5]*result[0] - tmp[8]*result[1] - tmp[11]*result[2];
//calculate pairs for second 8 elements (cofactors)
tmp[0] = result[2]*result[7];
tmp[1] = result[3]*result[6];
tmp[2] = result[1]*result[7];
tmp[3] = result[3]*result[5];
tmp[4] = result[1]*result[6];
tmp[5] = result[2]*result[5];
tmp[6] = result[0]*result[7];
tmp[7] = result[3]*result[4];
tmp[8] = result[0]*result[6];
tmp[9] = result[2]*result[4];
tmp[10] = result[0]*result[5];
tmp[11] = result[1]*result[4];
//calculate second 8 elements (cofactors)
resultTemp[8] = tmp[0]*result[13] + tmp[3]*result[14] + tmp[4]*result[15] - tmp[1]*result[13] - tmp[2]*result[14] - tmp[5]*result[15];
resultTemp[9] = tmp[1]*result[12] + tmp[6]*result[14] + tmp[9]*result[15] - tmp[0]*result[12] - tmp[7]*result[14] - tmp[8]*result[15];
resultTemp[10] = tmp[2]*result[12] + tmp[7]*result[13] + tmp[10]*result[15] - tmp[3]*result[12] - tmp[6]*result[13] - tmp[11]*result[15];
resultTemp[11] = tmp[5]*result[12] + tmp[8]*result[13] + tmp[11]*result[14] - tmp[4]*result[12] - tmp[9]*result[13] - tmp[10]*result[14];
resultTemp[12] = tmp[2]*result[10] + tmp[5]*result[11] + tmp[1]*result[9] - tmp[4]*result[11] - tmp[0]*result[9] - tmp[3]*result[10];
resultTemp[13] = tmp[8]*result[11] + tmp[0]*result[8] + tmp[7]*result[10] - tmp[6]*result[10] - tmp[9]*result[11] - tmp[1]*result[8];
resultTemp[14] = tmp[6]*result[9] + tmp[11]*result[11] + tmp[3]*result[8] - tmp[10]*result[11] - tmp[2]*result[8] - tmp[7]*result[9];
resultTemp[15] = tmp[10]*result[10] + tmp[4]*result[8] + tmp[9]*result[9] - tmp[8]*result[9] - tmp[11]*result[10] - tmp[5]*result[8];
// calculate determinant
det = result[0]*resultTemp[0] + result[1]*resultTemp[1] + result[2]*resultTemp[2] + result[3]*resultTemp[3];
resultTemp[0] = resultTemp[0]/det;
resultTemp[1] = resultTemp[1]/det;
resultTemp[2] = resultTemp[2]/det;
resultTemp[3] = resultTemp[3]/det;
resultTemp[4] = resultTemp[4]/det;
resultTemp[5] = resultTemp[5]/det;
resultTemp[6] = resultTemp[6]/det;
resultTemp[7] = resultTemp[7]/det;
resultTemp[8] = resultTemp[8]/det;
resultTemp[9] = resultTemp[9]/det;
resultTemp[10] = resultTemp[10]/det;
resultTemp[11] = resultTemp[11]/det;
resultTemp[12] = resultTemp[12]/det;
resultTemp[13] = resultTemp[13]/det;
resultTemp[14] = resultTemp[14]/det;
resultTemp[15] = resultTemp[15]/det;
if(det==0.0f)
{
result[0] = 1.0;
result[1] = 0.0;
result[2] = 0.0;
result[3] = 0.0;
result[4] = 0.0;
result[5] = 1.0;
result[6] = 0.0;
result[7] = 0.0;
result[8] = 0.0;
result[9] = 0.0;
result[10] = 1.0;
result[11] = 0.0;
result[12] = 0.0;
result[13] = 0.0;
result[14] = 0.0;
result[15] = 1.0;
}
result[0] = resultTemp[0];
result[1] = resultTemp[4];
result[2] = resultTemp[8];
result[3] = resultTemp[12];
result[4] = resultTemp[1];
result[5] = resultTemp[5];
result[6] = resultTemp[9];
result[7] = resultTemp[13];
result[8] = resultTemp[2];
result[9] = resultTemp[6];
result[10] = resultTemp[10];
result[11] = resultTemp[14];
result[12] = resultTemp[3];
result[13] = resultTemp[7];
result[14] = resultTemp[11];
result[15] = resultTemp[15];
}
这是我现在的 OpenGL 显示功能。它仍然无法正常工作。
void renderScene()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
camera.RenderCam();
camera.MoveCamMouse();
// Sky Box is manually textured
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
drawSkyBox();
// Use texgen to apply cube map
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glUseProgram(glassProgram);
utilities.setUniform("Cubemap", 0);
glPushMatrix();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glScalef(-1, -1, -1);
glPushMatrix();
GLfloat m[16];
glGetFloatv(GL_MODELVIEW_MATRIX, m);
camera.getCameraInverse(m);
glMultMatrixf(m);
glutSolidSphere(5.0, 100, 100);
glPopMatrix();
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glUseProgram(0);
glPopMatrix();
// FPS
frame++;
time = glutGet(GLUT_ELAPSED_TIME);
if (time - timebase > 1000)
{
sprintf(s,"Texture Mapping | FPS: %4.2f",frame*1000.0/(time-timebase));
timebase = time;
frame = 0;
}
glutSetWindowTitle((const char*)&s);
// Swap double buffer for flicker-free animation
glutSwapBuffers();
}
这是我执行反射和折射的 GLSL 代码。不确定这里是否有问题
// Vertex Shader
const float EtaR = 0.65;
const float EtaG = 0.67; // Ratio of indices of refraction
const float EtaB = 0.69;
const float FresnelPower = 1.0;
const float F = ((1.0-EtaG) * (1.0-EtaG)) / ((1.0+EtaG) * (1.0+EtaG));
varying vec3 Reflect;
varying vec3 RefractR;
varying vec3 RefractG;
varying vec3 RefractB;
varying float Ratio;
void main()
{
vec4 ecPosition = gl_ModelViewMatrix * gl_Vertex;
vec3 ecPosition3 = ecPosition.xyz / ecPosition.w;
vec3 i = normalize(ecPosition3);
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
Ratio = F + (1.0 - F) * pow((1.0 - dot(-i, n)), FresnelPower);
RefractR = refract(i, n, EtaR);
RefractR = vec3(gl_TextureMatrix[0] * vec4(RefractR, 1.0));
RefractG = refract(i, n, EtaG);
RefractG = vec3(gl_TextureMatrix[0] * vec4(RefractG, 1.0));
RefractB = refract(i, n, EtaB);
RefractB = vec3(gl_TextureMatrix[0] * vec4(RefractB, 1.0));
Reflect = reflect(i, n);
Reflect = vec3(gl_TextureMatrix[0] * vec4(Reflect, 1.0));
gl_Position = ftransform();
}
// Fragment Shader
varying vec3 Reflect;
varying vec3 RefractR;
varying vec3 RefractG;
varying vec3 RefractB;
varying float Ratio;
uniform samplerCube Cubemap;
void main()
{
vec3 refractColor, reflectColor;
refractColor.r = vec3(textureCube(Cubemap, RefractR)).r;
refractColor.g = vec3(textureCube(Cubemap, RefractG)).g;
refractColor.b = vec3(textureCube(Cubemap, RefractB)).b;
reflectColor = vec3(textureCube(Cubemap, Reflect));
vec3 color = mix(refractColor, reflectColor, Ratio);
gl_FragColor = vec4(color, 1.0);
}