📄 radeondot3bump3dlight.cpp
字号:
}
}
//////////////////////////
// Draw the object
//////////////////////////
void drawObject(GLuint cubeFlag)
{
// Determine light position in object space.
GLfloat lp[3];
vecMatMult(lightpos, lightMat, lp);
// If we aren't doing wireframe then do each pass of the rendering.
if (!wireframe) {
// Render object. First pass for DOT3 bump mapping.
glDisable(GL_BLEND);
if (texturing < 5) {
bumpObject.computeLighting(lp, cubeFlag);
if (cubeFlag) {
Dot3CubeBump();
} else {
Dot3Bump();
}
bumpObject.renderObject(cubeFlag, 0);
}
// Render object. Second pass for 3D lightmapping.
if (texturing == 0) {
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
}
if ((texturing == 0) || (texturing == 5)) {
lightmap3D();
bumpObject.renderObject(cubeFlag, 1);
}
}
// Disable texture units so vectors and light appear correctly.
glDisable(GL_BLEND);
glDisable(GL_LIGHTING);
glActiveTexture(GL_TEXTURE0_ARB);
glMatrixMode(GL_TEXTURE);
glLoadIdentity ();
glMatrixMode(GL_MODELVIEW);
glDisable(GL_TEXTURE_3D_EXT);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glActiveTexture(GL_TEXTURE1_ARB);
glMatrixMode(GL_TEXTURE);
glLoadIdentity ();
glMatrixMode(GL_MODELVIEW);
glDisable(GL_TEXTURE_3D_EXT);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glActiveTexture(GL_TEXTURE2_ARB);
glMatrixMode(GL_TEXTURE);
glLoadIdentity ();
glMatrixMode(GL_MODELVIEW);
glDisable(GL_TEXTURE_3D_EXT);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glDisable(GL_TEXTURE_2D);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
// Show wireframe if desired.
if (wireframe) {
bumpObject.computeLighting(lp, cubeFlag);
glColor4fv (white);
glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
bumpObject.renderObject(GL_FALSE, 1);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
}
// Draw vectors and coordinate systems
if (showVectors || showTanCoord) {
glColor4fv (white);
bumpObject.renderVectors(scaleFactor*2.0f, showTanCoord, showVectors,
cubeFlag);
}
// Draw the light as a magenta sphere
static GLfloat lightcolor[] = { 1.0f, 0.0f, 1.0f, 1.0f };
glColor4fv (lightcolor);
static GLUquadricObj *sphere = NULL;
if (sphere == NULL) {
sphere = gluNewQuadric ();
}
glPushMatrix ();
glTranslatef (lp[0], lp[1], lp[2]);
gluSphere (sphere, (0.5f*scaleFactor), 10, 10);
glPopMatrix ();
// Draw the labeling text.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0f,1.0f,0.0f,1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glActiveTexture(GL_TEXTURE0_ARB);
glDisable(GL_TEXTURE_CUBE_MAP_ARB);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textID);
glColor4fv (white);
if (cubeFlag) {
flDrawString(0.01, 0.9, "With Cube Map Normalizer");
}
displayText(texturing);
}
//////////////////////////
// Scene drawing function
//////////////////////////
void
display(void) {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
// Viewport parameter calculation
int w = width/2;
int h = height;
// Setup first viewport
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, (double)w/(double)h, clipNear, clipFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLoadMatrixf(viewMat);
drawObject(GL_FALSE);
// Setup second viewport
glViewport(w,0,w,height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(fov, (double)w/(double)h, clipNear, clipFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLoadMatrixf(viewMat);
drawObject(GL_TRUE);
// Draw the dividing line.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0f,1.0f,0.0f,1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor4fv (white);
glBegin(GL_LINES);
glVertex3f (0.0f, 0.0f, 0.0f);
glVertex3f (0.0f, 1.0f, 0.0f);
glEnd();
// Finish up
glFinish ();
glutSwapBuffers();
}
//////////////////////////
// Projection and View Setup
///////////////////////////
void
MyReshape(int w,int h){
width = w;
height = h;
}
/////////////////////////////////////
// Generate the faces for the normalizer cubemap
/////////////////////////////////////
void
generateCubemap(void)
{
#define PackFloatInByte(in) (GLubyte) ((((in)+1.0f) / 2.0f) * 255.0f)
int x,y,z;
GLfloat mapSize = (GLfloat)CUBEMAP_TEX_SIZE;
GLfloat halfMapSize = (GLfloat)((int) (CUBEMAP_TEX_SIZE/2));
printf("Generating cubemap\n");
// Positive X face
for (y = 0; y < mapSize; y++) {
for (z = 0; z < mapSize; z++) {
GLfloat fX = (GLfloat) (halfMapSize);
GLfloat fY = (GLfloat) (halfMapSize - y);
GLfloat fZ = (GLfloat) (halfMapSize - z);
GLfloat oolen = 1.0f/sqrtf(fX*fX + fY*fY + fZ*fZ);
fX *= oolen; fY *= oolen; fZ *= oolen;
cubemapPX[y*3*CUBEMAP_TEX_SIZE + z*3 + 0] = PackFloatInByte(fX);
cubemapPX[y*3*CUBEMAP_TEX_SIZE + z*3 + 1] = PackFloatInByte(fY);
cubemapPX[y*3*CUBEMAP_TEX_SIZE + z*3 + 2] = PackFloatInByte(fZ);
}
}
// Negative X face
for (y = 0; y < mapSize; y++) {
for (z = 0; z < mapSize; z++) {
GLfloat fX = (GLfloat) (-halfMapSize);
GLfloat fY = (GLfloat) (halfMapSize - y);
GLfloat fZ = (GLfloat) (z - halfMapSize);
GLfloat oolen = 1.0f/sqrtf(fX*fX + fY*fY + fZ*fZ);
fX *= oolen; fY *= oolen; fZ *= oolen;
cubemapNX[y*3*CUBEMAP_TEX_SIZE + z*3 + 0] = PackFloatInByte(fX);
cubemapNX[y*3*CUBEMAP_TEX_SIZE + z*3 + 1] = PackFloatInByte(fY);
cubemapNX[y*3*CUBEMAP_TEX_SIZE + z*3 + 2] = PackFloatInByte(fZ);
}
}
// Positive Y face
for (z = 0; z < mapSize; z++) {
for (x = 0; x < mapSize; x++) {
GLfloat fX = (GLfloat) (x - halfMapSize);
GLfloat fY = (GLfloat) (halfMapSize);
GLfloat fZ = (GLfloat) (z - halfMapSize);
GLfloat oolen = 1.0f/sqrtf(fX*fX + fY*fY + fZ*fZ);
fX *= oolen; fY *= oolen; fZ *= oolen;
cubemapPY[z*3*CUBEMAP_TEX_SIZE + x*3 + 0] = PackFloatInByte(fX);
cubemapPY[z*3*CUBEMAP_TEX_SIZE + x*3 + 1] = PackFloatInByte(fY);
cubemapPY[z*3*CUBEMAP_TEX_SIZE + x*3 + 2] = PackFloatInByte(fZ);
}
}
// Negative Y face
for (z = 0; z < mapSize; z++) {
for (x = 0; x < mapSize; x++) {
GLfloat fX = (GLfloat) (x - halfMapSize);
GLfloat fY = (GLfloat) (-halfMapSize);
GLfloat fZ = (GLfloat) (halfMapSize - z);
GLfloat oolen = 1.0f/sqrtf(fX*fX + fY*fY + fZ*fZ);
fX *= oolen; fY *= oolen; fZ *= oolen;
cubemapNY[z*3*CUBEMAP_TEX_SIZE + x*3 + 0] = PackFloatInByte(fX);
cubemapNY[z*3*CUBEMAP_TEX_SIZE + x*3 + 1] = PackFloatInByte(fY);
cubemapNY[z*3*CUBEMAP_TEX_SIZE + x*3 + 2] = PackFloatInByte(fZ);
}
}
// Positive Z face
for (y = 0; y < mapSize; y++) {
for (x = 0; x < mapSize; x++) {
GLfloat fX = (GLfloat) (x - halfMapSize);
GLfloat fY = (GLfloat) (halfMapSize - y);
GLfloat fZ = (GLfloat) (halfMapSize);
GLfloat oolen = 1.0f/sqrtf(fX*fX + fY*fY + fZ*fZ);
fX *= oolen; fY *= oolen; fZ *= oolen;
cubemapPZ[y*3*CUBEMAP_TEX_SIZE + x*3 + 0] = PackFloatInByte(fX);
cubemapPZ[y*3*CUBEMAP_TEX_SIZE + x*3 + 1] = PackFloatInByte(fY);
cubemapPZ[y*3*CUBEMAP_TEX_SIZE + x*3 + 2] = PackFloatInByte(fZ);
}
}
// Negative Z face
for (y = 0; y < mapSize; y++) {
for (x = 0; x < mapSize; x++) {
GLfloat fX = (GLfloat) (halfMapSize - x);
GLfloat fY = (GLfloat) (halfMapSize - y);
GLfloat fZ = (GLfloat) (-halfMapSize);
GLfloat oolen = 1.0f/sqrtf(fX*fX + fY*fY + fZ*fZ);
fX *= oolen; fY *= oolen; fZ *= oolen;
cubemapNZ[y*3*CUBEMAP_TEX_SIZE + x*3 + 0] = PackFloatInByte(fX);
cubemapNZ[y*3*CUBEMAP_TEX_SIZE + x*3 + 1] = PackFloatInByte(fY);
cubemapNZ[y*3*CUBEMAP_TEX_SIZE + x*3 + 2] = PackFloatInByte(fZ);
}
}
// Setup texture environment and load cubemap.
glGenTextures(1, &cubemapID);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, cubemapID);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, 0, 3,
CUBEMAP_TEX_SIZE, CUBEMAP_TEX_SIZE, 0, GL_RGB,
GL_UNSIGNED_BYTE, cubemapPX);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, 0, 3,
CUBEMAP_TEX_SIZE, CUBEMAP_TEX_SIZE, 0, GL_RGB,
GL_UNSIGNED_BYTE, cubemapPY);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, 0, 3,
CUBEMAP_TEX_SIZE, CUBEMAP_TEX_SIZE, 0, GL_RGB,
GL_UNSIGNED_BYTE, cubemapPZ);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, 0, 3,
CUBEMAP_TEX_SIZE, CUBEMAP_TEX_SIZE, 0, GL_RGB,
GL_UNSIGNED_BYTE, cubemapNX);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, 0, 3,
CUBEMAP_TEX_SIZE, CUBEMAP_TEX_SIZE, 0, GL_RGB,
GL_UNSIGNED_BYTE, cubemapNY);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, 0, 3,
CUBEMAP_TEX_SIZE, CUBEMAP_TEX_SIZE, 0, GL_RGB,
GL_UNSIGNED_BYTE, cubemapNZ);
}
/////////////////////////////////////
// Generate the 3D lightmap. Note we only generate a quater of a sphere and
// use the mirror wrap mode to fill in the rest.
/////////////////////////////////////
void
generateLightmap3D(void)
{
// Generate the lightmap texture
printf("Generating lightmap\n");
#define SQ(A) ((A)*(A))
float rad = 63.0f;
float rad_sq = rad*rad;
for (int r = 0; r < SIZE_LIGHTMAP_3D; r++) {
for (int t = 0; t < SIZE_LIGHTMAP_3D; t++) {
for (int s = 0; s < SIZE_LIGHTMAP_3D; s++) {
float d_sq = SQ(r) + SQ(s) + SQ(t);
if (d_sq < rad_sq) {
float falloff = SQ((rad_sq - d_sq)/rad_sq);
lightmap[r*SIZE_LIGHTMAP_3D*SIZE_LIGHTMAP_3D*3 +
t*SIZE_LIGHTMAP_3D*3 + s*3 + 0] = (255.0f * falloff);
lightmap[r*SIZE_LIGHTMAP_3D*SIZE_LIGHTMAP_3D*3 +
t*SIZE_LIGHTMAP_3D*3 + s*3 + 1] = (255.0f * falloff);
lightmap[r*SIZE_LIGHTMAP_3D*SIZE_LIGHTMAP_3D*3 +
t*SIZE_LIGHTMAP_3D*3 + s*3 + 2] = (255.0f * falloff);
} else {
lightmap[r*SIZE_LIGHTMAP_3D*SIZE_LIGHTMAP_3D*3 +
t*SIZE_LIGHTMAP_3D*3 + s*3 + 0] = 0;
lightmap[r*SIZE_LIGHTMAP_3D*SIZE_LIGHTMAP_3D*3 +
t*SIZE_LIGHTMAP_3D*3 + s*3 + 1] = 0;
lightmap[r*SIZE_LIGHTMAP_3D*SIZE_LIGHTMAP_3D*3 +
t*SIZE_LIGHTMAP_3D*3 + s*3 + 2] = 0;
}
}
}
}
// Setup texture environment and load cubemap.
glGenTextures(NUM_LIGHTMAP_TEXTURES, lightmapID);
glBindTexture(GL_TEXTURE_3D_EXT, lightmapID[0]);
glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_S,
GL_MIRROR_CLAMP_TO_EDGE_ATI);
glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_T,
GL_MIRROR_CLAMP_TO_EDGE_ATI);
glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_R_EXT,
GL_MIRROR_CLAMP_TO_EDGE_ATI);
glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage3DEXT(GL_TEXTURE_3D_EXT, 0, 3,
SIZE_LIGHTMAP_3D, SIZE_LIGHTMAP_3D, SIZE_LIGHTMAP_3D,
0, GL_RGB, GL_UNSIGNED_BYTE, lightmap);
}
/////////////////////////////////////
// Setup GL textures.
/////////////////////////////////////
void
initTextures(void)
{
// Reference to global error message.
extern char gszErrMsg[];
gszErrMsg[0] = '\0';
// Initialize the text texture
printf("Loading: charset.tga\n");
glGenTextures(1, &textID);
charset = new ATI_GLTexture("charset.tga", textID,
GL_TRUE, GL_RGBA, GL_RGBA);
if (gszErrMsg[0] != '\0') printf(gszErrMsg);
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_MIPMAP_NEAREST);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glEnable(GL_TEXTURE_2D);
flSetWidth(1.0f/25.0f);
flSetHeight(1.0f/10.0f);
// Load the set of textures needed.
glGenTextures(NUM_DEMO_TEXTURES, textureID);
glGenTextures(NUM_DEMO_TEXTURES, textureDotID);
for (GLuint i=0; i < NUM_DEMO_TEXTURES; i++) {
// Load Base texture
gszErrMsg[0] = '\0';
printf("Loading: %s\n", textureName[i]);
texture[i] = new ATI_GLTexture(textureName[i], textureID[i],
GL_TRUE, GL_RGBA, GL_RGBA);
if (gszErrMsg[0] != '\0') printf("Error loading %s: %s\n",
textureName[i],gszErrMsg);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -