Thread: New screenshots from engine

  1. #16
    Crazy Fool Perspective's Avatar
    Join Date
    Jan 2003
    Location
    Canada
    Posts
    2,640
    looking very nice Bubba. When can we expect a playable demo? even if its just a flight sim of sorts...

  2. #17
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    The system I'm running on is fairly dated. It's just an AMD 1.333 GHz with 64 MB GeForce 3 and 896 MB RAM with an Audigy 2 sound card.

    Right now this is brute force. The hardware is clipping/culling the frustrum which is not the best idea in the world. I really want to implement my own frustrum culling except I'm not quite sure how to get the clip matrix from D3D. Once I figure that out I just test

    -x<w<x
    -y<w<y
    -z<w<z

    To create my render list. I have optimized the inner loop so that it renders all alpha blended objects at one time. Even if I have well over 10000 alpha blended objects it still only requires 2 state changes per frame which is very nice.

    The planets are not progressive meshes and I'm kinda deciding whether to use them or not. It is a good possibility that progressive meshes may actually take longer to decimate than simply using set LOD's. Progressive LOD's may not work well.

    Also as my system is old it really doesn't matter to me if I tax it because my system is not a good representation of my target platform. I also cannot use any pixel shaders over version 2.0 or vertex shaders over version 2.0. My card does not support them. So just because it lags on my system does not mean it will lag on another.

    Very very soon I'm going to put all of this stuff in effects files so that I can check the device caps and adjust my display quality based on the rig it's running on.

    Need help on these problems
    But I'm having some problems with Window's messages. It seems that every time I move the cursor in the upper left hand corner the stupid mouse cursor appears, as well as when I move it in the upper right. I've trapped the WM_SYSCOMMAND message and trapped cracked it into lParam and wParam but it still allows you to select the system menu. I've looked at the Direct3D framework that MS wrote and it isn't doing anything I'm not doing. It's really 'bugging' me.

    Firing lasers so they move through the target
    Now I have this figured out except that the lasers don't look as though they move through the target until they are way off in the distance. In essence I need to adjust the convergence of the lasers so that they converge at a spot just in front or some distance in front of the ship. Should I alter the direction vector components individually by the up and right vectors of the camera or should I just wait until these are actually being fired by a gun in 3D space?

    Sound clipping
    It seems that DirectMusic doesn't like playing a lot of sound effects through one channel. It tends to clip them rather quickly. This is probably due to them using some crappy additive mixing scheme in the primary buffer. I.E.:

    I would imagine its something like this since I do have some experience in writing sound engines.
    Code:
     
    WORD finalsamplevalue=0;
     
     
    std::vector<Buffer>::iterator ptr; 
    for (ptr=Buffers.begin();ptr!=Buffers.end();ptr++)
    {
    WORD samplevalue=(ptr->SoundData[ptr->PlayCursor]*ptr->VolumeCoef);
    finalsamplevalue++;
    }
     
    finalsamplevalue/=numsamples;
     
    //clamp final mix
    if (finalsamplevalue<0) finalsamplevalue=0;
    if (finalsamplevalue>65535) finalsamplevalue=65535;
     
    ....write final sample value to buffer
    This is of course for unsigned short sample buffers, but you get the idea. I shudder to think about writing my own mixer but if I keep getting this clipping I just might.
    That's where I'll probably move to pure assembly and use MMX so I can be fast...even though it won't be as fast as the hardware.

    Rotating objects to match their velocity vector
    Now I know how to compute a velocity vector from one point in space to another, but I'm not sure how to actually rotate the object to match the given vector orientation. Just simply using the normalized vector components for rotation does not work. The normalized vector will always fall in the range 0 to 1.0f, but the D3DXRotation functions expect a value from -PI to PI.

    Things I've tried:

    1. Compute dot product between velocity vector and current lookAt vector for object. Use dot product as angle argument for D3DXRotationAxis along the Velocity Vector.
    Code:
    D3DXVECTOR3 Base(0.0f,0.0f,1.0f);	 //pointing down positive Z
     
    //Find angle between vectors
    float dot=D3DXVec3Dot(&Base,&VelocityVector); 
     
    //Rotate on velocity vector by specified angle
    D3DXMATRIX Final;
    D3DXMatrixRotationAxis(&Final,&VelocityVector,dot);
    But this does not work. This assumes that we are already on the velocity vector axis and so it does not work. If I use the base vector as the vector it still does not work properly.
    I'm sorta lost.

    2. Compute the picking ray that goes through mouse point mx,my. Compute atan2(y,z), atan2(x,z) and atan2(x,y). Rotate object by those amounts on x,y, and z. This produces some very ugly gimbal lock situations and is quite slow because of the atan2.


    Here is the code I have so far:
    Code:
    #include "CLaser.h"
    #include "math.h"
     
    const DWORD LaserVertex::FVF=D3DFVF_XYZ | D3DFVF_TEX1;
    void CActiveLaserContainer::Create(IDirect3DDevice9 *_Device,std::string _File)
    {
    Device=_Device;
     
    //Properties.Position=D3DXVECTOR3(0.0f,0.0f,0.0f);
    LaserVertex *verts;
    Device->CreateVertexBuffer(4*sizeof(LaserVertex),
    							 D3DUSAGE_WRITEONLY,
    							 LaserVertex::FVF,
    							 D3DPOOL_MANAGED,
    							 &VB,
    							 0);
    VB->Lock(0,0,(void **)&verts,0);
    verts[0]=LaserVertex(D3DXVECTOR3(-.3f, 0.0f, 5.0f), 0.0f, 0.0f);
    verts[1]=LaserVertex(D3DXVECTOR3(.3f, 0.0f, 5.0f), 1.0f, 0.0f);
    verts[2]=LaserVertex(D3DXVECTOR3(-.3f, 0.0f, 0.0f), 0.0f, 1.0f);
    verts[3]=LaserVertex(D3DXVECTOR3(.3f, 0.0f, 0.0f), 1.0f, 1.0f);
     
    VB->Unlock();
     
    D3DXCreateTextureFromFile(Device,_File.c_str(),&Texture);
    }
    void CLaser::Create(IDirect3DDevice9 *_Device,
    					LaserProps _Props,
    					D3DXMATRIX _view,
    					D3DXVECTOR3 _lookAt,
    					unsigned long _mx,
    					unsigned long _my)
    {
    Properties=_Props;
     
    //Compute picking ray
    float px=0.0f;
    float py=0.0f;
     
    D3DVIEWPORT9	vp;
    _Device->GetViewport(&vp);
    D3DXMATRIX proj;
    _Device->GetTransform(D3DTS_PROJECTION,&proj);
    px=((( 2.0f*_mx)/ vp.Width ) - 1.0f)/ (proj(0,0));
    py=(((-2.0f*_my)/ vp.Height) + 1.0f)/ (proj(1,1));
    D3DXVECTOR3 Direction(px,py,1.0f);
     
    //Compute Velocity Vector
    D3DXMATRIX ViewInverse;
    D3DXMatrixInverse(&ViewInverse,0,&_view);
    D3DXVec3TransformNormal(&Direction,&Direction,&ViewInverse);
    D3DXVec3Normalize(&Direction,&Direction);
    Properties.VelocityVector=Direction;
     
    //Setup base translation matrix
    D3DXMATRIX Trans;
    D3DXMatrixTranslation(&Trans,
    						Properties.GunPos.x,
    						Properties.GunPos.y,
    						Properties.GunPos.z);
    //Setup laser-to-target translation matrices
    D3DXMATRIX Trans2;
    D3DXMatrixTranslation(&Trans2,Direction.x,Direction.y,1.0f);
     
    //Rotate lasers toward's target
    D3DXMATRIX Rot;
    D3DXMatrixRotationYawPitchRoll(&Rot,px,-py,1.0f);
     
    //Store our world matrix so we don't compute later
    Properties.World=Rot*Trans*Trans2*ViewInverse;
     
    }
     
    void CActiveLaserContainer::Render(float timeDelta,D3DXMATRIX view,CLaser *Laser)
    {
     
    D3DXMATRIX world=Laser->Properties.World;
     
    //Fast translation - no multiply
    world._41=Laser->Properties.Position.x;
    world._42=Laser->Properties.Position.y;
    world._43=Laser->Properties.Position.z;
     
    //Transform object
    Device->SetTransform(D3DTS_WORLD,&world);
     
    //Render object 
    Device->SetStreamSource(0,VB,0,sizeof(LaserVertex));
    Device->SetFVF(LaserVertex::FVF);
    Device->SetTexture(0,Texture);
    Device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
     
    }
    That's the relevant code for my laser creation and rendering. Please help me.

    Here are the headers:

    Code:
    #ifndef CLASER
    #define CLASER
    
    #include "d3dx9.h"
    #include "CQuickCom.h"
    #include <vector>
    
    //Current vertex type
    struct LaserVertex
    {
      D3DXVECTOR3	 Position;
      float		   u,v;
      LaserVertex(D3DXVECTOR3 &_pos,float _u,float _v):Position(_pos),u(_u),v(_v) {}
      static const DWORD FVF;
    };
    
    //Structure for a ray if needed
    struct CRay
    {
      D3DXVECTOR3   Origin;
      D3DXVECTOR3   Direction;
    };
    
    //Laser properties structure - still a work in progress
    struct LaserProps
    {
      //Position, speed, picking ray, and world matrix for this object
      D3DXMATRIX			World;
      CRay				  PickingRay;
      float				 Speed;
      D3DXVECTOR3		   Position;
    
      //Convergence factor - not working
      D3DXVECTOR3		   ConvergenceVector;
      
      //Current gun position and rotational matrix
      D3DXVECTOR3		   GunPos;
      D3DXMATRIX			*RotationMatrix;
      D3DXVECTOR3		   Rotation;
      D3DXVECTOR3		   VelocityVector;
      
      //Attributes
      float				 FireRate;
      float				 RechargeRate;
      float				 EnergyDrain;
      float				 DamageAmount;
      unsigned int	   DamageType;
      float				 LifeTimer;
      float				 LifeDistance;
     
      //Textures - not used yet
      IDirect3DTexture9	 *Texture;
      IDirect3DTexture9	 *AlphaTexture;
      
      //Sounds
      WCHAR				 *SoundFile;
    };
    
    class CLaser
    {
      protected:
    	friend class CActiveLaserContainer;
    	
    	LaserProps				Properties;
    	
    	CLaser(void) {}
    	
      public:
    	LaserProps GetProps(void) {return Properties;};
    	void Create(IDirect3DDevice9 *_Device,
    				LaserProps _Props,
    				D3DXMATRIX _view,
    				D3DXVECTOR3 _lookAt,				
    				unsigned long _mx,
    				unsigned long _my);
     
    	//Update ourself 
    	void Update(float timeDelta) 
    	{
    	  Properties.Position+=((Properties.VelocityVector*Properties.Speed)*timeDelta);
    	}
       
    	
    };
     
    class CActiveLaserContainer
    {   
      protected:
    	std::vector<CLaser> Lasers;
    	
    	//Shared resources
    	IDirect3DTexture9		 *Texture; 
    	IDirect3DDevice9		  *Device;
    	IDirect3DVertexBuffer9	*VB;
      public:
    	CActiveLaserContainer(void):Texture(NULL),Device(NULL),VB(NULL) {}
    	virtual ~CActiveLaserContainer(void) 
    	{
    	  Lasers.clear();
    	  SAFE_RELEASE(Texture);
    	  SAFE_RELEASE(VB);
    	}
    	void Create(IDirect3DDevice9 *_Device,std::string _File);
     
    	//Add a laser to the mix
    	unsigned int AddLaser(LaserProps _NewLaser,
    						  D3DXMATRIX _view,
    						  D3DXVECTOR3 _lookAt,
    						  unsigned long _mx,
    						  unsigned long _my)
    	{
    	  CLaser temp;
    	  temp.Create(Device,_NewLaser,_view,_lookAt,_mx,_my);
    		
    	  
    	  Lasers.push_back(temp);
    			
    	  return Lasers.size()-1;
    	}
    	void Render(float timeDelta,D3DXMATRIX _view,CLaser *Laser);
    	void RemoveLaser(unsigned int _ID);
    	bool GetProps(unsigned int lasernum,LaserProps *outProps)
    	{
    	  if (Lasers.empty()) return false;
    	  std::vector<CLaser>::iterator laser=Lasers.begin();
    	  int count=0;
    	  while (count!=lasernum)
    	  {
    		laser++;
    		count++;
    	  }
    	  outProps=&(laser->Properties);
    	  return true;
    	}
     
    	//Update all lasers
    	void Update(D3DXVECTOR3 &_ObjectVector,D3DXMATRIX view,float timeDelta)
    	{
    		   
    	  std::vector<CLaser>::iterator laser;
    				  
    	  for (laser=Lasers.begin();laser!=Lasers.end();laser++)
    	  {
    		//Check life-span
    		if (laser->Properties.LifeTimer>laser->Properties.LifeDistance)
    		{
    		  if (laser!=Lasers.end()-1)
    		  {
    			//We are dying
    			laser=Lasers.erase(laser);
    		  }
    		  
    		} 
    
    		//Make sure we are not at end of list - big time crash if we are
    		if (laser!=(Lasers.end()))
    		{
    		  laser->Properties.LifeTimer+=timeDelta;
    		  
    		  //Update laser -> faster than calling laser->Update()
    		  laser->Properties.Position+=
    			(laser->Properties.VelocityVector*laser->Properties.Speed)*timeDelta;
    
    		  //Draw the laser
    		  Render(timeDelta,view,laser);
    		}
    		
    	  }
    	}
    };
    #endif
    Notice that I've left some code in CLaser that doesn't do anything. I used to update the lasers in the local class but then decided it was faster to update it from the container class. In fact I'm learning that structure is very very important to how fast the thing will render. Making something private just to be C++-like is a sure way to destroy your framerates. Every time you call a function you create function call overhead. Do that about 10000 times a frame and you crawl.

    Sorry so long but you can't say I didn't post enough code for you to help me. I tried on my own first I'm thinking.

    Last edited by VirtualAce; 11-22-2004 at 02:49 PM.

  3. #18
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    See what the board did to my first sections of code??? Thats what we are talking about. Anytime you edit your post it kills the spaces and moves everything to the left. Notice my second code block does not suffer from this. That's because I hit edit post and posted the header later - thus it moved all my code block(s) from the initial post to the left margin and yet preserved the later code block(s).

    Quite an annoying board bug.

  4. #19
    Registered User
    Join Date
    Mar 2003
    Posts
    580
    I can help with the rotation problem you are experiencing. I have implemented the code so that enemies in a 3D world will rotate towards you and face you. Do you want me to explain my method, or do you want me to try to find a possible error in your code and edit it? I am very willing to help, if you want me to.

  5. #20
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Either way is fine with me. I understand the concepts and can draw it out, but I'm obviously missing something. This is the laser code so it prob wont help to point out anything here.

    Just explain it to me if you could please.

  6. #21
    Registered User
    Join Date
    Mar 2003
    Posts
    580
    D3DXVECTOR3 Base(0.0f,0.0f,1.0f); //pointing down positive Z

    //Find angle between vectors
    float dot=D3DXVec3Dot(&Base,&VelocityVector);

    //Rotate on velocity vector by specified angle
    D3DXMATRIX Final;
    D3DXMatrixRotationAxis(&Final,&VelocityVector,dot) ;
    Firstly, does D3DXVec3Dot really return the angle between vectors, or just the dotproduct? If it just takes the dotproduct, and not the angle, then does D3DMatrixRotationAxis know how to compute the correct rotation axis when you give it the two vectors and the dotproduct between the two? If not, you need to take the inverse cosine of the dotproduct in order to get an angle. If this is stuff you already know, I'm sorry, I'm just trying to see if there's something 'easy' that might've been missed.

    In my next post i'm going to describe what works for me in my method.

  7. #22
    Registered User
    Join Date
    Mar 2003
    Posts
    580
    This is my code just for computing the angle yaw. It's similar for pitch, and I don't know how to do roll. This works perfectly.
    Code:
    	Vector3Double	PlayerPos	=	Engine->GetPlayerPos();
    	Vector3Double	ToPlayer	=	PlayerPos - this->mPosition;
    	ToPlayer.y = 0;	//I am doing this because I am doing a polar coordinate calculation on the y = 0 plane, this calculates the rotation angle on the y axis
    	ToPlayer.Normalize();
    	this->mYaw = acosf(-ToPlayer.z); //This is the same as taking the dotproduct between the ToPlayer vector and the 'base vector'.  
    //I am in OpenGL, so the base vector is (0,0,-1), else it's (0,0,1)
    
    	//This step is crucial because I only know the angle between the two vectors, but I don't know if it is a positive or negative angle!
    	if(PlayerPos.x > this->mPosition.x)
    		this->mYaw *=	-1;
    Last edited by Darkness; 11-22-2004 at 03:34 PM.

  8. #23
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well thats sort of what I figured it would be. However I'm not calculating the arccos of the dot product. I would like to be able to do it w/o making that computation. However your basis vector is exactly what I've been doing.

    All my objects have a base vector of 0,0,1. That is they are all in model space pointing down the positive (in Direct3D away from the camera) z axis. So it makes a lot of sense that you compute the dot product between the base vector and the vector you need to rotate to. So I wasn't too far off. Thanks a bunch and I will try it. I think for Z rotation you need to setup so that Z will always rotate the object or roll the object. This is done by using your 3 basis vectors. Roll really doesn't matter in most cases and especially in my game. As long as the object heads towards you is all that matters.

    If all of the basis vectors are correct and you are using the inverse view matrix then roll is simply a matter of saying roll this way or that way. To roll upright you would simply roll until your vector was 0,0,1 or what you started with.

  9. #24
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Also to answer your second question.....each laser in that picture represents 2 tri's. Each side of the skybox represent's two tri's and the mouse cursor object represent's 2 tri's. The planet's each have 32 facets north/south and east/west or 32*32*2 tri's in them (2048 tri's per planet). In this render there are 2 planets in system. So here is the triangle breakdown by object:

    Triangles per object:

    Skybox: 12 (6 faces *2 tri's per face)
    Mouse cursor: 2 (triangulated quad)
    Lasers: 2 (triangulated quad)
    Planets: 2048

    I cannot tell exactly how many lasers there are because there are more off screen as well. I would say that there are about 500 or more lasers or about 1000 tri's.

    So in all there are only about 2048+12+2+1000 tri's (3062 triangles).

    But note that there are NOT 1000 textures, sounds, or vertex buffers in memory. Each laser share's the container's vertex buffer, sound, and texture. I coded it this way to be efficient and it seems to have worked. When you create a container you must specify the texture you want and you must specify the model (or manually create one in the create() function of the container class) as well. This works quite nice and makes a lot more sense as well. The class also DOES NOT change any render states whatsoever. The engine does that.

    EDIT:
    Ok I underestimated somewhat. Here is a screenie with an exact count of lasers.
    Last edited by VirtualAce; 11-23-2004 at 01:56 AM.

  10. #25
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Another test: Bad frames but lots of crapola on the screen.

  11. #26
    Registered User PanzTec's Avatar
    Join Date
    Sep 2004
    Posts
    24
    I wish i could program like he can... im stuck in stupid 2D programming right now....
    The Matrix Will Live Again!

  12. #27
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    It's nothing spectacular. Look on some game sites. They blow my screenies out of the water. I need more people...namely 3D modelers and artists.

  13. #28
    ---
    Join Date
    May 2004
    Posts
    1,379
    Don't say 'stuck' and dont say 'stupid 2D programming'.
    You are never 'stuck' and there is nothing stupid about programming.
    (Unless it's COBOL, but that is another story )

    [edit]
    Oh and a lot of us wish we could program as well as Bubba could
    [/edit]

  14. #29
    #junkie
    Join Date
    Oct 2004
    Posts
    240
    Just outa curiosity, and im sure i am the odd one for asking this out of all the masterful coding being displayed lol, but where are you hosting those pics?
    01110111011000010110110001100100011011110010000001 11000101110101011010010111010000100000011011000110 10010110011001100101001000000111100101101111011101 0100100000011011100111010101100010

  15. #30
    ---
    Join Date
    May 2004
    Posts
    1,379
    They are attached to the board

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In a game Engine...
    By Shamino in forum Game Programming
    Replies: 28
    Last Post: 02-19-2006, 11:30 AM
  2. Game Engine Link Prob
    By swgh in forum Game Programming
    Replies: 2
    Last Post: 01-26-2006, 12:14 AM
  3. Ultra chess engine contest
    By yodacpp in forum Projects and Job Recruitment
    Replies: 8
    Last Post: 11-21-2004, 07:58 AM
  4. Updated sound engine code
    By VirtualAce in forum Game Programming
    Replies: 8
    Last Post: 11-18-2004, 12:38 PM
  5. Game structure, any thoughts?
    By Vorok in forum Game Programming
    Replies: 2
    Last Post: 06-07-2003, 01:47 PM