advsky.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 859 行 · 第 1/2 页
CPP
859 行
}
}
bx++;
}
}
for(int a=0;a<CLOUD_SIZE*CLOUD_SIZE;a++){
cloudThickness2[a]=alphaTransform[rawClouds[0][a]>>7];
}
cloudThickness2[CLOUD_SIZE*CLOUD_SIZE]=cloudThickness2[CLOUD_SIZE*CLOUD_SIZE-1]; //this one is read in one place, so to avoid reading uninitialized mem ...
//create the cloud shading
int ydif[CLOUD_SIZE];
for(int a=0;a<CLOUD_SIZE;++a){
ydif[a]=0;
ydif[a]+=cloudThickness2[(a+3*CLOUD_SIZE)];
ydif[a]+=cloudThickness2[(a+2*CLOUD_SIZE)];
ydif[a]+=cloudThickness2[(a+1*CLOUD_SIZE)];
ydif[a]+=cloudThickness2[(a+0*CLOUD_SIZE)];
ydif[a]-=cloudThickness2[(a-1*CLOUD_SIZE+CLOUD_SIZE*CLOUD_SIZE)];
ydif[a]-=cloudThickness2[(a-2*CLOUD_SIZE+CLOUD_SIZE*CLOUD_SIZE)];
ydif[a]-=cloudThickness2[(a-3*CLOUD_SIZE+CLOUD_SIZE*CLOUD_SIZE)];
}
int b=0;
ydif[(b)&255]+=cloudThickness2[(b-3*CLOUD_SIZE+CLOUD_SIZE*CLOUD_SIZE)];
ydif[(b)&255]-=cloudThickness2[(b)]*2;
ydif[(b)&255]+=cloudThickness2[(b+4*CLOUD_SIZE)];
for(int a=0;a<CLOUD_SIZE*3-1;a++){
ydif[(a+1)&255]+=cloudThickness2[(a-3*CLOUD_SIZE+1+CLOUD_SIZE*CLOUD_SIZE)];
ydif[(a+1)&255]-=cloudThickness2[(a+1)]*2;
ydif[(a+1)&255]+=cloudThickness2[(a+4*CLOUD_SIZE+1)];
int dif=0;
dif+=ydif[(a)&255];
dif+=ydif[(a+1)&255]>>1;
dif+=ydif[(a-1)&255]>>1;
dif+=ydif[(a+2)&255]>>2;
dif+=ydif[(a-2)&255]>>2;
dif/=16;
cloudTexMem[a*4+0]=128+dif;
cloudTexMem[a*4+1]=thicknessTransform[rawClouds[0][a]>>7];
cloudTexMem[a*4+2]=255;
}
for(int a=CLOUD_SIZE*3-1;a<CLOUD_SIZE*CLOUD_SIZE-CLOUD_SIZE*4-1;a++){
ydif[(a+1)&255]+=cloudThickness2[(a-3*CLOUD_SIZE+1)];
ydif[(a+1)&255]-=cloudThickness2[(a+1)]*2;
ydif[(a+1)&255]+=cloudThickness2[(a+4*CLOUD_SIZE+1)];
int dif=0;
dif+=ydif[(a)&255];
dif+=ydif[(a+1)&255]>>1;
dif+=ydif[(a-1)&255]>>1;
dif+=ydif[(a+2)&255]>>2;
dif+=ydif[(a-2)&255]>>2;
dif/=16;
cloudTexMem[a*4+0]=128+dif;
cloudTexMem[a*4+1]=thicknessTransform[rawClouds[0][a]>>7];
cloudTexMem[a*4+2]=255;
}
for(int a=CLOUD_SIZE*CLOUD_SIZE-CLOUD_SIZE*4-1;a<CLOUD_SIZE*CLOUD_SIZE;a++){
ydif[(a+1)&255]+=cloudThickness2[(a-3*CLOUD_SIZE+1)];
ydif[(a+1)&255]-=cloudThickness2[(a+1)]*2;
ydif[(a+1)&255]+=cloudThickness2[(a+4*CLOUD_SIZE+1-CLOUD_SIZE*CLOUD_SIZE)];
int dif=0;
dif+=ydif[(a)&255];
dif+=ydif[(a+1)&255]>>1;
dif+=ydif[(a-1)&255]>>1;
dif+=ydif[(a+2)&255]>>2;
dif+=ydif[(a-2)&255]>>2;
dif/=16;
cloudTexMem[a*4+0]=128+dif;
cloudTexMem[a*4+1]=thicknessTransform[rawClouds[0][a]>>7];
cloudTexMem[a*4+2]=255;
}
int modDensity=(int) ((1-cloudDensity)*256);
for(int a=0;a<CLOUD_SIZE*CLOUD_SIZE;a++){
int f=(rawClouds[0][a]>>8)-modDensity;
if(f<0)
f=0;
if(f>255)
f=255;
cloudTexMem[a*4+3]=f;
}
delete[] rawClouds;
glBindTexture(GL_TEXTURE_2D, cloudDot3Tex);
glTexSubImage2D(GL_TEXTURE_2D,0, 0,0,CLOUD_SIZE, CLOUD_SIZE,GL_RGBA, GL_UNSIGNED_BYTE, cloudTexMem);
}
}
void CAdvSky::CreateRandMatrix(int matrix[32][32],float mod)
{
for(int y=0;y<32;y++){
for(int x=0;x<32;x++){
float r = ((float)( rand() )) / (float)RAND_MAX;
matrix[y][x]=((int)(r * 255.0f));
}
}
}
void CAdvSky::CreateRandDetailMatrix(unsigned char* matrix,int size)
{
for(int a=0;a<size*size;a++){
float r = ((float)( rand() )) / (float)RAND_MAX;
matrix[a]=((int)(r * 255.0f));
}
}
void CAdvSky::CreateTransformVectors()
{
for(int a=0;a<1024;++a){
float f=(1023.0f-(a+cloudDensity*1024-512))/1023.0f;
float alpha=pow(f*2,3);
if(alpha>1)
alpha=1;
alphaTransform[a]=(int) (alpha*255);
float d=f*2;
if(d>1)
d=1;
thicknessTransform[a]=(unsigned char) (128+d*64+alphaTransform[a]*255/(4*255));
}
}
void CAdvSky::DrawSun()
{
glPushMatrix();
CMatrix44f m(camera->pos,sundir1,UpVector,sundir2);
glMultMatrixf(m.m);
glDisable(GL_DEPTH_TEST);
glDisable(GL_ALPHA_TEST);
unsigned char buf[128];
glEnable(GL_TEXTURE_2D);
float3 modCamera=sundir1*camera->pos.x+sundir2*camera->pos.z;
float ymod=(sunTexCoordY-0.5f)*domeWidth*0.025f*256;
float fy=ymod+modCamera.z*CLOUD_SIZE*0.000025f;
int baseY=int(floor(fy))&CLOUD_MASK;
fy-=floor(fy);
float fx=gs->frameNum*0.00005f*CLOUD_SIZE+modCamera.x*CLOUD_SIZE*0.000025f;
int baseX=int(floor(fx))&CLOUD_MASK;
fx-=floor(fx);
if(baseX!=oldCoverBaseX || baseY!=oldCoverBaseY){
oldCoverBaseX=baseX;
oldCoverBaseY=baseY;
CreateCover(baseX,baseY,covers[0]);
CreateCover(baseX+1,baseY,covers[1]);
CreateCover(baseX,baseY+1,covers[2]);
CreateCover(baseX+1,baseY+1,covers[3]);
}
float mid=0;
for(int x=0;x<32;++x){
float cx1=covers[0][x]*(1-fx)+covers[1][x]*fx;
float cx2=covers[2][x]*(1-fx)+covers[3][x]*fx;
float cover=cx1*(1-fy)+cx2*fy;
if(cover>127.5f)
cover=127.5f;
mid+=cover;
buf[x+32]=(unsigned char)(255-cover*2);
buf[x+64]=(unsigned char)(128-cover);
}
mid*=1.0f/32;
for(int x=0;x<32;++x){
buf[x]=(unsigned char)(255-mid*2);
}
glBindTexture(GL_TEXTURE_2D, sunFlareTex);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,32,3,GL_LUMINANCE,GL_UNSIGNED_BYTE,buf);
glColor4f(0.4f*sunColor.x,0.4f*sunColor.y,0.4f*sunColor.z,0.0f);
glCallList(sunFlareList);
glEnable(GL_DEPTH_TEST);
glPopMatrix();
}
void CAdvSky::SetCloudShadow(int texunit)
{
}
void CAdvSky::ResetCloudShadow(int texunit)
{
}
void CAdvSky::DrawShafts()
{
}
void CAdvSky::InitSun()
{
unsigned char* mem=SAFE_NEW unsigned char[128*128*4];
for(int y=0;y<128;++y){
for(int x=0;x<128;++x){
mem[(y*128+x)*4+0]=255;
mem[(y*128+x)*4+1]=255;
mem[(y*128+x)*4+2]=255;
float dist=sqrt((float)(y-64)*(y-64)+(x-64)*(x-64));
if(dist>60)
mem[(y*128+x)*4+3]=0;
else
mem[(y*128+x)*4+3]=255;
}
}
glGenTextures(1, &sunTex);
glBindTexture(GL_TEXTURE_2D, sunTex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA8 ,128, 128, GL_RGBA, GL_UNSIGNED_BYTE, mem);
for(int y=0;y<4;++y){
for(int x=0;x<32;++x){
if(y==0 && x%2)
mem[(y*32+x)]=255;
else
mem[(y*32+x)]=0;
}
}
glGenTextures(1, &sunFlareTex);
glBindTexture(GL_TEXTURE_2D, sunFlareTex);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
// gluBuild2DMipmaps(GL_TEXTURE_2D,1 ,32, 2, GL_ALPHA, GL_UNSIGNED_BYTE, mem);
glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE ,32, 4,0, GL_LUMINANCE, GL_UNSIGNED_BYTE, mem);
delete[] mem;
float3 ldir=modSunDir.cross(UpVector);
ldir.Normalize();
float3 udir=modSunDir.cross(ldir);
sunFlareList=glGenLists(1);
glNewList(sunFlareList, GL_COMPILE);
glDisable(GL_FOG);
glBindTexture(GL_TEXTURE_2D, sunFlareTex);
glBlendFunc(GL_ONE_MINUS_DST_COLOR,GL_ONE);
glBegin(GL_TRIANGLE_STRIP);
for(int x=0;x<257;++x){
float dx=sin(x*2*PI/256.0f);
float dy=cos(x*2*PI/256.0f);
glTexCoord2f(x/256.0f,0.125f);
glVertexf3(modSunDir*5+ldir*dx*0.0014f+udir*dy*0.0014f);
glTexCoord2f(x/256.0f,0.875f);
glVertexf3(modSunDir*5+ldir*dx*4+udir*dy*4);
}
glEnd();
if (gu->drawFog) glEnable(GL_FOG);
glEndList();
}
void CAdvSky::CreateCover(int baseX, int baseY, float *buf)
{
static const int line[]={
5, 0, 1, 0, 2, 0, 3, 0, 4, 0, 5,
5, 0, 1, 0, 2, 1, 3, 1, 4, 1, 5,
5, 0, 1, 1, 2, 1, 3, 2, 4, 2, 5,
4, 1, 1, 2, 2, 2, 3, 3, 4,
4, 1, 1, 2, 2, 3, 3, 4, 4,
4, 1, 1, 2, 2, 3, 2, 4, 3,
5, 1, 0, 2, 1, 3, 1, 4, 2, 5, 2,
5, 1, 0, 2, 0, 3, 1, 4, 1, 5, 1
};
int i=0;
for(int l=0;l<8;++l){
int num=line[i++];
int cover1=0;
int cover2=0;
int cover3=0;
int cover4=0;
float total=0;
for(int x=0;x<num;++x){
int dx=line[i++];
int dy=line[i++];
int incy = ((baseY+dy) & CLOUD_MASK) * CLOUD_SIZE;
int decy = ((baseY-dy) & CLOUD_MASK) * CLOUD_SIZE;
int incx = (baseX+dx) & CLOUD_MASK;
int decx = (baseX-dx) & CLOUD_MASK;
cover1+=255-cloudThickness2[incy+decx];//*(num-x);
cover2+=255-cloudThickness2[decy+decx];//*(num-x);
cover3+=255-cloudThickness2[decy+incx];//*(num-x);
cover4+=255-cloudThickness2[incy+incx];//*(num-x);
total+=1;//(num-x);
}
buf[l]=cover1/total;
buf[l+8]=cover2/total;
buf[l+16]=cover3/total;
buf[l+24]=cover4/total;
}
}
void CAdvSky::CreateDetailTex(void)
{
glViewport(0,0,256,256);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,1,0,1,-1,1);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_FOG);
glDisable(GL_LIGHTING);
glEnable(GL_TEXTURE_2D);
glClearColor(0,0,0,0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
glDisable(GL_DEPTH_TEST);
unsigned char randDetailMatrix[32*32];
for(int a=0;a<5;++a){
float fade=(gs->frameNum/float(30<<a));
fade-=floor(fade/2)*2;
int size=min(32,256>>a);
if(fade>1){
fade=2-fade;
if(!cloudDetailDown[a]){
cloudDetailDown[a]=true;
CreateRandDetailMatrix(randDetailMatrix,size);
glBindTexture(GL_TEXTURE_2D, detailTextures[a+6]);
glTexSubImage2D(GL_TEXTURE_2D,0, 0,0,size, size, GL_LUMINANCE, GL_UNSIGNED_BYTE, randDetailMatrix);
}
} else {
if(cloudDetailDown[a]){
cloudDetailDown[a]=false;
CreateRandDetailMatrix(randDetailMatrix,size);
glBindTexture(GL_TEXTURE_2D, detailTextures[a]);
glTexSubImage2D(GL_TEXTURE_2D,0, 0,0,size, size, GL_LUMINANCE, GL_UNSIGNED_BYTE, randDetailMatrix);
}
}
float tSize=max(1,8>>a);
float c=pow(2.0f,a)*6/255.0f;
// logOutput.Print("%f",c);
CVertexArray* va=GetVertexArray();
va->Initialize();
va->AddVertexT(ZeroVector,0,0);
va->AddVertexT(float3(1,0,0),tSize,0);
va->AddVertexT(float3(1,1,0),tSize,tSize);
va->AddVertexT(UpVector,0,tSize);
float ifade=(3*fade*fade-2*fade*fade*fade);
glBindTexture(GL_TEXTURE_2D, detailTextures[a+6]);
glColor4f(c,c,c,1-ifade);
va->DrawArrayT(GL_QUADS);
glBindTexture(GL_TEXTURE_2D, detailTextures[a]);
glColor4f(c,c,c,ifade);
va->DrawArrayT(GL_QUADS);
}
/* unsigned char buf[256*256*4];
glReadPixels(0,0,256,256,GL_RGBA,GL_UNSIGNED_BYTE,buf);
CBitmap bm(buf,256,256);
bm.Save("dc.bmp");
*/
glBindTexture(GL_TEXTURE_2D, cdtex);
glCopyTexSubImage2D(GL_TEXTURE_2D,0,0,0,0,0,256,256);
// SwapBuffers(hDC);
// SleepEx(500,true);
glViewport(gu->viewPosX,0,gu->viewSizeX,gu->viewSizeY);
glEnable(GL_DEPTH_TEST);
}
float3 CAdvSky::GetDirFromTexCoord(float x, float y)
{
float3 dir;
dir.x=(x-0.5f)*domeWidth;
dir.z=(y-0.5f)*domeWidth;
float hdist=sqrt(dir.x*dir.x+dir.z*dir.z);
float fy=asin(hdist/400);
dir.y=(cos(fy)-domeheight)*400;
dir.Normalize();
return dir;
}
//should be improved
//only take stuff in yz plane
float CAdvSky::GetTexCoordFromDir(float3 dir)
{
float tp=0.5f;
float step=0.25f;
for(int a=0;a<10;++a){
float tx=0.5f+tp;
float3 d=GetDirFromTexCoord(tx,0.5f);
if(d.y<dir.y)
tp-=step;
else
tp+=step;
step*=0.5f;
}
return 0.5f+tp;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?