📄 main.c
字号:
/* Copyright (C) Gabor Nagy, 2000. * All rights reserved worldwide. * * This software is provided "as is" without express or implied * warranties. You may freely copy and compile this source into * applications you distribute provided that the copyright text * below is included in the resulting source code, for example: * "Portions Copyright (C) Gabor Nagy, 2000" *//*==============================================================================*//* Real-time cast shadows *//* *//* - The Main *//* *//* AUTHOR: Gabor Nagy *//* DATE: 2000-May-02 14:28:33 *//* v1.02 *//* *//* For Game Programming Graphics Gems *//*==============================================================================*/#include <stdio.h>#include <math.h>#include <GL/glut.h>#include <stdlib.h>#ifdef _WIN32#include <windows.h>#include <time.h>#else#include <sys/time.h>#include <sys/param.h>#endif#include "str.h"#include "obj.h"E3dModel* Scn_BulbModel=NULL;E3dModel* Scn_BlockerModel=NULL;E3dModel* Scn_ReceiverModel0=NULL;E3dModel* Scn_ReceiverModel1=NULL;E3dLight Sh_Light;enum{ ShDOLLY_CAMERA=0, ShMOVE_LIGHT};int Sh_MiddleMouseMode=ShDOLLY_CAMERA;int Sh_DisplayMode=0;#ifdef _WIN32float Sh_StartTime;#elseunsigned long Sh_StartTime;#endifunsigned long Sh_NumOfFrames=200;unsigned long Sh_Frame=0;// Shadow map//unsigned long* Sh_ShadowMapImage=NULL;int Sh_ShadowMapXSize=128, Sh_ShadowMapYSize=128;int Sh_TexXSize, Sh_TexYSize;GLubyte* Sh_TexImage;GLuint Sh_ShadowMapTexId, Sh_WoodTexId;EBool Sh_BackFaceShadowElimination=TRUE;// Viewing//float Sh_Longitude=152.0, Sh_Latitude=-36.0;float Sh_ViewDistance = 20.0;float Sh_ZNear=0.1, Sh_ZFar=8192.0;float Sh_WindowAspect = 4.0/3.0;long Sh_WindowXSize, Sh_WindowYSize;int Sh_PrevMX, Sh_PrevMY;EBool Sh_LeftButton = FALSE, Sh_MiddleButton = FALSE;int Sh_MainMenu, Sh_DisplayMenu, Sh_BlockerObjectMenu, Sh_ShadowMapMenu, Sh_BackFaceShadowMenu;int Sh_CurrentBlockerObject=-1;/* From shadow.c */extern void E3d_ShadowMatrix(E3dLight* LLight, E3dModel *LModel, E3dMatrix LBlockerMatrix, E3dMatrix LReceiverUVMatrix);extern void Sh_CreateShadowMap(GLuint LShadowMapTexId, int LMapXSize, int LMapYSize, E3dMesh *LBlockerMesh, E3dMatrix LBlockerMatrix);/*======================================*//* Setlect blocker object *//*======================================*/void ShCB_SetlectBlockerObject(int LValue){ E3dMesh* LMesh; E3dPolyGroup* LPolyGroup; E3dMaterial* LMaterial; if(Sh_CurrentBlockerObject!=LValue) { switch(LValue) { case 0: if(Scn_BlockerModel!=NULL) E3d_ModelFree(Scn_BlockerModel); if((Scn_BlockerModel=E3d_ReadOBJFile("objects/torus.obj")) != NULL) { Scn_BlockerModel->Translation.Y=5.0; } break; case 1: if(Scn_BlockerModel!=NULL) E3d_ModelFree(Scn_BlockerModel); if((Scn_BlockerModel=E3d_ReadOBJFile("objects/HGlassShadow.obj")) != NULL) { Scn_BlockerModel->Translation.Y=5.0; } break; } Sh_CurrentBlockerObject=LValue; } if(Scn_BlockerModel!=NULL) { LMesh=(E3dMesh*)(Scn_BlockerModel->Geometry); LPolyGroup=LMesh->PolyGroups[0]; LPolyGroup->Material=LMaterial=E3d_MaterialAllocate(); LMaterial->Diffuse[0]=0.0; LMaterial->Diffuse[1]=0.5; LMaterial->Diffuse[2]=0.9; } glutPostRedisplay();}/*======================================*//* Set shadow-map size *//*======================================*/void ShCB_SetShadowMapSize(int LValue){ if(Sh_ShadowMapXSize!=LValue) { if(Sh_ShadowMapImage!=NULL) free(Sh_ShadowMapImage); Sh_ShadowMapImage=(unsigned long*)malloc(LValue*LValue*sizeof(unsigned long)); } Sh_ShadowMapXSize=LValue; Sh_ShadowMapYSize=LValue; glutPostRedisplay();}/*======================================*//* Back-face shadow elimination On/Off *//*======================================*/void ShCB_BackFaceShadow(int LValue){ Sh_BackFaceShadowElimination=LValue; glutPostRedisplay();}/*======================================*//* Main menu callback *//*======================================*/void ShCB_MainMenu(int value){ switch(value) { case 5: exit(0); break; }}/*==============================*//* Glut idle function *//*==============================*/void Sh_Run(void){ if(Scn_BlockerModel!=NULL) { Scn_BlockerModel->Rotation.X+=1.0; Scn_BlockerModel->Rotation.Y+=2.0; Scn_BlockerModel->Rotation.Z+=4.0; glutPostRedisplay(); }}// Texture "border color" for clamping// (same as the shadow-map background color: white)//float Sh_TxBorder[4]= { 1.0, 1.0, 1.0, 1.0};/*==============================*//* Read raw RGBA file *//*==============================*/char* E3d_LoadImage(char* LFileName){ FILE* LInFile; char* LBuffer=NULL; unsigned long LFileSize; if((LInFile=fopen(LFileName,"r"))!=NULL) {// Determine file length// fseek(LInFile, 0, SEEK_END); LFileSize=ftell(LInFile); fseek(LInFile, 0, SEEK_SET);// Allocate buffer and read file// if((LBuffer=EMalloc(LFileSize))!=NULL) { fread(LBuffer, 1, LFileSize, LInFile); } fclose(LInFile); } return(LBuffer);}/*==============================*//* Initialize textures *//*==============================*/void Sh_InitTextures(void){ int LTexXSize, LTexYSize; GLubyte* LTexData;// Read and set up wood texture// glGenTextures(1,&Sh_WoodTexId); glBindTexture(GL_TEXTURE_2D, Sh_WoodTexId); if((LTexData=(GLubyte*)E3d_LoadImage("Wood.rgba"))!=NULL) { LTexXSize=128;LTexYSize=128; glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 4, LTexXSize, LTexYSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, LTexData ); }// Initialize shadow map// glGenTextures(1,&Sh_ShadowMapTexId); glBindTexture(GL_TEXTURE_2D, Sh_ShadowMapTexId); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, Sh_TxBorder); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);}/*==============================*//* Render the scene *//*==============================*/void Sh_DrawScene(){ E3dModel* LModel; E3dMesh* LMesh; E3dPolyGroup* LPolyGroup; E3dMaterial* LMaterial; glDisable(GL_LIGHTING);// Draw bulb model to show where the light source is// if(Scn_BulbModel!=NULL) { glPushMatrix(); Scn_BulbModel->Translation.X=Sh_Light.Position.X; Scn_BulbModel->Translation.Y=Sh_Light.Position.Y; Scn_BulbModel->Translation.Z=Sh_Light.Position.Z; E3d_ModelRefreshMatrices(Scn_BulbModel); E3d_DrawModel(Scn_BulbModel, FALSE, NULL, FALSE); glPopMatrix(); } glEnable(GL_LIGHTING); glDisable(GL_TEXTURE_2D);// Render blocker model// if(Scn_BlockerModel!=NULL) { glPushMatrix(); E3d_ModelRefreshMatrices(Scn_BlockerModel); E3d_DrawModel(Scn_BlockerModel, FALSE, NULL, FALSE); glPopMatrix(); }// Render receiver objects// if((LModel=Scn_ReceiverModel0)!=NULL) { glPushMatrix(); glBindTexture(GL_TEXTURE_2D, Sh_ShadowMapTexId); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable(GL_TEXTURE_2D); E3d_DrawModel(LModel, FALSE, &Sh_Light, Sh_BackFaceShadowElimination); glPopMatrix(); }// Draw table// if((LModel=Scn_ReceiverModel1)!=NULL) { glPushMatrix(); if((LMesh=(E3dMesh*)(LModel->Geometry))!=NULL) { LPolyGroup=LMesh->PolyGroups[0]; LMaterial=LPolyGroup->Material;// We will use lights in this pass// LMaterial->Type=E3dMAT_PHONG;// Set up wood texture// glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, Sh_WoodTexId); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T);// Just lighting and texture in this pass// LPolyGroup->ShadowPass=FALSE; E3d_DrawModel(LModel, TRUE, &Sh_Light, Sh_BackFaceShadowElimination); glPopMatrix();// Draw shadow pass of table// glPushMatrix();// No light calculations in this pass// LMaterial->Type=E3dMAT_CONSTANT; glEnable(GL_BLEND); glDisable(GL_LIGHTING);// We will use multiplicative blending here, so we can avoid// creating a separate white on black shadow-map// Result=SourceRGB*DestinationRGB// glBlendFunc(GL_DST_COLOR, GL_ZERO);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -