#include "mapviewer.h" using namespace std; void CWater::Init() { if ((Game.GetVersion() & GAMESANANDREAS) == 0) ReadWaterData(); } void CWater::DrawPatch(float x, float y, float patchsize, float height) { glBegin(GL_QUADS); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f); glVertex3f(x, y, height); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 1.0f); glVertex3f(x+patchsize, y, height); glMultiTexCoord2f(GL_TEXTURE0, 1.0f, 1.0f); glVertex3f(x+patchsize, y+patchsize, height); glMultiTexCoord2f(GL_TEXTURE0, 1.0f, 0.0f); glVertex3f(x, y+patchsize, height); glEnd(); } void CWater::Draw() { int x, y; float patchsize; color watercolor; GLfloat lim[4]; GLfloat height; if (!GLView.UseTextures()) return; patchsize = 32; Game.GetWorldLimits(lim); glColor3ub(67, 65, 100); if ((Game.GetVersion() & GAMEVICECITY) != 0) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); BindTextureFromTxd("waterclear256", "PARTICLE"); Sky.GetWaterColor(watercolor); glColor4ubv(watercolor); } else if ((Game.GetVersion() & GAMEIII) != 0) { BindTextureFromTxd("water_old", "PARTICLE"); glColor4ub(255, 255, 255, 255); } for (x = 0; x < 128; x++) { for (y = 0; y < 128; y++) { if (indiceshi[x*128+y] != 0x80) DrawPatch(x*patchsize+lim[0], y*patchsize+lim[1], patchsize, palette[indiceshi[x*128+y]]); } } /* Draw outer water areas */ glDisable(GL_BLEND); height = palette[indiceshi[0]]; /* Western water patch */ glBegin(GL_QUADS); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f); glVertex3f(lim[0]-2048, lim[1]-2048, height); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 2048/patchsize); glVertex3f(lim[0], lim[1]-2048, height); glMultiTexCoord2f(GL_TEXTURE0, ((lim[3]+2048)-(lim[1]-2048))/patchsize, 2048/patchsize); glVertex3f(lim[0], lim[3]+2048, height); glMultiTexCoord2f(GL_TEXTURE0, ((lim[3]+2048)-(lim[1]-2048))/patchsize, 0); glVertex3f(lim[0]-2048, lim[3]+2048, height); glEnd(); /* Eastern water patch */ glBegin(GL_QUADS); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f); glVertex3f(lim[2], lim[1]-2048, height); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 2048/patchsize); glVertex3f(lim[2]+2048, lim[1]-2048, height); glMultiTexCoord2f(GL_TEXTURE0, ((lim[3]+2048)-(lim[1]-2048))/patchsize, 2048/patchsize); glVertex3f(lim[2]+2048, lim[3]+2048, height); glMultiTexCoord2f(GL_TEXTURE0, ((lim[3]+2048)-(lim[1]-2048))/patchsize, 0); glVertex3f(lim[2], lim[3]+2048, height); glEnd(); /* Southern water patch */ glBegin(GL_QUADS); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f); glVertex3f(lim[0], lim[1]-2048, height); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, (lim[2]-lim[0])/patchsize); glVertex3f(lim[2], lim[1]-2048, height); glMultiTexCoord2f(GL_TEXTURE0, 2048/patchsize, (lim[2]-lim[0])/patchsize); glVertex3f(lim[2], lim[1], height); glMultiTexCoord2f(GL_TEXTURE0, 2048/patchsize, 0.0f); glVertex3f(lim[0], lim[1], height); glEnd(); /* Northern water patch */ glBegin(GL_QUADS); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, 0.0f); glVertex3f(lim[0], lim[3], height); glMultiTexCoord2f(GL_TEXTURE0, 0.0f, (lim[2]-lim[0])/patchsize); glVertex3f(lim[2], lim[3], height); glMultiTexCoord2f(GL_TEXTURE0, 2048/patchsize, (lim[2]-lim[0])/patchsize); glVertex3f(lim[2], lim[3]+2048, height); glMultiTexCoord2f(GL_TEXTURE0, 2048/patchsize, 0.0f); glVertex3f(lim[0], lim[3]+2048, height); glEnd(); glEnable(GL_BLEND); } void CWater::ReadWaterData() { int i; byte image[128*128*4]; byte colpal[48][4]; FILE *wpro; wpro = efopen("DATA/WATERPRO.DAT", "rb"); fseek(wpro, 4, SEEK_SET); if (fread(&palette, 4, 48, wpro) != 48) exiterror("Error in file", "waterpro.dat"); fseek(wpro, 0x300, SEEK_CUR); if (fread(&indiceslo, 1, 64*64, wpro) != 64*64) exiterror("Error in file", "waterpro.dat"); if (fread(&indiceshi, 1, 128*128, wpro) != 128*128) exiterror("Error in file", "waterpro.dat"); fclose(wpro); memcpy(colpal, palette, 48*4); for (i = 0; i < 128*128; i++) { if (indiceshi[i] == 0x80) { image[i*4] = 255; image[i*4+1] = 255; image[i*4+2] = 255; image[i*4+3] = 255; } else { image[i*4] = colpal[indiceshi[i]][0]; image[i*4+1] = colpal[indiceshi[i]][1]; image[i*4+2] = colpal[indiceshi[i]][2]; image[i*4+3] = 255; } } glGenTextures(1, &TexID); glBindTexture(GL_TEXTURE_2D, TexID); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 128, 128, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); }