Демонстрационный код
От: Northaunt  
Дата: 27.07.10 10:52
Оценка: 7 (3)
Я начинающий программист на С++, ищу работу. Часто просят отослать пример кода. Вот только, после того как я пересылаю его, на другой стороне полная тишина. Я каждый раз объяснял, что сложных, хорошо написанных и спроектированных программ у меня нет (мои проекты связаны с 3D графикой, я акцентировал усилия только на ней, к сожалению) и просил тестовое задание, но не помогало. Посмотрите, пожалуйста, кто-нибудь код и укажите на самые фатальные ошибки, из-за которых меня сразу же посылали в черный список. Всего два класса. Все действия, которые там есть, это: инициализировать нужные ресурсы, установить различные состояния для отрисовки, посчитать и отрендерить, что нужно, затем удалить навсегда.


Fluid.h
#ifndef __Fluid_H__
#define __Fluid_H__
//-------------------------------------------------------------------------


#include <d3dx9.h>
#include <math.h>
#include <string>
#include "..\..\- Mein\GameApp.h"
#include "..\..\Service\Service.h"

using std::string;
//-------------------------------------------------------------------------



//---------------------------------------------
//Fluid Navie-Stocks 3D Solver on GPU
//---------------------------------------------
class Fluid3D
{
public:

    //Create and Clean
    Fluid3D    ();
    ~Fluid3D();

    
    //Setup
    void SetEffectValues    (float TimeScale);
    void InitTextures        ();
    void InitVertexBuffers    ();

    
    //Computation
    void Update                (float TimeScale);
    void ComputeStep        (IDirect3DTexture9* renderTarget, string technique);
    void ComputeBorders        (IDirect3DTexture9* renderTarget, string technique);


    //Service
    void CopyTexture                (IDirect3DTexture9* destinationTex, IDirect3DTexture9* sourceTex);
    void ClearTexture                (IDirect3DTexture9* texture);
    void SetScreenFillingTransform    (bool set);
    void RenderTextureToScreen        (IDirect3DTexture9* texture, D3DXVECTOR3 pos);
    void ChechTechnique                (HRESULT Result, string& technique);
    void ChechTextureValues            (IDirect3DTexture9* texture);
    void Debug                        ();


    //Get
    IDirect3DTexture9*    GetVelocity()    {return Velocity;}
    IDirect3DTexture9*    GetDensity()    {return Density;}
    IDirect3DTexture9*    GetPreassure()    {return Pressure;}
    IDirect3DTexture9*    GetDivergence()    {return Divergence;}
    IDirect3DTexture9*    GetVorticity()    {return Vorticity;}
    IDirect3DTexture9*    GetZLookup()    {return ZLookup;}


private:

    //Effect
    ID3DXEffect* FluidEffect;


    //Textures
    IDirect3DTexture9* Velocity;
    IDirect3DTexture9* Pressure;
    IDirect3DTexture9* Density;
    IDirect3DTexture9* Divergence;
    IDirect3DTexture9* Vorticity;

    IDirect3DTexture9* TemporaryRenderTarget;
    IDirect3DSurface9* RenderSurface;
    IDirect3DSurface9* BackBuffer;
    IDirect3DTexture9* ZLookup;


    //Geometry
    IDirect3DVertexBuffer9* QuadVB;
    IDirect3DVertexBuffer9* QuadsArrayVB;
    IDirect3DVertexBuffer9* BorderLinesVB;
    IDirect3DVertexBuffer9* BorderLinesArrayVB;

    
    //Parameters
    static const int GridSize3D = 64;
    static const int GridSize2D = 512; 
    static const int JacobiIterations = 20;
    float VolumeSize;
    float Viscosity;
    float GridScale;
    float SqrGridScale;

};




//---------------------------------------------
//Fluid Volume Render
//---------------------------------------------
class RayCasting
{
public:

    //Create and Clean
    RayCasting();
    ~RayCasting();


    //Render all
    void Render(float TimeScale);
    void RenderTexture(IDirect3DTexture9* texture, D3DXVECTOR3 Position, float timeDelta);


private:

    //Render It
    Fluid3D Fluid;


    //Effects
    ID3DXEffect* RayCastingEffect;


    //Position of Fluid
    D3DXVECTOR3 Position;


    //Textures 
    LPDIRECT3DSURFACE9 BackBuffer;
    LPDIRECT3DTEXTURE9 BackfacesTexture;
    LPDIRECT3DSURFACE9 BackfacesSurface;
    LPDIRECT3DTEXTURE9 FluidTexture;
    LPDIRECT3DSURFACE9 FluidSurface;
    

    //Volumes
    IDirect3DVertexBuffer9* BoundingBoxVB;
    IDirect3DIndexBuffer9*  BoundingBoxIB;
    IDirect3DVertexBuffer9* QuadVB;
    
};




//---------------------------------------------
//Vertecies Strucutres
//---------------------------------------------

//VertexColored Structure
struct VertexColored
{
    VertexColored(float x, float y, float z, float u, float v, D3DCOLOR c)
    {
        _x = x;     _y = y;  _z = z;  
        _color = c;
    }

    float _x, _y, _z;
    D3DCOLOR _color;        
    

    static const DWORD FVF = D3DFVF_XYZ | D3DFVF_DIFFUSE ; 
};


//VertexTextured Structure
struct VertexTextured 
{ 
 
    VertexTextured(float x, float y, float z, float u, float v) 
    { 
      _x = x; _y = y; _z = z; 
      _u = u, _v = v; 
    } 

    float _x, _y, _z; 
    float _u, _v; 

    static const DWORD FVF = D3DFVF_XYZ | D3DFVF_TEX1; 
}; 



//VertexTextured Structure
struct Vertex3DTextured 
{ 
 
    Vertex3DTextured(float x, float y, float z, float u, float v, float w) 
    { 
      _x = x; _y = y; _z = z; 
      _u = u, _v = v; _w = w;
    } 

    float _x, _y, _z; 
    float _u, _v, _w;

    static const DWORD FVF = D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0); 
}; 


#endif // __Fluid_H__




Fluid.cpp
#include "Fluid.h"

using GameApp::Device;




//-------------------------------------------------------------------------
//
//        Fluid3D Solver
//
//-------------------------------------------------------------------------


//-------------------------------------------------------------------------
//    Fluid class Constructor
//-------------------------------------------------------------------------
Fluid3D::Fluid3D()
{
    //Attributes
    Viscosity        = 50.0f;
    VolumeSize        = 2.0f; //Change ?
    GridScale        = 1.0f;
    SqrGridScale    = pow( GridScale /*VolumeSize / GridSize*/, 2.0f);


    //Effect Setup     
    HRESULT Result = 0;
    ID3DXBuffer* errorBuffer = 0; 

    Result = D3DXCreateEffectFromFile(Device,"- Sources/Mechanic/Fluid/Fluid.fx", 0, 0, D3DXSHADER_DEBUG, 0, &FluidEffect, &errorBuffer);  

    if(errorBuffer) 
    { 
        ::MessageBox(0, (char*)errorBuffer->GetBufferPointer(),0, 0); 
        GameApp::Release<ID3DXBuffer*>(errorBuffer); 
    } 
    
    if(FAILED(Result)) 
    { 
        ::MessageBox(0, "D3DXCreateEffectFromFile() - FAILED", 0, 0); 
        return;
    } 


    //Init Vertex Buffers
    InitVertexBuffers();


    //Init Textures
    InitTextures();

}



//-------------------------------------------------------------------------
//    Init Vertex Buffers
//-------------------------------------------------------------------------
void Fluid3D::InitVertexBuffers()
{

    //-----------------------------------
    //Textured Quad Verticies
    //-----------------------------------
    Device->CreateVertexBuffer(6 * sizeof(VertexTextured), D3DUSAGE_WRITEONLY, VertexTextured::FVF, D3DPOOL_MANAGED, &QuadVB, 0);
    VertexTextured* verticesTex;
    QuadVB->Lock(0, 0, (void**)&verticesTex, 0);

    float x = 1.0f;
    float y = 1.0f;
    verticesTex[0] = VertexTextured(-x, -y, 0.0f, 0.0f, 1.0f);
    verticesTex[1] = VertexTextured(-x,  y, 0.0f, 0.0f, 0.0f);
    verticesTex[2] = VertexTextured( x,  y, 0.0f, 1.0f, 0.0f);
    verticesTex[3] = VertexTextured(-x, -y, 0.0f, 0.0f, 1.0f);
    verticesTex[4] = VertexTextured( x,  y, 0.0f, 1.0f, 0.0f);
    verticesTex[5] = VertexTextured( x, -y, 0.0f, 1.0f, 1.0f);
    
    QuadVB->Unlock();




    //-----------------------------------
    //Textured Quads Array Verticies 64x64 for Flat3D Texture
    //-----------------------------------
    Device->CreateVertexBuffer( 6 * GridSize3D * sizeof(Vertex3DTextured), D3DUSAGE_WRITEONLY, Vertex3DTextured::FVF, D3DPOOL_MANAGED, &QuadsArrayVB, 0 );
    Vertex3DTextured* verticesTex3D;

    float quadSize = 1.0f;
    float pixelSize = quadSize / GridSize3D;
    float sliceSize = sqrt((float)GridSize3D);
    
    float sliceOffset = quadSize / sliceSize;
    float sliceOffsetX = sliceOffset;
    float sliceOffsetY = sliceOffset;
    float sliceOffsetZ = 0.5f / GridSize3D;
    
    int index = 0;
    x = -0.5f;
    y = -0.5f;
    float xT = 0.0f;
    float yT = 0.0f;
    
    
    QuadsArrayVB->Lock(0, 0, (void**)&verticesTex3D, 0);
    for (int i = 0; i < sliceSize; i++)
    {
        for (int j = 0; j < sliceSize; j++)
        {
            verticesTex3D[index++] = Vertex3DTextured( x,                    y,                    0.0f, xT,                    yT,                        sliceOffsetZ );
            verticesTex3D[index++] = Vertex3DTextured( x,                    y + sliceOffsetY,    0.0f, xT,                    yT + sliceOffsetY,        sliceOffsetZ );
            verticesTex3D[index++] = Vertex3DTextured( x + sliceOffsetX,    y,                    0.0f, xT + sliceOffsetX,    yT,                        sliceOffsetZ );
            verticesTex3D[index++] = Vertex3DTextured( x + sliceOffsetX,    y,                    0.0f, xT + sliceOffsetX,    yT,                        sliceOffsetZ );
            verticesTex3D[index++] = Vertex3DTextured( x,                    y + sliceOffsetY,    0.0f, xT,                    yT + sliceOffsetY,        sliceOffsetZ );
            verticesTex3D[index++] = Vertex3DTextured( x + sliceOffsetX,    y + sliceOffsetY,    0.0f, xT + sliceOffsetX,    yT + sliceOffsetY,        sliceOffsetZ );

            //Next quad in Row
            x += quadSize / sliceSize;
            xT += quadSize / sliceSize;
            sliceOffsetZ += quadSize / GridSize3D;
        }

        //Next Column
        x = -0.5f;
        xT = 0.0f;
        y += quadSize / sliceSize;
        yT += quadSize / sliceSize;
        
    }
    QuadsArrayVB->Unlock();




    //-----------------------------------
    //Border Lines Verticies
    //-----------------------------------
    Device->CreateVertexBuffer(8 * sizeof(VertexTextured), D3DUSAGE_WRITEONLY, VertexTextured::FVF, D3DPOOL_MANAGED, &BorderLinesVB, 0);
    BorderLinesVB->Lock(0, 0, (void**)&verticesTex, 0);

    //Left
    verticesTex[0] = VertexTextured(-1.0f, -1.0f, 0.0f,    1.0f, 0.0f);
    verticesTex[1] = VertexTextured(-1.0f,  1.0f, 0.0f,    1.0f, 0.0f);
    
    //Right
    verticesTex[2] = VertexTextured(1.0f,  1.0f, 0.0f, -1.0f, 0.0f);
    verticesTex[3] = VertexTextured(1.0f, -1.0f, 0.0f, -1.0f, 0.0f);

    ////Botttom
    verticesTex[6] = VertexTextured( 1.0f, -1.0f, 0.0f, 0.0f, 1.0f);
    verticesTex[7] = VertexTextured(-1.0f, -1.0f, 0.0f, 0.0f, 1.0f);

    ////Top
    verticesTex[4] = VertexTextured(-1.0f, 1.0f, 0.0f, 0.0f, -1.0f);
    verticesTex[5] = VertexTextured( 1.0f, 1.0f, 0.0f, 0.0f, -1.0f);

    BorderLinesVB->Unlock();



    //-----------------------------------
    //Border Lines Array Verticies
    //-----------------------------------
    Device->CreateVertexBuffer(8 * GridSize3D * sizeof(VertexTextured), D3DUSAGE_WRITEONLY, VertexTextured::FVF, D3DPOOL_MANAGED, &BorderLinesArrayVB, 0);
    BorderLinesArrayVB->Lock(0, 0, (void**)&verticesTex, 0);
    
    quadSize = 1.0f;
    sliceSize = sqrt((float)GridSize3D);
    pixelSize = quadSize / GridSize2D / 1.0;
    sliceOffset = quadSize / sliceSize - 2 * pixelSize;
    
    x = -quadSize / 2.0 + pixelSize;
    y = -quadSize / 2.0 + pixelSize;
    index = 0;

    for (int i = 0; i < sliceSize; i++)
    {
        for (int j = 0; j < sliceSize; j++)
        {
        
            //Left
            verticesTex[index++] = VertexTextured(x, y,                                    0.0f,    1.0f, 0.0f);
            verticesTex[index++] = VertexTextured(x, y + sliceOffset,                    0.0f,    1.0f, 0.0f);
            
            //Right
            verticesTex[index++] = VertexTextured(x + sliceOffset, y + sliceOffset,        0.0f, -1.0f, 0.0f);
            verticesTex[index++] = VertexTextured(x + sliceOffset, y,                    0.0f, -1.0f, 0.0f);

            ////Botttom
            verticesTex[index++] = VertexTextured(x + sliceOffset,    y,                    0.0f, 0.0f, 1.0f);
            verticesTex[index++] = VertexTextured(x,                y,                    0.0f, 0.0f, 1.0f);

            ////Top
            verticesTex[index++] = VertexTextured(x,                y + sliceOffset,    0.0f, 0.0f, -1.0f);
            verticesTex[index++] = VertexTextured(x + sliceOffset,    y + sliceOffset,    0.0f, 0.0f, -1.0f);


            //Next quad
            x += quadSize / sliceSize ;
        }

        //Next column
        x = -quadSize / 2.0 + pixelSize;
        y += quadSize / sliceSize /*+ 2 * pixelSize*/;

    }
    BorderLinesArrayVB->Unlock();
    
}



//-------------------------------------------------------------------------
//    Init Textures
//-------------------------------------------------------------------------
void Fluid3D::InitTextures()
{
    Device->GetRenderTarget(0,&BackBuffer);

    Device->CreateTexture(GridSize2D, GridSize2D, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &Velocity, NULL);
    Device->CreateTexture(GridSize2D, GridSize2D, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &Pressure, NULL);
    Device->CreateTexture(GridSize2D, GridSize2D, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &Density, NULL);
    Device->CreateTexture(GridSize2D, GridSize2D, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &Divergence, NULL);
    Device->CreateTexture(GridSize2D, GridSize2D, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &Vorticity, NULL);
    Device->CreateTexture(GridSize2D, GridSize2D, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &TemporaryRenderTarget, NULL);
    
    ClearTexture(Velocity);
    ClearTexture(Pressure);
    ClearTexture(Density);
    ClearTexture(Divergence);    
    ClearTexture(Vorticity);
    ClearTexture(TemporaryRenderTarget);


        

    //------------------------------------
    //Lookup Tex for Z coord in shader
    //------------------------------------
    IDirect3DTexture9* ZLookupInSystemPool; //To use LockRect in System memory
    int height = 1; // Height for 1D texture


    //Create Lookup texture and its copy in System memory
    Device->CreateTexture(GridSize3D, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A32B32G32R32F, D3DPOOL_DEFAULT,        &ZLookup, NULL);
    Device->CreateTexture(GridSize3D, height, 1, D3DUSAGE_DYNAMIC,        D3DFMT_A32B32G32R32F, D3DPOOL_SYSTEMMEM,    &ZLookupInSystemPool, NULL);
    
    D3DLOCKED_RECT lockedRect; 
    ZLookupInSystemPool->LockRect( 0, &lockedRect, 0, 0);
    D3DXVECTOR4* imageData = (D3DXVECTOR4*)lockedRect.pBits; 

    //Copy offset values from VB
    Vertex3DTextured* verticesTex3D;
    QuadsArrayVB->Lock(0, 0, (void**)&verticesTex3D, 0);

    for (int i = 0, iV = 0; i < GridSize3D; i++)
    {
        imageData[i] = D3DXVECTOR4(verticesTex3D[iV]._x + 0.5f, 0.875f - (verticesTex3D[iV]._y + 0.5f), 0.0f, 0.0f);
        iV += 6;//Next Quad
    }
    
    QuadsArrayVB->Unlock();
    ZLookupInSystemPool->UnlockRect(0); 

    
    //Copy form System to Video memory
    Device->UpdateTexture(ZLookupInSystemPool, ZLookup);
    GameApp::Release<IDirect3DTexture9*>(ZLookupInSystemPool);

}




//-------------------------------------------------------------------------
//    Fluid class Destructor
//-------------------------------------------------------------------------
Fluid3D::~Fluid3D()
{
    //Free all Textures
    GameApp::Release<IDirect3DTexture9*>(Velocity);
    GameApp::Release<IDirect3DTexture9*>(Pressure);
    GameApp::Release<IDirect3DTexture9*>(Density);
    GameApp::Release<IDirect3DTexture9*>(ZLookup);
    GameApp::Release<IDirect3DTexture9*>(Divergence);
    GameApp::Release<IDirect3DTexture9*>(TemporaryRenderTarget);
    GameApp::Release<IDirect3DSurface9*>(BackBuffer);
    GameApp::Release<IDirect3DSurface9*>(RenderSurface);

    //Free all Vertex Buffers
    GameApp::Release<IDirect3DVertexBuffer9*>(QuadVB);
    GameApp::Release<IDirect3DVertexBuffer9*>(QuadsArrayVB);
    GameApp::Release<IDirect3DVertexBuffer9*>(BorderLinesVB);

    //Free all Effects
    GameApp::Release<ID3DXEffect*>(FluidEffect);
}




//-------------------------------------------------------------------------
//    Setup Effect
//-------------------------------------------------------------------------
void Fluid3D::SetEffectValues(float TimeScale)
{
    //Fluid Parameters
    FluidEffect->SetFloat("Timestep",    1.0f * (TimeScale * 10.0f)); //TimeScale * 50.0f
    FluidEffect->SetFloat("Rdx",        5.0f);
    FluidEffect->SetFloat("HalfRdx",    0.5f / 1.0f);
    FluidEffect->SetFloat("DXscale",    1.0f );// / GridSize
    FluidEffect->SetFloat("GridSize2D",    GridSize2D);
    FluidEffect->SetFloat("GridSize3D",    GridSize3D);
    FluidEffect->SetFloat("Scale",        1.0f);
    

    //Controls
    FluidEffect->SetFloat("XForce", 0.0f);
    FluidEffect->SetFloat("YForce", 0.0f);
    FluidEffect->SetFloat("ZForce", 0.0f);
    
    float force = 5.0f;
    if (::GetAsyncKeyState(VK_LEFT) & 0x8000f )        FluidEffect->SetFloat("XForce", -force);    
    if (::GetAsyncKeyState(VK_RIGHT) & 0x8000f )    FluidEffect->SetFloat("XForce", force);                
    if (::GetAsyncKeyState(VK_UP) & 0x8000f )        FluidEffect->SetFloat("YForce", force);            
    if (::GetAsyncKeyState(VK_DOWN) & 0x8000f )        FluidEffect->SetFloat("YForce", -force);    
    if (::GetAsyncKeyState(VK_END) & 0x8000f )        FluidEffect->SetFloat("ZForce", -force);


    //View in Vertex Shader
    float dist = 1.0f;
    static D3DXMATRIX orthoProj = *D3DXMatrixOrthoLH(&orthoProj, dist, dist, 1.0f, 1000.0f);
    static D3DXMATRIX translation    = *D3DXMatrixTranslation(&translation, 0.0f, 0.0f, 10.0f);
    FluidEffect->SetMatrix( "ModelViewProj", &(translation * orthoProj) );//translation * invView * view * orthoProj

    //Effect uniform samplers
    FluidEffect->SetTexture("VelocityTex", Velocity);
    FluidEffect->SetTexture("PressureTex", Pressure);
    FluidEffect->SetTexture("DensityTex", Density);
    FluidEffect->SetTexture("DivergenceTex", Divergence);
    FluidEffect->SetTexture("VorticityTex", Vorticity);
    FluidEffect->SetTexture("ZLookupTex", ZLookup);
}





//-------------------------------------------------------------------------
//    Fluid Update
//-------------------------------------------------------------------------
void Fluid3D::Update(float TimeScale)
{
    SetEffectValues(TimeScale);


    //----------------------------------------
    //Advection
    //----------------------------------------
    //Advection of Velocity
    FluidEffect->SetFloat( "Dissipation", 1.0f);
    ComputeStep(Velocity, "AdvectionVelocityStep");
    

    //Advection of Density
    FluidEffect->SetFloat( "Dissipation", 0.99f);
    ComputeStep(Density, "AdvectionDensityStep");



    //----------------------------------------
    //Add
    //----------------------------------------
    //Force
    ComputeStep(Velocity, "ForceStep");
    
    //Density
    if (true || ::GetAsyncKeyState(VK_SPACE)) 
    {
        ComputeStep(Density, "DensityStep");
    }
    


    //----------------------------------------
    //Diffusion
    //----------------------------------------
    //Velocity
    Viscosity    = 20.0f;
    FluidEffect->SetFloat( "Alpha", SqrGridScale / (Viscosity * TimeScale) );
    FluidEffect->SetFloat( "RBeta", 1.0f / (6.0f + SqrGridScale / (Viscosity * TimeScale)) );
    for (int i = 0; i < 25 /*JacobiIterations*/; i++)
    {
        ComputeStep(Velocity, "DiffuseStep");
    }
    

    //Density
    Viscosity    = 0.0001f;
    FluidEffect->SetFloat( "Alpha", SqrGridScale / (Viscosity * TimeScale) );
    FluidEffect->SetFloat( "RBeta", 1.0f / (4.0f + SqrGridScale / (Viscosity * TimeScale)) );
    for (int i = 0; i < JacobiIterations; i++)
    {
        ComputeStep(Density, "DiffuseDensityStep");
    }


    //----------------------------------------
    //    Projection
    //----------------------------------------
    ClearTexture(Pressure);

    //Divergence of W
    ComputeStep(Divergence, "DivergenceStep");

    //Poisson solve for P
    FluidEffect->SetFloat( "Alpha", -SqrGridScale );
    FluidEffect->SetFloat( "RBeta", 0.16f );

    for (int i = 0; i < JacobiIterations; i++)
    {
        ComputeStep(Pressure, "PoissonSolveStep");
    }

    //Gradient
    ComputeStep(Velocity, "GradientStep");


    //----------------------------------------
    //Vorticity 
    //----------------------------------------
    //Compute scalar Vorticity field
    ComputeStep(Vorticity, "VorticityStep");

    //Vorticity Force
    ComputeStep(Velocity, "VorticityForceStep");



    //Borders
    ComputeBorders(Velocity, "BoundaryVelocity");
    ComputeBorders(Pressure, "BoundaryPressure");



    //----------------------------------------
    //Debug 
    //----------------------------------------
    //Debug();

    //FluidEffect->SetFloat("ScaleColor", true);    RenderTextureToScreen(Velocity,        D3DXVECTOR3( 4.0, 3.0f, 0.0f));
    FluidEffect->SetFloat("ScaleColor", false);    RenderTextureToScreen(Density,        D3DXVECTOR3( 8.0, 3.0f, 0.0f));
    //RenderTextureToScreen(Vorticity,    D3DXVECTOR3( 2.5, 1.5f, 3.0f));
    //RenderTextureToScreen(ZLookup,    D3DXVECTOR3(-2.5, 1.5f, 3.0f));
}



//-------------------------------------------------------------------------
//    Computational step in Fluid (Init, Compute, Clean)
//-------------------------------------------------------------------------
void Fluid3D::ComputeStep(IDirect3DTexture9* renderTarget, string technique)
{    
    //Render in Temporary texture
    TemporaryRenderTarget->GetSurfaceLevel(0, &RenderSurface);
    Device->SetRenderTarget(0, RenderSurface);
    //Device->SetRenderTarget(0, BackBuffer);
    Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_XRGB(200,200,55), 1.0f, 0);
    
    //Computation Step
    ChechTechnique( FluidEffect->SetTechnique(technique.c_str()), technique );
    FluidEffect->Begin(0, 0);
    FluidEffect->BeginPass(0);     
    
    Device->SetFVF(Vertex3DTextured::FVF);
    Device->SetStreamSource(0, QuadsArrayVB, 0, sizeof(Vertex3DTextured));
    Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, GridSize3D * 2.0);
    
    FluidEffect->EndPass();
    FluidEffect->End();


    //Copy Temporary tex to Output tex
    CopyTexture(renderTarget, TemporaryRenderTarget);


    //Restore States
    Device->SetRenderTarget(0, BackBuffer);

    //Debug
    //ChechTextureValues(renderTarget);
    //GameApp::SceneRender(0.01); 
}



//-------------------------------------------------------------------------
//    Activate Borders
//-------------------------------------------------------------------------
void Fluid3D::ComputeBorders(IDirect3DTexture9* renderTarget, string technique)
{
    //Render in Temporary texture
    TemporaryRenderTarget->GetSurfaceLevel(0, &RenderSurface);
    Device->SetRenderTarget(0, RenderSurface);
    
    ChechTechnique( FluidEffect->SetTechnique(technique.c_str()), technique );

    FluidEffect->Begin(0, 0);
    FluidEffect->BeginPass(0);     
    
    Device->SetFVF(VertexTextured::FVF);
    Device->SetStreamSource(0, BorderLinesArrayVB, 0, sizeof(VertexTextured));
    Device->DrawPrimitive(D3DPT_LINELIST, 0, 4 * GridSize3D);

    FluidEffect->EndPass();
    FluidEffect->End();


    //Copy Temporary tex to Output tex
    CopyTexture(renderTarget, TemporaryRenderTarget);


    //Restore States
    Device->SetRenderTarget(0, BackBuffer);
}




//-------------------------------------------------------------------------
//
//        Fluid3D::Service
//
//-------------------------------------------------------------------------



//-------------------------------------------------------------------------
//    ClearTexture
//-------------------------------------------------------------------------
void Fluid3D::ClearTexture(IDirect3DTexture9* texture)
{
    texture->GetSurfaceLevel(0, &RenderSurface);
    Device->SetRenderTarget(0, RenderSurface);
    Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, 0x00000000, 1.0f, 0);
    
    Device->SetRenderTarget(0, BackBuffer);
}



//-------------------------------------------------------------------------
//    Copy Textures
//-------------------------------------------------------------------------
void Fluid3D::CopyTexture(IDirect3DTexture9* destinationTex, IDirect3DTexture9* sourceTex)
{
    //Set destinationTex as Render Terget
    IDirect3DSurface9* destinationSurface;
    destinationTex->GetSurfaceLevel(0, &destinationSurface);
    Device->SetRenderTarget(0, destinationSurface);
    Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_XRGB(150,150,55), 1.0f, 0);

    FluidEffect->SetTexture("CopySourceTex", sourceTex);

    //Draw in Render Terget
    FluidEffect->SetTechnique("CopyTexture"); 
    FluidEffect->Begin(0, 0);
    FluidEffect->BeginPass(0); 
    
    Device->SetStreamSource(0, QuadVB, 0, sizeof(VertexTextured));
    Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

    FluidEffect->EndPass();
    FluidEffect->End();


    //Clean
    GameApp::Release<IDirect3DSurface9*>(destinationSurface);
}


//-------------------------------------------------------------------------
//    Screen Filling Transform
//-------------------------------------------------------------------------
void Fluid3D::SetScreenFillingTransform(bool isTransformSet)
{
    static float viewSize                = 1.0f;
    static D3DXMATRIX matProjection        = *D3DXMatrixOrthoLH(&matProjection, viewSize, viewSize, 1.0f, 1000.0f); 
    static D3DXMATRIX matOldProjection    = GameApp::m_pCamera->GetProjMatrix();
    static D3DXMATRIX translation        = *D3DXMatrixTranslation(&translation, 0.0f, 0.0f, 10.0f);


    if (isTransformSet)
    {
        //Set texture to filling viewport
        D3DXMATRIX invView = *D3DXMatrixInverse( &invView, 0, &GameApp::m_pCamera->GetViewMatrix() );
        Device->SetTransform(D3DTS_PROJECTION, &matProjection);
        Device->SetTransform( D3DTS_WORLD, &(translation * invView) );
    }
    else
    {    
        //Return Perpective projection
        Device->SetTransform(D3DTS_PROJECTION,&matOldProjection);
    }
}



//-------------------------------------------------------------------------
//    Render Texture To Screen
//-------------------------------------------------------------------------
void Fluid3D::RenderTextureToScreen(IDirect3DTexture9* texture, D3DXVECTOR3 position)
{
    D3DXMATRIX translation = *D3DXMatrixTranslation( &translation, position.x, position.y, position.z );
    D3DXMATRIX view = GameApp::m_pCamera->GetViewMatrix();
    static D3DXMATRIX proj = GameApp::m_pCamera->GetProjMatrix();
    static D3DXMATRIX scale = *D3DXMatrixScaling(&scale, scaleFactor, scaleFactor, 0);
    static D3DXMATRIX rotate = *D3DXMatrixRotationY(&rotate, 3.14 / 2.0);


    Device->Clear(0, 0,  D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(100,100,55), 1.0f, 0);
    Device->SetRenderTarget(0, BackBuffer);

    FluidEffect->SetMatrix( "ModelViewProj", &(scale * rotate * translation * view * proj) );
    FluidEffect->SetTexture("TextureToScreenTex", texture);

    FluidEffect->SetTechnique("RenderTextureToScreen"); 
    FluidEffect->Begin(0, 0);
    FluidEffect->BeginPass(0); 

    Device->SetStreamSource(0, QuadVB, 0, sizeof(VertexTextured));
    Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

    FluidEffect->EndPass();
    FluidEffect->End();
}

//-------------------------------------------------------------------------
//    Chech Technique
//-------------------------------------------------------------------------
void Fluid3D::ChechTechnique(HRESULT Result, string& technique)
{
    if(FAILED(Result))
    {
        ::MessageBox(0, technique.c_str(), 0, 0); 
        return;
    }
}


//-------------------------------------------------------------------------
//    Debug
//-------------------------------------------------------------------------
void Fluid3D::Debug ()
{
    IDirect3DTexture9* renderTex;
    Device->CreateTexture(GridSize2D, GridSize2D, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16F, D3DPOOL_DEFAULT, &renderTex, NULL);


    //Render in Temporary texture
    renderTex->GetSurfaceLevel(0, &RenderSurface);
    Device->SetRenderTarget(0, RenderSurface);

    float dist = 1.0f;
    static D3DXMATRIX orthoProj = *D3DXMatrixOrthoLH(&orthoProj, dist, dist, 1.0f, 1000.0f);
    static D3DXMATRIX translation    = *D3DXMatrixTranslation(&translation, 0.0f, 0.0f, 10.0f);
    FluidEffect->SetMatrix( "ModelViewProj", &(translation * orthoProj) );//translation * invView * view * orthoProj

    //Computation Step
    FluidEffect->SetTechnique("Debug");
    FluidEffect->Begin(0, 0);
    FluidEffect->BeginPass(0);     
    
    Device->SetFVF(Vertex3DTextured::FVF);
    Device->SetStreamSource(0, QuadsArrayVB, 0, sizeof(Vertex3DTextured));
    Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, GridSize3D * 2.0);
    
    FluidEffect->EndPass();
    FluidEffect->End();

    //Render results
    RenderTextureToScreen(renderTex,    D3DXVECTOR3(0.0, 6.0f, 3.0f));

    //Clean
    GameApp::Release<IDirect3DTexture9*>(renderTex);
}








//-------------------------------------------------------------------------
//
//        Ray Casing Render
//
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
//    Ray Casing Constructor
//-------------------------------------------------------------------------
RayCasting::RayCasting()
{
    BackfacesTexture = NULL;
    BackfacesSurface = NULL;
    FluidTexture = NULL;
    FluidSurface = NULL;
    BackBuffer = NULL;
    VolumeTexture = NULL;

    Device->GetRenderTarget(0,&BackBuffer);

    Device->CreateTexture(512, 512,1,D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &BackfacesTexture, NULL);
    BackfacesTexture->GetSurfaceLevel(0, &BackfacesSurface);

    Device->CreateTexture(512, 512,1,D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &FluidTexture, NULL);
    FluidTexture->GetSurfaceLevel(0, &FluidSurface);
    
    

    //-------------------------------
    //Geometry
    //-------------------------------

    //Bounding Box Verticies
    Device->CreateVertexBuffer(8 * sizeof(VertexColored), D3DUSAGE_WRITEONLY, VertexColored::FVF, D3DPOOL_MANAGED, &BoundingBoxVB, 0);
    Device->CreateIndexBuffer (36 * sizeof(WORD), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &BoundingBoxIB, 0);

    VertexColored* vertices;
    BoundingBoxVB->Lock(0, 0, (void**)&vertices, 0);
    
    int size = 4.0f;
    vertices[0] = VertexColored(-size, -size, -size, 0.0f, 0.0f, D3DXCOLOR(D3DXVECTOR3(-1.0f, -1.0f, -1.0f)));
    vertices[1] = VertexColored(-size,  size, -size, 0.0f, 0.0f, D3DXCOLOR(D3DXVECTOR3(-1.0f,  1.0f, -1.0f)));
    vertices[2] = VertexColored( size,  size, -size, 0.0f, 0.0f, D3DXCOLOR(D3DXVECTOR3( 1.0f,  1.0f, -1.0f)));
    vertices[3] = VertexColored( size, -size, -size, 0.0f, 0.0f, D3DXCOLOR(D3DXVECTOR3( 1.0f, -1.0f, -1.0f)));
    vertices[4] = VertexColored(-size, -size,  size, 0.0f, 0.0f, D3DXCOLOR(D3DXVECTOR3(-1.0f, -1.0f,  1.0f)));
    vertices[5] = VertexColored(-size,  size,  size, 0.0f, 0.0f, D3DXCOLOR(D3DXVECTOR3(-1.0f,  1.0f,  1.0f)));
    vertices[6] = VertexColored( size,  size,  size, 0.0f, 0.0f, D3DXCOLOR(D3DXVECTOR3( 1.0f,  1.0f,  1.0f)));
    vertices[7] = VertexColored( size, -size,  size, 0.0f, 0.0f, D3DXCOLOR(D3DXVECTOR3( 1.0f, -1.0f,  1.0f)));

    BoundingBoxVB->Unlock();

    
    //Bounding Box Indices
    WORD* indices = 0;
    BoundingBoxIB->Lock(0, 0, (void**)&indices, 0);

    indices[0]  = 0; indices[1]  = 1; indices[2]  = 2;    indices[3]  = 0; indices[4]  = 2; indices[5]  = 3;
    indices[6]  = 4; indices[7]  = 6; indices[8]  = 5;    indices[9]  = 4; indices[10] = 7; indices[11] = 6;
    indices[12] = 4; indices[13] = 5; indices[14] = 1;    indices[15] = 4; indices[16] = 1; indices[17] = 0;
    indices[18] = 3; indices[19] = 2; indices[20] = 6;    indices[21] = 3; indices[22] = 6; indices[23] = 7;
    indices[24] = 1; indices[25] = 5; indices[26] = 6;    indices[27] = 1; indices[28] = 6; indices[29] = 2;
    indices[30] = 4; indices[31] = 0; indices[32] = 3;    indices[33] = 4; indices[34] = 3; indices[35] = 7;

    BoundingBoxIB->Unlock();


    //Textured Quad Verticies
    Device->CreateVertexBuffer(6 * sizeof(VertexTextured), D3DUSAGE_WRITEONLY, VertexTextured::FVF, D3DPOOL_MANAGED, &QuadVB, 0);

    VertexTextured* verticesTex;
    QuadVB->Lock(0, 0, (void**)&verticesTex, 0);


    float x = 4.0f;
    float y = 3.0f;
    verticesTex[0] = VertexTextured(-x, -y, 0.0f, 0.0f, 1.0f);
    verticesTex[1] = VertexTextured(-x,  y, 0.0f, 0.0f, 0.0f);
    verticesTex[2] = VertexTextured( x,  y, 0.0f, 1.0f, 0.0f);
    verticesTex[3] = VertexTextured(-x, -y, 0.0f, 0.0f, 1.0f);
    verticesTex[4] = VertexTextured( x,  y, 0.0f, 1.0f, 0.0f);
    verticesTex[5] = VertexTextured( x, -y, 0.0f, 1.0f, 1.0f);

    QuadVB->Unlock();
    
    
    //Position of Fluid
    Position = D3DXVECTOR3(-20.0f, 10.0f, 15.0f) + D3DXVECTOR3 (18.0f, -5.0f, -3.0f);;




    //-------------------------------
    //Effects Setup
    //-------------------------------
    HRESULT Result = 0;
    ID3DXBuffer* errorBuffer = 0; 

    Result = D3DXCreateEffectFromFile(Device,"- Sources/Mechanic/Fluid/RayCasting.fx", 0, 0, D3DXSHADER_DEBUG, 0, &RayCastingEffect, &errorBuffer);  

    if(errorBuffer) 
    { 
        ::MessageBox(0, (char*)errorBuffer->GetBufferPointer(),0, 0); 
        GameApp::Release<ID3DXBuffer*>(errorBuffer); 
    } 
    
    if(FAILED(Result)) 
    { 
        ::MessageBox(0, "D3DXCreateEffectFromFile() - FAILED", 0, 0); 
        return;
    } 
    
}



//-------------------------------------------------------------------------
//    Render class Destructor
//-------------------------------------------------------------------------
RayCasting::~RayCasting()
{
    GameApp::Release<IDirect3DVertexBuffer9*>(BoundingBoxVB);
    GameApp::Release<IDirect3DIndexBuffer9*> (BoundingBoxIB);
    GameApp::Release<IDirect3DVertexBuffer9*> (QuadVB);

    GameApp::Release<IDirect3DTexture9*>(BackfacesTexture);
    GameApp::Release<IDirect3DTexture9*>(FluidTexture);
    GameApp::Release<IDirect3DVolumeTexture9*>(VolumeTexture);
    GameApp::Release<LPDIRECT3DSURFACE9>(FluidSurface);
    GameApp::Release<LPDIRECT3DSURFACE9>(BackBuffer);
    GameApp::Release<LPDIRECT3DSURFACE9>(BackfacesSurface);

    GameApp::Release<ID3DXEffect*>(RayCastingEffect);

}



//-------------------------------------------------------------------------
//    Render Volume
//-------------------------------------------------------------------------
void RayCasting::Render(float TimeScale)
{
    //Prepare Data sources for render
    Fluid.Update(TimeScale);
    
    
    //-------------------------------
    //Step 0: Setup
    //-------------------------------
    //Setup States
    Device->SetRenderState(D3DRS_LIGHTING, false); 
    Device->SetStreamSource(0, BoundingBoxVB, 0, sizeof(VertexColored));
    Device->SetIndices(BoundingBoxIB);
     RayCastingEffect->SetTexture("BackfacesTex", BackfacesTexture);
    RayCastingEffect->SetTexture("VolumeTex", Fluid.GetDensity());
    RayCastingEffect->SetTexture("ZLookupTex", Fluid.GetZLookup());
    

    //Setup Effect
    D3DXMATRIX Translation;
    D3DXMatrixTranslation(&Translation, Position.x, Position.y, Position.z);
    D3DXMATRIX Temporary = Translation * GameApp::m_pCamera->GetViewMatrix();
    RayCastingEffect->SetMatrix("ModelView", &Temporary); 
    Temporary *= GameApp::m_pCamera->GetProjMatrix(); 
    RayCastingEffect->SetMatrix("ModelViewProj", &Temporary);

    RayCastingEffect->SetTechnique("RayCastingTechnique"); 
    RayCastingEffect->Begin(0, 0);


    
    //-------------------------------
    //Step 1: Render Cube Backfaces In Texture
    //-------------------------------
    Device->SetRenderTarget(0, BackfacesSurface);
    Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_XRGB(150,150,150), 1.0f, 0);
    //Device->BeginScene();
    //Device->EndScene();

    RayCastingEffect->BeginPass(0); 
    Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
    RayCastingEffect->EndPass();
    


    //-------------------------------
    //Step 2: Render Cube Frontfaces + Do Raycasting In Texture
    //-------------------------------
    Device->SetRenderTarget(0, FluidSurface);
    //Device->SetRenderTarget(0, BackBuffer);
    Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, D3DCOLOR_ARGB(0, 255,255,255), 1.0f, 0);
    
    RayCastingEffect->BeginPass(1); 
    Device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
    RayCastingEffect->EndPass();    

    RayCastingEffect->End();



    //-------------------------------
    //Step 3:  Compositing Fluid Texture in scene (Not worked now)
    //-------------------------------
    //GameApp::SceneRender(TimeScale);

    //Previous Render Target
    Device->SetRenderTarget(0, BackBuffer);
    

    //Render Texture
    RenderTexture(FluidTexture, D3DXVECTOR3(0.0f, 0.0f, 3.0f), TimeScale);
}

//-------------------------------------------------------------------------
//    Render Various Texture
//-------------------------------------------------------------------------
void RayCasting::RenderTexture(IDirect3DTexture9* texture, D3DXVECTOR3 Position, float timeDelta)
{
    if( !Device ) return;

    Device->Clear(0, 0,  D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(100,100,100), 1.0f, 0);
    
    Service::SetMaterial( D3DXCOLOR(1.0f, 1.0f, 1.0f, 0.0f) );

    D3DXMATRIX Translation = *D3DXMatrixTranslation(&Translation, Position.x, Position.y, Position.z);
    D3DXMATRIX invView = *D3DXMatrixInverse( &invView, 0, &GameApp::m_pCamera->GetViewMatrix() );
    Translation *= invView;
    
    //Set Render States
    Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
    Device->SetTexture(0, texture);    
    
    Device->SetStreamSource(0, QuadVB, 0, sizeof(VertexTextured));
    Device->SetFVF(VertexTextured::FVF);
    Device->SetTransform( D3DTS_WORLD, &Translation);
    Device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
    
    Device->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
    

    //Restore States
    Device->SetTexture(0, NULL);
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.