Thread: Sun bursts and glows.

  1. #1
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607

    Sun bursts and glows.

    Ok, I tried to add a point sprite to my game engine and the code works. However, my goal was to put a 'sun' in my world and well it looks more like a moon.

    I want to create the star like glow around the sun and then blend it with the surrounding sky color and/or texture. Glow mapping is one idea, but I've not been able to understand exactly how to get it done.

    So if anyone understands the Direct3D SetTextureStageState() method for doing this, plz help me. My books are, at best, vague on this topic.


    Here is the code this far:

    CPointSprite.h
    Code:
    #include <d3dx9.h>
    #include <string>
    
    
    struct PointSpriteVertex
    {
      PointSpriteVertex(D3DXVECTOR3 pos,D3DCOLOR col,float sz):position(pos),pointsize(sz),color(col) {}
    
      D3DXVECTOR3         position;
      float		  pointsize;
      D3DCOLOR	  color;
      static const DWORD FVF;
    };
    
    
    class CPointSprite
    {
      protected:
        IDirect3DDevice9               *_device;
        D3DXVECTOR3		_position;
        D3DCOLOR		_col;
        IDirect3DTexture9             *_texture;
        IDirect3DVertexBuffer9      *_vb;
        D3DXMATRIX	                _worldpos;
      public:
        CPointSprite(void) {};
        ~CPointSprite(void);
    
        //
        //Init the point sprite
        //
        void Init(IDirect3DDevice9 *Device,
        std::string File,D3DCOLOR col,float sz,D3DXVECTOR3 pos);
        
        //
        //Render the point sprite
        //
        void Render(D3DXVECTOR3 &cameraPos);
    };
    CPointSprite.cpp
    Code:
    #include "CPointSprite.h"
    #include "d3dutility.h"
    
    const DWORD PointSpriteVertex::FVF=D3DFVF_XYZ | D3DFVF_DIFFUSE;
    
    CPointSprite::~CPointSprite(void)
    {
      _device=0;
      _texture=0;
      _vb=0;
    }
    
    void CPointSprite::Init(IDirect3DDevice9 *Device,
                                        std::string File,
    		    D3DCOLOR	col,
    		    float size,
    		    D3DXVECTOR3 pos)
    {
      _device=Device;
      _position=pos;
    	
      //
      //Create the texture
      //
      D3DXCreateTextureFromFile(Device,File.c_str(),&_texture);
      
      //
      //Position point sprite in the world
      //
      D3DXMatrixTranslation(&_worldpos,pos.x,pos.y,pos.z);
    
      //
      //Create Vertex Buffer
      //
      _device->CreateVertexBuffer(1*sizeof(PointSpriteVertex),
                                                     D3DUSAGE_POINTS,
    			PointSpriteVertex::FVF,
    			D3DPOOL_DEFAULT,
    			&_vb,
    			0);
       PointSpriteVertex *psv=0;
      
      //
      //Populate vertex buffer with data
      //
      _vb->Lock(0,0,(void **)&psv,0);
      psv[0]=PointSpriteVertex(pos,col,size);
      _vb->Unlock();
    
    }
    
    void CPointSprite::Render(D3DXVECTOR3 &cameraPos)
    {
      //
      //Set Translation according to camera
      //
      D3DXMATRIX w;
      D3DXMatrixTranslation
      (&w,cameraPos.x,cameraPos.y,cameraPos.z);
    
      //
      //Set world transform
      //
      _device->SetTransform(D3DTS_WORLD,&w);
    
      //
      //Enable point sprites
      //
      _device->SetRenderState(D3DRS_POINTSPRITEENABLE,true);
     
      //
      //Do not scale this sprite 
      //
      _device->SetRenderState(D3DRS_POINTSCALEENABLE,false);
    
      // 
      //Set sprite size in screen pixels
      //
      _device->SetRenderState(D3DRS_POINTSIZE,d3d::FtoDw(100.0f));
      
      //
      //Used for scaling point sprites - currently disabled
      //_device->SetRenderState(D3DRS_POINTSCALE_A,d3d::FtoDw(0.0f));
      //_device->SetRenderState(D3DRS_POINTSCALE_B,d3d::FtoDw(0.0f));
      //_device->SetRenderState(D3DRS_POINTSCALE_C,d3d::FtoDw(1.0f));
      //_device->SetRenderState(D3DRS_POINTSIZE_MIN,d3d::FtoDw(0.0f));
      //
    	
      //
      //Turn alpha blending on - currently disabled	
      //
      //_device->SetRenderState(D3DRS_ALPHABLENDENABLE,true);
    
      //
      //Set texture for point sprite
      //
      _device->SetTexture(0,_texture);
    	
      //
      //Setup texture stage states for glow mapping
      //
      //
      //Stage 0
      //
      _device->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
      _device->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
      _device->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
      _device->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
    
      //
      //Stage 1 color
      //  
      _device->SetTextureStageState(1,D3DTSS_COLORARG1,D3DTA_CURRENT);
      _device->SetTextureStageState(1,D3DTSS_COLORARG2,D3DTA_TEXTURE);
      _device->SetTextureStageState(1,D3DTSS_COLOROP,D3DTOP_ADD);
    	
      //
      //Stage 1 alpha
      //
      _device->SetTextureStageState(1,D3DTSS_ALPHAARG1,D3DTA_CURRENT);
      _device->SetTextureStageState(1,D3DTSS_ALPHAARG2,D3DTA_TEXTURE);
      _device->SetTextureStageState(1,D3DTSS_ALPHAOP,D3DTOP_ADD);
    
      //
      //Stage 2 - disable color/alpha blend
      //
      _device->SetTextureStageState(2,D3DTSS_COLOROP,D3DTOP_DISABLE);
      _device->SetTextureStageState(2,D3DTSS_ALPHAOP,D3DTOP_DISABLE);
    
      //
      //Turn D3D lighting on
      //
      _device->SetRenderState(D3DRS_LIGHTING,true);
    	
      //
      //Set Flexible Vertex Format to ours
      //
      _device->SetFVF(PointSpriteVertex::FVF);
    
      //
      //Set D3D stream source to our vertex buffer
      //
      _device->SetStreamSource(0,_vb,0,sizeof(PointSpriteVertex));
    
      //
      //Set texture 0 to ours
      //
      _device->SetTexture(0,_texture);
     
      //
      //Draw the stupid thing
      //
      _device->DrawPrimitive(D3DPT_POINTLIST,1,1);
    	
      //
      //Turn off alpha blending - currently disabled
      //
      //_device->SetRenderState(D3DRS_ALPHABLENDENABLE,false);
    }
    Last edited by VirtualAce; 04-15-2004 at 05:05 PM.

  2. #2
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    You should really read this paper:

    http://developer.nvidia.com/docs/IO/..._EffectsNV.pdf

    It describes the glow effect in the Tron game. It's a pretty easy effect to accomplish once you read the article. If you read it and still have questions I would be happy to answer them. Especially about things they gloss over like rendering to textures. I'm not sure if you're familiar with that. Anyways, good luck.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  3. #3
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Here is 1 sample I created from an article on gamedev.

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Also I took your advice concerning the texture transform's.

    It works great. Now my clouds move across the sky.


    By the way I'm using a single quad to represent the sky. Do you think this is ideal - in other words does it take longer for D3D to render my large quad than it would say several smaller quads?

    I could just make the sky plane a small mesh of quads with no height values - but it seems to me this would add more primitives.

    Also I downloaded that paper and it works great.

    Ok, now for water and adding DirectInput instead of the slow keyboard crap I have now. I'm getting 80 to 100 FPS but the game still hesitates when using the keyboard because of the latency in the Windows API GetAsyncKeyState().

    DirectInput, DirectSound, and DirectMusic are next.

  5. #5
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Quote Originally Posted by Bubba
    Also I took your advice concerning the texture transform's.

    It works great. Now my clouds move across the sky.


    By the way I'm using a single quad to represent the sky. Do you think this is ideal - in other words does it take longer for D3D to render my large quad than it would say several smaller quads?

    I could just make the sky plane a small mesh of quads with no height values - but it seems to me this would add more primitives.

    Also I downloaded that paper and it works great.

    Ok, now for water and adding DirectInput instead of the slow keyboard crap I have now. I'm getting 80 to 100 FPS but the game still hesitates when using the keyboard because of the latency in the Windows API GetAsyncKeyState().

    DirectInput, DirectSound, and DirectMusic are next.
    D3D Hates too many DrawPrimitive calls with a small amount of vertices. So just drawing one large textured quad as opposed to several smaller ones will be better for performance.

    Glad to hear the texture transformations worked out for you.

    Looking good so far, keep it up.
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  6. #6
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Another issue here is destination color keying. Quite simply D3D doesn't support it. So how do I render my flares and light source bitmaps w/o seing the big black ugly box?

    I've tried alpha blending and using the DX9 texture tool - convert the surface to ARGB8 and then load onto alpha channel the inverse of the image , but it alters the colors too much.

    I'm seriously considering dumping the point sprite for the sun. It seems that it is clamped to 64x64 pixels no matter what size I make it. This is not good on a 1024x768 or larger screen. Perhaps going back to the old billboard technique is the best solution here.

  7. #7
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Why don't you try using the native point sprites? They are very fast, I have used them in my particle systems in the past. As far as blending, try:

    // No z-writing for particles
    g_Graphics->SetRenderState( D3DRS_ZWRITEENABLE, FALSE );
    g_Graphics->SetRenderState( D3DRS_LIGHTING, FALSE );

    // Alpha blend the textures
    g_Graphics->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );

    if( m_Props.m_bFade )
    g_Graphics->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
    else
    g_Graphics->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );

    g_Graphics->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE );
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Here is another sample of the most recent build

    I'm not using alpha blending anymore for the sky.

    Here is my solution to creating a good sky from the same texture as the ground - although I will eventually create a cloud creator program that will create clouds for me.

    Code:
    ....
    _device->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
    _device->SetTextureStateState(0,D3DTSS_COLORARG2,D3DTA_TEXTURE);
    _device->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_ADD);
    ...
    ..Render
    Last edited by VirtualAce; 04-15-2004 at 10:04 PM.

  9. #9
    Registered User
    Join Date
    Mar 2004
    Posts
    50
    that looks good

    What kind of game are you making? sorry if you've explained it too many times, already.

    Are you doing it for fun or commercial gain ?

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    I am using native point sprites for the sun - but they seem clamped to 64x64 pixels which aint big enough.

    This 'game' is going to be whatever I can make it for. I doubt it will be good enough for commercial...but it might help me get into the industry if they see what I can do...and then again maybe it won't.
    Last edited by VirtualAce; 04-16-2004 at 02:41 AM.

  11. #11
    mov.w #$1337,D0 Jeremy G's Avatar
    Join Date
    Nov 2001
    Posts
    704
    I haven't used d3d since I discovered openGL to be far easier.
    So I cant give you technical pointers.
    However, I can give general idea that you may be able to convert.

    Considering the sun is only one entity, I don't see their being a problem with not using the point sprite class functionality. Just make your own helper functions to rotate a single quad polygon toward the camera. From there you can use this general forumala for a good "sun" effect.

    Draw the sun polygon just below your sky quad, distance = 1/2 width of sun polygon. // so rotation of polygon toward camera wont clip some of the edges against the sqy quad.

    Then draw N more triangles a very very small distance ahead of the first one, and slightly larger. N is based on performance VS. effect. 11 might be a nice effect, it really depends. Make sure every n'th additional polygon is slightly larger then the last one.

    With the polygons being blended together you will create a blur of the sprite (which is appropriate when you look at the sun its not defined, its very guassian.

    The blending method should be additional, so black is just transparent, but any color should be added to the current pixel value. (Createing the white out you usualy see when looking toward the sun). I have no idea which d3d alpha blend method this is.

    Hopefully that helps ya. BTW, lookin good so far.
    c++->visualc++->directx->opengl->c++;
    (it should be realized my posts are all in a light hearted manner. And should not be taken offense to.)

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Well I'm going to keep the CPointSprite class except that all of these bases will have a virtual function called prerender that will setup all the Direct3D testure and render states. My goal is to draw all the alpha blended objects together, switch back to non-alpha blending, and then draw the rest.

    But I will have to make a CBillboard class for billboarding large point sprites. The CPointSprite class is not useless but being clamped to 64 or 128 pixels is simply not big enough for certain special effects. Plus, I need billboard functionality to populate the ground with bushes, grass, and other foliage.

    CBillboard does have some of the same functionality of CPointSprite but they differ so much in the method that I'm going to make them totally independent of each other.

    My next step really is animated sprites...among other things I want to get working.

Popular pages Recent additions subscribe to a feed