basicsky.cpp
来自「这是整套横扫千军3D版游戏的源码」· C++ 代码 · 共 809 行 · 第 1/2 页
CPP
809 行
}
}
int ifade=(int)((3*fade*fade-2*fade*fade*fade)*256);
for(int y=0;y<32;y++){
for(int x=0;x<32;x++){
blendMatrix[a][y][x]=(randMatrix[a][y][x]*ifade+randMatrix[a+8][y][x]*(256-ifade))>>8;
}
}
}
int rawClouds[CLOUD_SIZE][CLOUD_SIZE];//=SAFE_NEW int[CLOUD_SIZE][CLOUD_SIZE];
for(int a=0;a<CLOUD_SIZE*CLOUD_SIZE;a++){
rawClouds[0][a]=0;
}
int kernel[CLOUD_SIZE/4*CLOUD_SIZE/4];
for(int a=0;a<CLOUD_DETAIL;a++){
for(int y=0;y<(CLOUD_SIZE/4)>>a;++y){
float ydist=fabs((float)1+y-((CLOUD_SIZE/8)>>a))/((CLOUD_SIZE/8)>>a);
ydist=3*ydist*ydist-2*ydist*ydist*ydist;
for(int x=0;x<(CLOUD_SIZE/4)>>a;++x){
float xdist=fabs((float)1+x-((CLOUD_SIZE/8)>>a))/((CLOUD_SIZE/8)>>a);
xdist=3*xdist*xdist-2*xdist*xdist*xdist;
float contrib=(1-xdist)*(1-ydist);
kernel[y*CLOUD_SIZE/4+x]=(int)( contrib*((4<<CLOUD_DETAIL)>>a));
}
}
unsigned int by=0,bx=0;
for(int y=0;y<CLOUD_SIZE-((CLOUD_SIZE/8)>>a);y+=(CLOUD_SIZE/8)>>a){
for(int x=0;x<CLOUD_SIZE-((CLOUD_SIZE/8)>>a);x+=(CLOUD_SIZE/8)>>a){
int blend=blendMatrix[a][by&31][bx&31];
for(int y2=0;y2<((CLOUD_SIZE/4)>>a)-1;++y2){
for(int x2=0;x2<((CLOUD_SIZE/4)>>a)-1;++x2){
rawClouds[y+y2][x+x2]+=blend*kernel[y2*CLOUD_SIZE/4+x2];
}
}
bx++;
}
by++;
}
by=0;
bx=31;
for(int y=0;y<CLOUD_SIZE-((CLOUD_SIZE/8)>>a);y+=(CLOUD_SIZE/8)>>a){
int x=CLOUD_SIZE-((CLOUD_SIZE/8)>>a);
int blend=blendMatrix[a][by&31][bx&31];
for(int y2=0;y2<((CLOUD_SIZE/4)>>a)-1;++y2){
for(int x2=0;x2<((CLOUD_SIZE/4)>>a)-1;++x2){
if(x+x2<CLOUD_SIZE)
rawClouds[y+y2][x+x2]+=blend*kernel[y2*CLOUD_SIZE/4+x2];
else
rawClouds[y+y2][x+x2-CLOUD_SIZE]+=blend*kernel[y2*CLOUD_SIZE/4+x2];
}
}
by++;
}
bx=0;
by=31;
for(int x=0;x<CLOUD_SIZE-((CLOUD_SIZE/8)>>a);x+=(CLOUD_SIZE/8)>>a){
int y=CLOUD_SIZE-((CLOUD_SIZE/8)>>a);
int blend=blendMatrix[a][by&31][bx&31];
for(int y2=0;y2<((CLOUD_SIZE/4)>>a)-1;++y2){
for(int x2=0;x2<((CLOUD_SIZE/4)>>a)-1;++x2){
if(y+y2<CLOUD_SIZE)
rawClouds[y+y2][x+x2]+=blend*kernel[y2*CLOUD_SIZE/4+x2];
else
rawClouds[y+y2-CLOUD_SIZE][x+x2]+=blend*kernel[y2*CLOUD_SIZE/4+x2];
}
}
bx++;
}
}
for(int a=0;a<CLOUD_SIZE*CLOUD_SIZE;a++){
cloudThickness[a*4+3]=alphaTransform[rawClouds[0][a]>>7];
}
cloudThickness[CLOUD_SIZE*CLOUD_SIZE*4+3]=alphaTransform[rawClouds[0][0]>>7];
// next line unused
cloudThickness[CLOUD_SIZE*CLOUD_SIZE*4+0]=cloudThickness[CLOUD_SIZE*CLOUD_SIZE*4+1]=cloudThickness[CLOUD_SIZE*CLOUD_SIZE*4+2]=0;
//create the cloud shading
int ydif[CLOUD_SIZE];
for(int a=0;a<CLOUD_SIZE;++a){
ydif[a]=0;
ydif[a]+=cloudThickness[(a+3*CLOUD_SIZE)*4+3];
ydif[a]+=cloudThickness[(a+2*CLOUD_SIZE)*4+3];
ydif[a]+=cloudThickness[(a+1*CLOUD_SIZE)*4+3];
ydif[a]+=cloudThickness[(a+0*CLOUD_SIZE)*4+3];
ydif[a]-=cloudThickness[(a-1*CLOUD_SIZE+CLOUD_SIZE*CLOUD_SIZE)*4+3];
ydif[a]-=cloudThickness[(a-2*CLOUD_SIZE+CLOUD_SIZE*CLOUD_SIZE)*4+3];
ydif[a]-=cloudThickness[(a-3*CLOUD_SIZE+CLOUD_SIZE*CLOUD_SIZE)*4+3];
}
int b=0;
ydif[(b)&255]+=cloudThickness[(b-3*CLOUD_SIZE+CLOUD_SIZE*CLOUD_SIZE)*4+3];
ydif[(b)&255]-=cloudThickness[(b)*4+3]*2;
ydif[(b)&255]+=cloudThickness[(b+4*CLOUD_SIZE)*4+3];
for(int a=0;a<CLOUD_SIZE*3-1;a++){
ydif[(a+1)&255]+=cloudThickness[(a-3*CLOUD_SIZE+1+CLOUD_SIZE*CLOUD_SIZE)*4+3];
ydif[(a+1)&255]-=cloudThickness[(a+1)*4+3]*2;
ydif[(a+1)&255]+=cloudThickness[(a+4*CLOUD_SIZE+1)*4+3];
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;
cloudThickness[a*4+0]=128+dif;
cloudThickness[a*4+1]=thicknessTransform[rawClouds[0][a]>>7];
cloudThickness[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]+=cloudThickness[(a-3*CLOUD_SIZE+1)*4+3];
ydif[(a+1)&255]-=cloudThickness[(a+1)*4+3]*2;
ydif[(a+1)&255]+=cloudThickness[(a+4*CLOUD_SIZE+1)*4+3];
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;
cloudThickness[a*4+0]=128+dif;
cloudThickness[a*4+1]=thicknessTransform[rawClouds[0][a]>>7];
cloudThickness[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]+=cloudThickness[(a-3*CLOUD_SIZE+1)*4+3];
ydif[(a+1)&255]-=cloudThickness[(a+1)*4+3]*2;
ydif[(a+1)&255]+=cloudThickness[(a+4*CLOUD_SIZE+1-CLOUD_SIZE*CLOUD_SIZE)*4+3];
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;
cloudThickness[a*4+0]=128+dif;
cloudThickness[a*4+1]=thicknessTransform[rawClouds[0][a]>>7];
cloudThickness[a*4+2]=255;
}
// delete[] rawClouds;
/*
for(int a=0;a<CLOUD_SIZE;++a){
cloudThickness[((int(48+camera->pos.z*CLOUD_SIZE*0.000025f)%256)*CLOUD_SIZE+a)*4+3]=0;
}
for(int a=0;a<CLOUD_SIZE;++a){
cloudThickness[(a*CLOUD_SIZE+int(gs->frameNum*0.00009f*256+camera->pos.x*CLOUD_SIZE*0.000025f))*4+3]=0;
}
/**/
glBindTexture(GL_TEXTURE_2D, cloudDot3Tex);
glTexSubImage2D(GL_TEXTURE_2D,0, 0,0,CLOUD_SIZE, CLOUD_SIZE,GL_RGBA, GL_UNSIGNED_BYTE, cloudThickness);
}
void CBasicSky::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 CBasicSky::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]=(unsigned char)(alpha*255);
float d=f*2;
if(d>1)
d=1;
thicknessTransform[a]=(unsigned char)(128+d*64+alphaTransform[a]*255/(4*255));
}
}
void CBasicSky::DrawSun()
{
glPushMatrix();
// glTranslatef(camera->pos.x,camera->pos.y,camera->pos.z);
CMatrix44f m(camera->pos,sundir1,UpVector,sundir2);
glMultMatrixf(m.m);
glDisable(GL_DEPTH_TEST);
unsigned char buf[32];
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))%256;
fy-=floor(fy);
float fx=gs->frameNum*0.00005f*CLOUD_SIZE+modCamera.x*CLOUD_SIZE*0.000025f;
int baseX=int(floor(fx))%256;
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]);
}
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;
buf[x]=(unsigned char)(255-cover*2);
}
glBindTexture(GL_TEXTURE_2D, sunFlareTex);
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,32,1,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 CBasicSky::SetCloudShadow(int texunit)
{
}
void CBasicSky::ResetCloudShadow(int texunit)
{
}
void CBasicSky::DrawShafts()
{
}
void CBasicSky::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<2;++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);
// gluBuild2DMipmaps(GL_TEXTURE_2D,1 ,32, 2, GL_ALPHA, GL_UNSIGNED_BYTE, mem);
glTexImage2D(GL_TEXTURE_2D,0,1 ,32, 2,0, GL_LUMINANCE, GL_UNSIGNED_BYTE, mem);
delete[] mem;
float3 ldir=modSunDir.cross(UpVector);
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.25f);
glVertexf3(modSunDir*5+ldir*dx*0.0014f+udir*dy*0.0014f);
glTexCoord2f(x/256.0f,0.75f);
glVertexf3(modSunDir*5+ldir*dx*4+udir*dy*4);
}
glEnd();
if (gu->drawFog) glEnable(GL_FOG);
glEndList();
}
inline unsigned char CBasicSky::GetCloudThickness(int x,int y)
{
assert (CLOUD_SIZE==256);
x &= 0xff;
y &= 0xff;
//assert (x>=0 && x<CLOUD_SIZE);
//assert (y>=0 && y<CLOUD_SIZE);
return cloudThickness [ (y * CLOUD_SIZE + x) * 4 + 3 ];
}
void CBasicSky::CreateCover(int baseX, int baseY, float *buf)
{
static 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++];
cover1+=255-GetCloudThickness(baseX-dx,baseY+dy);
cover2+=255-GetCloudThickness(baseX-dy,baseY-dx);//*(num-x);
cover3+=255-GetCloudThickness(baseX+dx,baseY-dy);//*(num-x);
cover4+=255-GetCloudThickness(baseX+dy,baseY+dx);//*(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;
}
}
float3 CBasicSky::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 CBasicSky::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 + -
显示快捷键?