shadowmap.c
来自「OpeNGL超级宝典源代码. OpeNGL超级宝典源代码.」· C语言 代码 · 共 545 行 · 第 1/2 页
C
545 行
void SetupRC()
{
const GLubyte *version;
fprintf(stdout, "Shadow Mapping Demo\n\n");
// Make sure required functionality is available!
version = glGetString(GL_VERSION);
if (((version[0] != '1') || (version[1] != '.') ||
(version[2] < '4') || (version[2] > '9')) && // 1.4+
(!gltIsExtSupported("GL_ARB_shadow")))
{
fprintf(stderr, "Neither OpenGL 1.4 nor GL_ARB_shadow"
" extension is available!\n");
Sleep(2000);
exit(0);
}
// Check for optional extension
if (gltIsExtSupported("GL_ARB_shadow_ambient"))
{
ambientShadowAvailable = GL_TRUE;
}
else
{
fprintf(stderr, "GL_ARB_shadow_ambient extension not available!\n");
fprintf(stderr, "Extra ambient rendering pass will be required.\n\n");
Sleep(2000);
}
fprintf(stdout, "Controls:\n");
fprintf(stdout, "\tRight-click for menu\n\n");
fprintf(stdout, "\tx/X\t\tMove +/- in x direction\n");
fprintf(stdout, "\ty/Y\t\tMove +/- in y direction\n");
fprintf(stdout, "\tz/Z\t\tMove +/- in z direction\n\n");
fprintf(stdout, "\tf/F\t\tChange polygon offset factor +/-\n\n");
fprintf(stdout, "\tq\t\tExit demo\n\n");
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
// Hidden surface removal
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glPolygonOffset(factor, 0.0f);
// Set up some lighting state that never changes
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHT0);
// Set up some texture state that never changes
glGenTextures(1, &shadowTextureID);
glBindTexture(GL_TEXTURE_2D, shadowTextureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
if (ambientShadowAvailable)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB,
0.5f);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
RegenerateShadowMap();
}
void ProcessMenu(int value)
{
switch(value)
{
case 1:
noShadows = !noShadows;
showShadowMap = GL_FALSE;
if (noShadows)
{
glutChangeToMenuEntry(1, "Toggle shadows (currently OFF)", 1);
}
else
{
glutChangeToMenuEntry(1, "Toggle shadows (currently ON)", 1);
}
glutChangeToMenuEntry(2, "Toggle show shadowmap (currently OFF)", 2);
break;
case 2:
showShadowMap = !showShadowMap;
noShadows = GL_FALSE;
if (showShadowMap)
{
glutChangeToMenuEntry(2, "Toggle show shadowmap (currently ON)", 2);
}
else
{
glutChangeToMenuEntry(2, "Toggle show shadowmap (currently OFF)", 2);
}
glutChangeToMenuEntry(1, "Toggle shadows (currently ON)", 1);
break;
case 3:
controlCamera = !controlCamera;
if (controlCamera)
{
glutChangeToMenuEntry(3, "Switch to LIGHT control (currently CAMERA)", 3);
}
else
{
glutChangeToMenuEntry(3, "Switch to CAMERA control (currently LIGHT)", 3);
}
break;
default:
break;
}
// Refresh the Window
glutPostRedisplay();
}
void KeyPressFunc(unsigned char key, int x, int y)
{
switch (key)
{
case 'f':
factor++;
glPolygonOffset(factor, 0.0f);
RegenerateShadowMap();
break;
case 'F':
factor--;
glPolygonOffset(factor, 0.0f);
RegenerateShadowMap();
break;
case 'x':
if (controlCamera)
cameraPos[0] += 5.0f;
else
lightPos[0] += 5.0f;
break;
case 'X':
if (controlCamera)
cameraPos[0] -= 5.0f;
else
lightPos[0] -= 5.0f;
break;
case 'y':
if (controlCamera)
cameraPos[1] += 5.0f;
else
lightPos[1] += 5.0f;
break;
case 'Y':
if (controlCamera)
cameraPos[1] -= 5.0f;
else
lightPos[1] -= 5.0f;
break;
case 'z':
if (controlCamera)
cameraPos[2] += 5.0f;
else
lightPos[2] += 5.0f;
break;
case 'Z':
if (controlCamera)
cameraPos[2] -= 5.0f;
else
lightPos[2] -= 5.0f;
break;
case 'q':
case 'Q':
case 27 : /* ESC */
exit(0);
}
// We don't need to regenerate the shadow map
// if only the camera angle changes
if (!controlCamera)
RegenerateShadowMap();
// Refresh the Window
glutPostRedisplay();
}
void SpecialKeys(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_LEFT:
if (controlCamera)
cameraPos[0] -= 5.0f;
else
lightPos[0] -= 5.0f;
break;
case GLUT_KEY_RIGHT:
if (controlCamera)
cameraPos[0] += 5.0f;
else
lightPos[0] += 5.0f;
break;
case GLUT_KEY_UP:
if (controlCamera)
cameraPos[2] -= 5.0f;
else
lightPos[2] -= 5.0f;
break;
case GLUT_KEY_DOWN:
if (controlCamera)
cameraPos[2] += 5.0f;
else
lightPos[2] += 5.0f;
break;
default:
break;
}
// We don't need to regenerate the shadow map
// if only the camera angle changes
if (!controlCamera)
RegenerateShadowMap();
// Refresh the Window
glutPostRedisplay();
}
void ChangeSize(int w, int h)
{
GLint i;
windowWidth = w;
windowHeight = h;
// Find the largest power of two that will fit in window
if (w > h)
shadowSize = h;
else
shadowSize = w;
// Try each size until we get one that's too big
i = 0;
while ((1 << i) <= shadowSize)
i++;
shadowSize = (1 << (i-1));
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(windowWidth, windowHeight);
glutCreateWindow("Shadow Mapping Demo");
glutReshapeFunc(ChangeSize);
glutKeyboardFunc(KeyPressFunc);
glutSpecialFunc(SpecialKeys);
glutDisplayFunc(RenderScene);
// Create the Menu
glutCreateMenu(ProcessMenu);
glutAddMenuEntry("Toggle shadows (currently ON)", 1);
glutAddMenuEntry("Toggle show shadowmap (currently OFF)", 2);
glutAddMenuEntry("Switch to LIGHT control (currently CAMERA)", 3);
glutAttachMenu(GLUT_RIGHT_BUTTON);
SetupRC();
glutMainLoop();
return 0;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?