#include "mapviewer.h" using namespace std; GLubyte carcol1[] = { 234, 205, 81, 255 }; GLubyte carcol2[] = { 80, 40, 200, 255 }; GLubyte carcols[95][3] = {{5,5,5}, {245,245,245}, {42,119,161}, {132,4,16}, {38,55,57}, {134,68,110}, {255,182,16}, {76,117,183}, {189,190,198}, {94,112,114}, {49,0,0}, {90,33,36}, {132,4,16}, {99,50,46}, {181,20,0}, {138,58,66}, {100,13,26}, {139,60,68}, {158,47,43}, {163,58,47}, {210,86,51}, {146,86,53}, {184,124,38}, {211,87,51}, {226,90,89}, {119,42,37}, {225,119,67}, {196,70,54}, {225,120,68}, {195,89,56}, {70,72,64}, {116,119,97}, {117,119,99}, {145,138,61}, {148,140,102}, {255,156,16}, {216,165,52}, {201,189,125}, {201,197,145}, {212,200,78}, {26,51,46}, {36,47,43}, {29,55,63}, {60,74,59}, {45,80,55}, {82,105,82}, {45,104,62}, {124,162,130}, {76,82,78}, {86,119,91}, {16,20,80}, {72,94,132}, {28,39,69}, {28,55,111}, {43,72,120}, {71,92,131}, {68,124,146}, {61,103,171}, {75,125,130}, {128,176,183}, {61,35,51}, {28,41,72}, {52,57,65}, {64,69,76}, {74,45,43}, {86,62,51}, {65,70,76}, {103,39,49}, {131,90,117}, {134,133,135}, {23,23,23}, {46,46,46}, {69,69,69}, {92,92,92}, {115,115,115}, {138,138,138}, {161,161,161}, {184,184,184}, {207,207,207}, {222,223,231}, {170,175,170}, {106,115,107}, {170,175,170}, {187,190,181}, {224,223,214}, {106,111,112}, {96,99,95}, {106,115,107}, {170,175,170}, {187,190,181}, {33,41,43}, {52,56,66}, {65,70,72}, {78,89,96}, {65,69,76}}; int carcol1ind, carcol2ind; void CWorldObj::DrawGeometry(RpGeometry &g, bool DrawTransp) { RwUInt32 i, j, k; bool isTransparent; RpMesh *s; bool hasAlpha; bool mixColors; Vector3f *vert, *norm; Vector2f *uv; Color4b *color1; Color4b *color2; // Color4b *newcolor; RwUInt8 *meshcol; Color4b avcolor; color Amb; avcolor[3] = 255; for (j = 0; j < g.numSplits; j++) { s = &g.Split[j]; vert = g.Vertex; norm = g.Normal; uv = g.UV; if (g.NightVColor != NULL) { if (Clock.GetHour() < 21 && Clock.GetHour() >= 20) { mixColors = true; color1 = g.VColor; color2 = g.NightVColor; } else if (Clock.GetHour() >=5 && Clock.GetHour()<6) { mixColors = true; color1 = g.NightVColor; color2 = g.VColor; } else if (Clock.GetHour() >=21 || Clock.GetHour()<5) { mixColors = false; color1 = g.NightVColor; color2 = g.NightVColor; } else { mixColors = false; color1 = g.VColor; color2 = g.VColor; } } else { mixColors = false; color1 = g.VColor; color2 = g.VColor; } isTransparent = false; if (GLView.UseTextures()) { glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); /* if there is a diffuse map, use it */ if (g.Mat[s->MatIndex].HasTex) { hasAlpha = BindTexture(g.Mat[s->MatIndex].Tex.Name); if (hasAlpha) isTransparent = true; } /* if there is a reflection map, use it */ if (g.Mat[s->MatIndex].HasRef) { glActiveTexture(GL_TEXTURE1); BindTexture(g.Mat[s->MatIndex].Reflection.Name); glActiveTexture(GL_TEXTURE0); } } else { glBindTexture(GL_TEXTURE_2D, 0); } glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); if (g.Mat[s->MatIndex].Color[3] != 255) isTransparent = true; if (DrawTransp != isTransparent) continue; if (isTransparent) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glAlphaFunc(GL_GREATER, 0.0); } else { glDisable(GL_BLEND); } if (g.Mat[s->MatIndex].Color[0] == 60 && g.Mat[s->MatIndex].Color[1] == 255 && g.Mat[s->MatIndex].Color[2] == 0) // meshcol = carcol1; meshcol = carcols[carcol1ind]; else if (g.Mat[s->MatIndex].Color[0] == 255 && g.Mat[s->MatIndex].Color[1] == 0 && g.Mat[s->MatIndex].Color[2] == 175) // meshcol = carcol2; meshcol = carcols[carcol2ind]; else meshcol = g.Mat[s->MatIndex].Color; glColor4ubv(meshcol); #if 0 // Vertex arrays aren't faster /* Mix colors and vertex colors */ if (g.Flags & rpGEOMETRYPRELIT && UseVertexColors) { newcolor = new Color4b[g.numVertices]; for (k = 0; k < s->numIndices; k++) { GLfloat tmpcolor[4]; i = s->Indices[k]; if (mixColors) { MixColors(avcolor, color1[i], color2[i], 60-Clock.GetMinute(), 60); } else { avcolor[0] = color1[i][0]; avcolor[1] = color1[i][1]; avcolor[2] = color1[i][2]; avcolor[3] = color1[i][3]; } Sky.GetAmb(Amb); tmpcolor[0] =(int)(((int)Amb[0]+(int)avcolor[0])%256); tmpcolor[1] =(int)(((int)Amb[1]+(int)avcolor[1])%256); tmpcolor[2] =(int)(((int)Amb[2]+(int)avcolor[2])%256); tmpcolor[3] = avcolor[3]; newcolor[i][0] = tmpcolor[0]; newcolor[i][1] = tmpcolor[1]; newcolor[i][2] = tmpcolor[2]; newcolor[i][3] = tmpcolor[3]; } } /* Draw everything */ glEnableClientState(GL_VERTEX_ARRAY); if (g.Flags & rpGEOMETRYNORMALS) glEnableClientState(GL_NORMAL_ARRAY); if (g.Flags & rpGEOMETRYPRELIT && UseVertexColors) glEnableClientState(GL_COLOR_ARRAY); if ((g.Flags & rpGEOMETRYTEXTURED) || (g.Flags & rpGEOMETRYTEXTURED2)) glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3, GL_FLOAT, 0, vert); glNormalPointer(GL_FLOAT, 0, norm); glColorPointer(4, GL_UNSIGNED_BYTE, 0, newcolor); glTexCoordPointer(2, GL_FLOAT, 0, uv); if (g.FaceType == 1) glDrawElements(GL_TRIANGLE_STRIP, s->numIndices, GL_UNSIGNED_INT, s->Indices); else glDrawElements(GL_TRIANGLES, s->numIndices, GL_UNSIGNED_INT, s->Indices); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); delete[] newcolor; #endif if (g.FaceType == 1) glBegin(GL_TRIANGLE_STRIP); else glBegin(GL_TRIANGLES); for (k = 0; k < s->numIndices; k++) { i = s->Indices[k]; if ((g.Flags & rpGEOMETRYTEXTURED) || (g.Flags & rpGEOMETRYTEXTURED2)) glMultiTexCoord2fv(GL_TEXTURE0, uv[i]); if (g.Flags & rpGEOMETRYPRELIT && GLView.UseVertexColors()) { GLfloat tmpcolor[4]; if (mixColors) { MixColors(avcolor, color1[i], color2[i], 60-Clock.GetMinute(), 60); } else { avcolor[0] = color1[i][0]; avcolor[1] = color1[i][1]; avcolor[2] = color1[i][2]; avcolor[3] = color1[i][3]; } if (ViewMode == GAME) { Sky.GetAmb(Amb); } else { Amb[0] = 100; Amb[1] = 100; Amb[2] = 100; } tmpcolor[0] =(GLfloat)(Amb[0]+avcolor[0])/255.0; tmpcolor[1] =(GLfloat)(Amb[1]+avcolor[1])/255.0; tmpcolor[2] =(GLfloat)(Amb[2]+avcolor[2])/255.0; tmpcolor[3] = 1.0; /* tmpcolor[0] = avcolor[0]; tmpcolor[1] = avcolor[1]; tmpcolor[2] = avcolor[2]; tmpcolor[3] = avcolor[3]; */ glColor4fv(tmpcolor); } if (g.Flags & rpGEOMETRYNORMALS) glNormal3fv(norm[i]); glVertex3fv(vert[i]); } glEnd(); } } void CWorldObj::Draw(bool DoTransformation, int atomic, bool DrawTransp) { RwInt32 g, f; if (ObjCount > Clump->numAtomics) return; /* This is rather crude, but it works for the railtrax in portland */ g = Clump->Atm[ObjCount-1-atomic].GeoIndex; f = Clump->Atm[ObjCount-1-atomic].FrmIndex; if (strcmp(Clump->Frm[f].Name, "chassis_vlo") == 0) return; if (strstr(Clump->Frm[f].Name, "_dam") != NULL) return; glPushMatrix(); if (DoTransformation) TransformFrame(Clump->Frm, f); DrawGeometry(Clump->Geo[g], DrawTransp); glPopMatrix(); } void CWorldObj::TransformFrame(RwFrame *f, RwInt32 which) { GLfloat transmat[16]; if (f[which].Parent != -1) TransformFrame(f, f[which].Parent); transmat[0] = f[which].Rotation[0][0]; transmat[1] = f[which].Rotation[0][1]; transmat[2] = f[which].Rotation[0][2]; transmat[3] = 0; transmat[4] = f[which].Rotation[1][0]; transmat[5] = f[which].Rotation[1][1]; transmat[6] = f[which].Rotation[1][2]; transmat[7] = 0; transmat[8] = f[which].Rotation[2][0]; transmat[9] = f[which].Rotation[2][1]; transmat[10] = f[which].Rotation[2][2]; transmat[11] = 0; transmat[12] = f[which].Position[0]; transmat[13] = f[which].Position[1]; transmat[14] = f[which].Position[2]; transmat[15] = 1; glMultMatrixf(transmat); } /* void CWorldObj::SetClump(RpClump *c) { Clump = c; } RpClump *CWorldObj::GetClump() { return Clump; } */