• Advertisement
Sign in to follow this  

DX Fire is skewed

This topic is 4738 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi all, I'm trying to learn to write a fire simulation with DirectX. I have _Special Effects Game Programming with Dirext X_ by McCuskey, but I haven't seen my CD in years. So, I went searching on the web, and found what appears to be someone's adaption of the code. I took that code, and tried to fit it in a class. Now, when I run, my fire looks skewed. Here is a picture of the fire: http://www.salival.net/fire.JPG and here is the code. i can't quite remember how to post code, but we'll see if this works. any advice you can offer would be much appreciated. let me know if anything else might help
#include "cFire.h"
//#include "palette.cpp"



cFire::cFire(IDirect3DDevice8* dev){
	this->b_Ready = false;
     if(dev != NULL){
		this->Device = dev;
		this->b_Ready = true;
	}
	this->SetPalette();
	  this->Device->SetRenderState(D3DRS_LIGHTING, FALSE);

    //Turn on z-buffering

    this->Device->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);

 

      //Turn on back face culling. This is becuase we want to hide the back of our polygons

    this->Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); //D3DCULL_CCW);

	 for(int q=0; q<255; q++)

      {

            g_palette[q].peRed            = g_FireRed[q];

            g_palette[q].peGreen    = g_FireGreen[q];

            g_palette[q].peBlue           = g_FireBlue[q];

            g_palette[q].peFlags    = 0;

      }

      memset( cFireField, 0, TEXTURESIZE*TEXTURESIZE);

      ::ZeroMemory(cFireField2, TEXTURESIZE*TEXTURESIZE);

 

      pFireActive = cFireField;

      pFireScratch = cFireField2;

     

      // Create Fire Texture.

      D3DXCreateTexture(this->Device, TEXTURESIZE, TEXTURESIZE, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &this->g_pTexture);

 

      this->Device->CreateVertexBuffer(   6*sizeof(my_vertex),

                                                            0, D3D8T_CUSTOMVERTEX,

                                                            D3DPOOL_MANAGED, &pVB);

 

      my_vertex* pV;

      pVB->Lock( 0, 6*sizeof(my_vertex), (BYTE**)&pV, 0);

 

      pV[0].x=-1.0f; pV[0].y=1.0f;  pV[0].z=1.0f; pV[0].colour=0x00000000; pV[0].tu=0.0f; pV[0].tv=0.0f;

      pV[1].x= 1.0f; pV[1].y=1.0f;  pV[1].z=1.0f; pV[1].colour=0x00000000; pV[1].tu=1.0f; pV[1].tv=0.0f;

      pV[2].x= 1.0f; pV[2].y=-1.0f; pV[2].z=1.0f; pV[2].colour=0x00000000; pV[2].tu=1.0f; pV[2].tv=1.0f;

 

      pV[3].x=-1.0f; pV[3].y=1.0f;  pV[3].z=1.0f; pV[3].colour=0xffffffff; pV[3].tu=0.0f; pV[3].tv=0.0f;

      pV[4].x= 1.0f; pV[4].y=-1.0f; pV[4].z=1.0f; pV[4].colour=0xffffffff; pV[4].tu=1.0f; pV[4].tv=1.0f;

      pV[5].x=-1.0f; pV[5].y=-1.0f;  pV[5].z=1.0f; pV[5].colour=0xffffffff; pV[5].tu=0.0f; pV[5].tv=1.0f;

 

      pVB->Unlock();
}

void cFire::SetDevice(IDirect3DDevice8* dev){
	if(dev != NULL){
		this->Device = dev;
		this->b_Ready = true;
	}
}

void cFire::SetPalette(){
  unsigned  char FireRed[256] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

  0,0,0,0,0,0,4,4,4,4,4,4,4,8,8,8,8,8,12,12,12,12,16,16,16,16,20,20,20,24,24,

  24,28,28,32,32,32,36,36,40,40,44,44,48,48,52,52,56,56,60,60,64,68,68,72,72,

  76,80,80,84,88,88,92,92,96,100,100,104,108,108,112,116,120,120,124,128,128,

  132,136,136,140,144,144,148,152,152,156,160,160,164,164,172,172,172,176,176,

  180,184,184,188,188,192,192,196,196,200,200,204,204,208,208,208,212,212,216,

  216,220,220,220,220,224,224,224,228,228,228,228,232,232,232,232,236,236,236,

  236,236,240,240,240,240,240,240,240,244,244,244,244,244,244,244,244,244,244,

  248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,

  248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,

  248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,

  248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,248,

  248,248,248,248,248};

 

unsigned char FireGreen[256]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,8,8,8,8,

  8,8,8,8,8,12,12,12,12,12,12,16,16,16,16,16,16,20,20,20,20,20,24,24,24,24,28,

  28,28,28,32,32,32,32,36,36,36,36,40,40,40,44,44,44,48,48,48,52,52,52,56,56,

  56,60,60,60,64,64,64,68,68,72,72,72,76,76,80,80,80,84,84,84,88,88,92,92,92,

  96,96,100,100,104,104,104,108,108,112,112,116,116,116,120,120,124,124,128,

  128,128,132,132,136,136,140,140,140,144,144,148,148,148,152,152,156,156,160,

  160,163,164,164,168,168,168,172,172,172,176,176,180,180,180,184,184,184,188,

  188,188,192,192,192,196,196,200,200,200,200,200,204,204,204,208,208,208,208,

  212,212,212,212,216,216,216,216,220,220,220,220,220,224,224,224,224,224,228,

  228,228,228,228,228,232,232,232,232,232,232,236,236,236,236,236,236,236,236,

  240,240,240,240,240,240};

 

unsigned char FireBlue[256]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,

  0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,

  4,4,8,8,8,2,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,12,12,12,12,12,12,12,12,12,12,

  12,12,12,12,12,12,12,16,16,16,16,16,16,16,16,16,16,16,16,16,16,20,20,20,20,

  20,20,20,20,20,20,20,20,24,24,24,24,24,24,24,24,24,24,24,24,28,28,28,28,28,

  28,28,28,28,28,32,32,32,32,32,32,32,32,32,32,36,36,36,36,36,36,36,36,36,40,

  40,40,40,40,40,40,40,44,44,44,44,44};

	int i =0;
	for(i=0; i<256; i++){
		this->g_FireRed = FireRed;
		this->g_FireBlue = FireBlue;
		this->g_FireGreen = FireGreen;
	}

}

void cFire::Render(){
	this->SetupCamera();

	this->ProcessFire( pFireActive, pFireScratch, TEXTURESIZE, TEXTURESIZE, 1);

	unsigned char* temp = pFireActive;

      pFireActive = pFireScratch;

      pFireScratch = temp;

     

 

    // Okay at this point... our graphics card has our vertices stored in it... we've just copied

    // them over :) Some stuff to setup or graphics card!

    //Turn off lighting becuase we are specifying that our vertices have colour

    this->Device->SetRenderState(D3DRS_LIGHTING, FALSE);

      this->Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);

 

      // Set to True to make the background transparent -----+

      //                                                     |

      this->Device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);

      this->Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);//D3DBLEND_INVSRCALPHA);

      this->Device->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_ONE);

 

 

    this->Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);

      this->Device->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);

      this->Device->SetTextureStageState(0,D3DTSS_COLORARG2, D3DTA_DIFFUSE);

      this->Device->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);

      this->Device->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);

 

 

      this->Device->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );

      this->Device->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );

      this->Device->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTEXF_LINEAR );

 



 

 

      D3DLOCKED_RECT lockedrect;

      ::ZeroMemory(&lockedrect, sizeof(lockedrect));

 

      g_pTexture->LockRect(0, &lockedrect, NULL, 0);

     

      unsigned char *pSurfBits = static_cast<unsigned char*>(lockedrect.pBits);

 

      int index=0;

      for(int y=0; y<TEXTURESIZE; y++)

      {

            for(int x=0; x<TEXTURESIZE; x++)

			{

                  pSurfBits[index++] = g_palette[ pFireActive[(y*TEXTURESIZE)+x] ].peBlue;

                  pSurfBits[index++] = g_palette[ pFireActive[(y*TEXTURESIZE)+x] ].peGreen;

                  pSurfBits[index++] = g_palette[ pFireActive[(y*TEXTURESIZE)+x] ].peRed;

                  pSurfBits[index++] = g_palette[ pFireActive[(y*TEXTURESIZE)+x] ].peFlags;

            }

            index += lockedrect.Pitch - (TEXTURESIZE*4);

      }

      g_pTexture->UnlockRect(0);

 

      // Clear the back buffer to a blue color

      this->Device->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );

      // Draw our triangle.

 

      this->Device->SetTexture(0, g_pTexture);

      this->Device->SetStreamSource( 0, pVB, sizeof(my_vertex) );

      this->Device->SetVertexShader( D3D8T_CUSTOMVERTEX );

      this->Device->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );

 

      // After rendering the scene we display it.

      this->Device->Present( NULL, NULL, NULL, NULL );

     

 
}

void cFire::SetupCamera(){
	// [1] D3DTS_VIEW
    D3DXMATRIX v;

    this->Device->SetTransform(D3DTS_VIEW, D3DXMatrixLookAtLH(&v, &D3DXVECTOR3(0,0,-3),
                                                                  &D3DXVECTOR3(0,0,0),
                                                                  &D3DXVECTOR3(0,1,0))); 

    // [2] D3DTS_PROJECTION
    D3DXMATRIX p;
    this->Device->SetTransform( D3DTS_PROJECTION, D3DXMatrixPerspectiveFovLH( &p,  D3DX_PI/4,  1.0f,
                                                                                       1.0f,200.0f));
}

void cFire::ProcessFire(unsigned  char* firefield,  unsigned char* firefield2, int firesizex, int firesizey, int coolamount)
{

      for(int y=0; y< firesizey; y++)
      {
            for(int x=0; x< firesizex-0; x++)
            {

	                 unsigned char     firevalue_left,
                                       firevalue_right,
                                       firevalue_bottom,

                                          firevalue_top;

                  int finalfirevalue;

 

                  int xplus1, xminus1, yplus1, yminus1;

                  xplus1  = x+1;  if(xplus1 >= firesizex) xplus1=0;

                  xminus1 = x-1;  if(xminus1 <0) xminus1 = firesizex - 1;

                  yplus1  = y+1;  if(yplus1 >= firesizey) yplus1 = firesizey - 1;

                  yminus1 = y-1;  if(yminus1 <0) yminus1 = 0;

 

                  firevalue_right  = firefield[ (y*firesizex) + xplus1 ];

                  firevalue_left   = firefield[ (y*firesizex) + xminus1 ];

                  firevalue_bottom = firefield[ ((yplus1)*firesizex) + x ];

                  firevalue_top    = firefield[ ((yminus1)*firesizex) + x ];

 

                  finalfirevalue = (firevalue_left + firevalue_right + firevalue_top + firevalue_bottom)/4;

 

                  finalfirevalue -= coolamount;

 

                  if( finalfirevalue < 0 ) finalfirevalue = 0;

 

                  firefield2[ ((yminus1)*firesizex)+x ] = finalfirevalue;

            }

      }

 

      // You could just pick one and stay with it... you should play around with the code to get various

      // by changing the below code to various parts gives different effects.

     

      // Add fuel to the fire value on the scratch array.

      for(int x=0; x< firesizex; x+=2)

      {

            int y=firesizey-1;

           

            int fuel = firefield[ (y*firesizex) + x ] + (rand() % 64) - 32;

 

            if( fuel > 255 ) fuel = 255;

            if( fuel < 0 )   fuel = 0;

 

            firefield2[ (y*firesizex) + x ] = (unsigned char)fuel;

            firefield2[ (y*firesizex) + x + 1 ] = (unsigned char)fuel;

      }

}

[Edited by - Coder on March 4, 2005 6:08:50 AM]

Share this post


Link to post
Share on other sites
Advertisement
I can't help but think the Texcoords in your code are off.

Both because of the way theres a diagonal line across the fire you're drawing, and because in your code, you have 2 vertices in 2 different locations with the same Texcoords.

I must admit, I don't really understand most of that code, but I gather that basicly you're tring to draw a quad, and if you are, the texcoords just arn't right.


Hope this helps.

Share this post


Link to post
Share on other sites
Thanks both Sirob, and Coder.

Sirob: I'm not sure that I understand you. I drew out all of the vertices (6 of them), and the texture coordinates seems to be correct. When you say that two have the same textcoords, but different positions... I can't see that. What are you looking at? (I might be mistaken)

Any more advice?

Thanks!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement