PDA

View Full Version : Three beginner questions about D3D



Firlefanz
11-01-2005, 07:58 AM
Hello,

for my project 'Commando Xenidis' I am building a 3D planet map. I am new to Direct3D. I am using Omega Headers based on Clootie-Headers for DirectX8.1. Screens can be found under projects/commando xenidis.

Those planets are X-Objects, just spheres, also is the sun.

1) How do I get animated clouds on my planets? Do I need to create a 2nd layer on my X-Object, a sphere that is a bit larger and give this layer a cloud texture? How do I make a transparent? Or is there a more simple way?

2) The sun only has a texture right now, how do I make a corona or another nice sun effect?

3) Is there a simple way to create some nice looking fog (Volumetric Fog?) or does anybody have other ideas for some nice effects?

I would be glad about some help or some ideas. The skybox does not look good I know, I am just switching it to another.

Thanks a lot,
Firle

Code for loading the planets:



function TForm1.Load_planets: boolean; // Tutorial 6 - Step 1
var _pAdjacency, _pD3DXMtrlBuffer : ID3DXBuffer;
_d3dxMaterials : PD3DXMaterial;
_i : longint;
i: integer;
begin
Result := false;
// Load mesh.
_pAdjacency := NIL;
_pD3DXMtrlBuffer := NIL;
for i:=1 to 31 do begin
//D3DXMatrixTranslation(planet3d[i].matXYZ,planet3d[i].nstartx,planet3d[i].nstarty,planet3d[i].nstartz);
D3DXMatrixTranslation(planet3d[i].matRot,0,0,0);
if failed(D3DXLoadMeshFromX(pChar(Planet3d[i].sMeshFileName), D3DXMESH_SYSTEMMEM,
OmegaScreen1.Device, @_pAdjacency, @_pD3DXMtrlBuffer,
@Planet3d[i].NumMaterials, Planet3d[i].g_pMesh)) then exit;
_pAdjacency := NIL;
if Planet3d[i].NumMaterials = 0 then exit;
// After loading the mesh object and material information,
// we need to extract the material properties and texture
// names from the material buffer.
_d3dxMaterials := _pD3DXMtrlBuffer.GetBufferPointer;
// Creates new mesh and texture objects based on the total
// number of materials for the mesh.
try
SetLength(planet3d[i].g_pMeshMaterials, Planet3d[i].NumMaterials);
SetLength(planet3d[i].g_pMeshTextures, Planet3d[i].NumMaterials);
except
exit;
end;

// Load materials and textures.
for _i := 0 to Planet3d[i].NumMaterials - 1 do
begin
// Copy the material
planet3d[i].g_pMeshMaterials[_i] := _d3dxMaterials^.MatD3D;
// Set the ambient color for the material (D3DX does not do this)
//planet3d[i].g_pMeshMaterials[_i].Ambient:=planet3d[i].g_pMeshMaterials[_i].Diffuse;
planet3d[i].g_pMeshMaterials[_i].Ambient.r:=(0.7-i/80)*planettyp[i].nRMul;
planet3d[i].g_pMeshMaterials[_i].Ambient.g:=(0.7-i/80)*planettyp[i].ngMul;
planet3d[i].g_pMeshMaterials[_i].Ambient.b:=(0.7-i/80)*planettyp[i].nbMul;
planet3d[i].g_pMeshMaterials[_i].Diffuse.r:=(0.5)*planettyp[i].nRMul;
planet3d[i].g_pMeshMaterials[_i].Diffuse.g:=(0.5)*planettyp[i].nGMul;
planet3d[i].g_pMeshMaterials[_i].Diffuse.b:=(0.5)*planettyp[i].nBMul;
planet3d[i].g_pMeshMaterials[_i].Specular.r:=(0.5)*planettyp[i].nRMul;
planet3d[i].g_pMeshMaterials[_i].Specular.g:=(0.5)*planettyp[i].nGMul;
planet3d[i].g_pMeshMaterials[_i].Specular.b:=(0.5)*planettyp[i].nBMul;
planet3d[i].g_pMeshMaterials[_i].Emissive.r:=(1-i/70)*planettyp[i].nRMul;
planet3d[i].g_pMeshMaterials[_i].Emissive.g:=(1-i/70)*planettyp[i].nGMul;
planet3d[i].g_pMeshMaterials[_i].Emissive.b:=(1-i/70)*planettyp[i].nBMul;
// Create the texture.
planet3d[i].g_pMeshTextures[_i] := NIL;
if _i=0 then begin
_d3dxMaterials^.pTextureFilename:=pansichar(planet 3d[i].stexturename)//feste textur laden
end;
if (_d3dxMaterials^.pTextureFilename = NIL) or
(failed(D3DXCreateTextureFromFile(OmegaScreen1.Dev ice,
_d3dxMaterials^.pTextureFilename,
planet3d[i].g_pMeshTextures[_i])))
then planet3d[i].g_pMeshTextures[_i] := NIL;
// Next
inc(_d3dxMaterials);
end;


Code for rendering the planets:


for i:=1 to 31 do begin
for _i := 0 to Planet3d[i].NumMaterials - 1 do begin
// Set the material for the subset.
SetMaterial(planet3d[i].g_pMeshMaterials[_i]);
// Set the texture for the subset.
//Lichter auf Texturen
//settexturestagestate(0,d3dtss_colorarg1,d3dta_text ure);
//settexturestagestate(0,d3dtss_colorop,d3dtop_selec targ1);
//settexturestagestate(1,d3dtss_colorarg1,d3dta_curr ent);
//settexturestagestate(1,d3dtss_colorarg2,d3dta_diff use);
//settexturestagestate(1,d3dtss_colorop,d3dtop_modul ate);
SetTexture(0,planet3d[i].g_pMeshTextures[_i]);
if i>1 then D3DXMatrixRotationY(planet3d[i].matrot,planet3d[i].nweite/150);//planet3d[i].nRotx);
x:=cos(planet3d[i].nweite/planet3d[nchosenplanet].nRotSpeed)*planet3d[i].nRotX;
z:=sin(planet3d[i].nweite/planet3d[nchosenplanet].nRotSpeed)*planet3d[i].nRotX;
y:=30-i*2;
planet3d[i].x:=x;
planet3d[i].y:=y;
planet3d[i].z:=z;
if i=1 then begin
x:=0;
y:=0;
z:=0;
end;
D3DXMatrixTranslation(planet3d[i].matxyz,x,y,z);
D3DXMatrixMultiply(matTmp, planet3d[i].matrot, planet3d[i].matxyz);
if i=1 then D3DXMatrixScaling(mattmp,planet3d[i].nradius,planet3d[i].nradius,planet3d[i].nradius); //grA¬?AYer skalieren
omegascreen1.Device.SetTransform(D3DTS_WORLD,mattm p);
planet3d[i].g_pMesh.DrawSubset(_i);
inc(planet3d[i].nweite);
end;
end;
for i:=1 to 20 do begin
for _i := 0 to aster3d[i].NumMaterials - 1 do begin
SetMaterial(aster3d[i].g_pMeshMaterials[_i]);
SetTexture(0,aster3d[i].g_pMeshTextures[_i]);
if i mod 2=0 then D3DXMatrixRotationY(aster3d[i].matrot,nresttimer/100);//planet3d[i].nRotx);
if i mod 3=0 then D3DXMatrixRotationX(aster3d[i].matrot,nresttimer/100);//planet3d[i].nRotx);
if i mod 2=1 then D3DXMatrixRotationZ(aster3d[i].matrot,nresttimer/100);//planet3d[i].nRotx);
D3DXMatrixTranslation(aster3d[i].matxyz,aster3d[i].x,aster3d[i].y,aster3d[i].z);
D3DXMatrixMultiply(matTmp, aster3d[i].matrot, aster3d[i].matxyz);
omegascreen1.Device.SetTransform(D3DTS_WORLD,mattm p);
settexturestagestate(0,d3dtss_colorarg1,d3dta_text ure);
settexturestagestate(0,d3dtss_colorop,d3dtop_selec targ1);
settexturestagestate(1,d3dtss_colorarg1,d3dta_curr ent);
settexturestagestate(1,d3dtss_colorarg2,d3dta_diff use);
settexturestagestate(1,d3dtss_colorop,d3dtop_modul ate);
aster3d[i].g_pMesh.DrawSubset(_i);
end;
end;
end;


Planet 1 is the sun, 2-31 the others, the sun is at 0/0/0, the others are rotating around it.

Sly
11-01-2005, 08:47 AM
1) How do I get animated clouds on my planets? Do I need to create a 2nd layer on my X-Object, a sphere that is a bit larger and give this layer a cloud texture? How do I make a transparent? Or is there a more simple way?
You can use the same sphere to draw the clouds. Set the depth func (D3DRS_ZFUNC) to D3DCMP_LESSEQUAL and draw the sphere again using an additive blend of a material that looks like clouds over a black background.


2) The sun only has a texture right now, how do I make a corona or another nice sun effect?
Coronas are simply a single large camera-facing quad (billboard) drawn at the sun position. Use an additive or alpha material for the corona. If you want a lens flare, then this is simply a series of billboards (usually a series of circles and hexagons) drawn along a line that passes through the screen position of the sun and the centre of the screen. The closer the sun is to the centre of the screen, the closer the billboards are spaced. The further away the sun is, the further apart the billboards are spaced along this imaginary line.


3) Is there a simple way to create some nice looking fog (Volumetric Fog?) or does anybody have other ideas for some nice effects?
Several large alpha-blended billboards in a bunch could represent a dust cloud.

Firlefanz
11-01-2005, 08:52 AM
Hello Sly,

thanks a lot for your help. But I am really a 3D newbie, could you please explain it a little bit more, or if you have the time and the knowledge, give
me a piece of code? I have just started to learn D3D and have understood how to load and position and render objects, not much more.

Thanks :D

Firle

Sly
11-01-2005, 10:41 AM
Here's a good tutorial on how to create clouds using Perlin noise.
http://freespace.virgin.net/hugo.elias/models/m_clouds.htm

To draw the clouds, set the depth func to less-equal
OmegaScreen1.Device.SetRenderState(D3DRS_ZFUNC, D3DCOMP_LESSEQUAL);
Enable alpha blending
OmegaScreen1.Device.SetRenderState(D3DRS_ALPHABLEN DENABLE, iTrue);
OmegaScreen1.Device.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
OmegaScreen1.Device.SetRenderState(D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA);
Then render the sphere again, but set the material to the cloud material instead of the planet material.

Note that I'm still learning D3D myself.

Firlefanz
11-01-2005, 10:46 AM
Hi Sly,

thanks for the link and your explanations, sounds good, I'll have to try it. :D

Firle