Pic and download are in the first post. Here is the code for making the nebulae:
The first part is making the texture:
void MakeNebulaImage(void){
NewNebulaImage=FindFreeImage();
dbMakeImage(NewNebulaImage,128,128);
dbMakeMemblockFromImage(2,NewNebulaImage);
dbDeleteImage(NewNebulaImage);
//make the circles
for (int i=64;i>0;i-=4){
PutCircleInMemBlock(2,dbRGB(33,33,33),63,63,i,128,true,255,true);
}
dbMakeMemblockFromImage(1,Galaxy.BaseImage);//this image is just a noise image made from "caust00.dds" that comes with DX and I itterated it 4x4 into another image.
for (int y=0;y<128;y++){// this part modulates the two images so that it comes out circular.
for (int x=0;x<128;x++){
int pos=(y*128+x)*4+12;
DWORD C=dbMemblockDword(2,pos);
float m=float(dbMemblockByte(1,pos+2));
m/=256.0;
int r=dbRGBR(C);
int g=dbRGBG(C);
int b=dbRGBB(C);
r*=m;
g*=m;
b*=m;
dbWriteMemblockDword(2,pos,dbRGB(r,g,b));
}
}
SmoothMemblockImage(2,2,128,128,4);
dbMakeImageFromMemblock(NewNebulaImage,2);
dbDeleteMemblock(1);
dbDeleteMemblock(2);
}
The PutCircleInMemBlock(..) part is something I made to put a circle in a memblock.
If you want the it, here it is:
void PutCircleInMemBlock(int MB,DWORD C,int x,int y,float D,int W,bool FillIn,byte Alpha,bool AddAlpha){
int Size=dbGetMemblockSize(MB);
if (!FillIn){
float Step=1500/D;
for (float a=0;a<36000;a+=Step){
int lx,ly;
lx=x+cosf(float(a)/100.0)*D;
ly=y+sinf(float(a)/100.0)*D;
int Pos=12+(ly*W+lx)*4;
if ((Pos>12)&&(Pos<12+Size)&&(lx>-1)&&(lx<W)){
if (!AddAlpha){
dbWriteMemblockDword(MB,Pos,C);
dbWriteMemblockByte(MB,Pos+3,Alpha);
}
else{
int A=dbMemblockByte(MB,Pos+3)+Alpha;
if (A>255) A=255;
DWORD C2=dbMemblockDword(MB,Pos);
int r=dbRGBR(C2)+dbRGBR(C);
int g=dbRGBG(C2)+dbRGBG(C);
int b=dbRGBB(C2)+dbRGBB(C);
if (r>255) r=255;
if (g>255) g=255;
if (b>255) b=255;
dbWriteMemblockDword(MB,Pos,dbRGB(r,g,b));
dbWriteMemblockByte(MB,Pos+3,A);
}
}
}
}
if (FillIn){
for (int ly=-D;ly<D;ly++){
int lx=dbSQRT((D*D)-(ly*ly));
for (int q=-lx;q<lx;q++){
int Pos=12+((ly+y)*W+q+x)*4;
if ((Pos>12)&&(Pos<12+Size)&&((q+x)>-1)&&((q+x)<W)){
if (!AddAlpha){
dbWriteMemblockDword(MB,Pos,C);
dbWriteMemblockByte(MB,Pos+3,Alpha);
}
else{
int A=dbMemblockByte(MB,Pos+3)+Alpha;
if (A>255) A=255;
DWORD C2=dbMemblockDword(MB,Pos);
int r=dbRGBR(C2)+dbRGBR(C);
int g=dbRGBG(C2)+dbRGBG(C);
int b=dbRGBB(C2)+dbRGBB(C);
if (r>255) r=255;
if (g>255) g=255;
if (b>255) b=255;
dbWriteMemblockDword(MB,Pos,dbRGB(r,g,b));
dbWriteMemblockByte(MB,Pos+3,A);
}
}
}
}
}
}
Here is the SmoothMemblockImage(..) :
void SmoothMemblockImage(int MB,int SmoothSize,int sx,int sy,int Itterations){
int MSize=dbGetMemblockSize(MB);
for (int it=0;it<Itterations;it++){
for (int y=0;y<sy;y++){
for (int x=0;x<sx;x++){
int Pos=(y*sx+x)*4+12;
DWORD C=dbMemblockDword(MB,Pos);
int cr=dbRGBR(C);
int cg=dbRGBG(C);
int cb=dbRGBB(C);
int Alpha=dbMemblockByte(MB,Pos+3);
int div=0;
for (int smy=-SmoothSize;smy<=SmoothSize;smy++){
for (int smx=-SmoothSize;smx<=SmoothSize;smx++){
if ((smx>-1)&&(smx<sx)&&(smy>-1)&&(smy<sy)){
div++;
Pos=((y+smy)*sx+x+smx)*4+12;
if ((Pos>12)&&(Pos<MSize)){
if ((smx!=0)||(smy!=0)){
C=dbMemblockDword(MB,Pos);
cr+=dbRGBR(C);
cg+=dbRGBG(C);
cb+=dbRGBB(C);
Alpha+=dbMemblockByte(MB,Pos+3);
}
}
}
}
}
cr/=div;
cg/=div;
cb/=div;
if (cr>255) cr=255;
if (cg>255) cg=255;
if (cb>255) cb=255;
C=dbRGB(cr,cg,cb);
Alpha/=div;
if (Alpha>255) Alpha=255;
Pos=(y*sx+x)*4+12;
dbWriteMemblockDword(MB,Pos,C);
dbWriteMemblockByte(MB,Pos+3,Alpha);
}
}
}
}
This is the part that makes the nebulae:
//load nebulas
int NON=dbRnd(2)+2;
for (int i=0;i<16;i++) NebulaMesh[i]=-1;
for (int n=0;n<NON;n++){
float lx=dbRnd(264)-132;
float lz=dbRnd(264)-132;
for (int i=0;i<4;i++){
NebulaMesh[i+n*4]=FindFreeObject();
sprintf(tmpString,"media/meshes/Nebula%d.x",dbRnd(3)+1);
dbLoadObject(tmpString,NebulaMesh[i+n*4]);
dbPositionObject(NebulaMesh[i+n*4],lx*30+dbRnd(300)-150,0,lz*30+dbRnd(300)-150);
dbScaleObject(NebulaMesh[i+n*4],dbRnd(2000)+1000,dbRnd(500)+1000,dbRnd(2000)+1000);
dbTurnObjectRight(NebulaMesh[i+n*4],dbRnd(360));
dbTextureObject(NebulaMesh[i+n*4],NewNebulaImage);
dbSetObjectEmissive(NebulaMesh[i+n*4],dbRGB(100+dbRnd(35),75+dbRnd(25),117+dbRnd(40)));
dbSetObjectAmbience(NebulaMesh[i+n*4],0);
dbSetObjectDiffuse(NebulaMesh[i+n*4],0);
dbGhostObjectOn(NebulaMesh[i+n*4]);
dbDisableObjectZWrite(NebulaMesh[i+n*4]);
}
}
The fastest code is the code never written.