Демонстрационный код
От: 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);
}
Re: Демонстрационный код
От: Northaunt  
Дата: 27.07.10 10:56
Оценка:
Извините, я думал, в код автоматом добавится скроллинг
Re: Демонстрационный код
От: Sni4ok  
Дата: 27.07.10 11:03
Оценка:
Здравствуйте, Northaunt, Вы писали:

из беглого просмотра
    static D3DXMATRIX proj = GameApp::m_pCamera->GetProjMatrix();
    static D3DXMATRIX scale = *D3DXMatrixScaling(&scale, scaleFactor, scaleFactor, 0);
    static D3DXMATRIX rotate = *D3DXMatrixRotationY(&rotate, 3.14 / 2.0);

....
    static D3DXMATRIX orthoProj = *D3DXMatrixOrthoLH(&orthoProj, dist, dist, 1.0f, 1000.0f);
    static D3DXMATRIX translation    = *D3DXMatrixTranslation(&translation, 0.0f, 0.0f, 10.0f);


такие статические переменные — очевидно плохо, сделайте их к примеру мемберами класса.
Re: Демонстрационный код
От: Handie  
Дата: 27.07.10 11:42
Оценка: :)
Возможно код будет кому-то в тему, но в общем случае я бы продпочел "чистый" код без идиотических API типа DirectX.

По сути:
1) Обилие "волшебных" констант в коде. Код изобилует захаркоденными цифрами:
Position = D3DXVECTOR3(-20.0f, 10.0f, 15.0f) + D3DXVECTOR3 (18.0f, -5.0f, -3.0f);;
Яркий пример кода написанного начинающим. По сути я на бейсике в школе писал проги
типа moveTo(120,450); lineTo(230,480); lineTo(520,170)

2) Местами выравнивание доминирует над кодом

3) Несколько операторов в строке. Может новичкам кажется это круто, но опытных программеров чаще раздражает.
_x = x; _y = y; _z = z; (кстати подчерки в переменных класса некрасивы)


4) Отсутствие консистентного стиля.
HRESULT Result = 0;
ID3DXBuffer* errorBuffer = 0;
А не пофиг что одна переменная названа c большой буквы а вторая с маленькой.
В одном классе
float VolumeSize;
float Viscosity;
В другом
float _x, _y, _z;
D3DCOLOR _color;

5) отсутствие общей идеи кода. Ну понятно что это аналог бейсика moveTo/lineTo
Re: Демонстрационный код
От: A.Lokotkov Россия  
Дата: 27.07.10 12:04
Оценка: +1
Навскидку. Если D3DXCreateEffectFromFile обломится в конструкторе, то объект окажется в не пойми каком состоянии. Пустым конструктором нужно сделать минимальную инициализацию, а загрузку откуда-нибудь (например, из файла) -- отдельными методами. Сейчас же, если на стеке завести несколько экземпляров Fluid3D, они все полезут в один и тот-же файл. Ну, и показывать "коробки" посреди конструктора тоже не очень правильно, -- обработка ошибок -- вопрос клиентского кода.
bloß it hudla
Re: Демонстрационный код
От: Muxa  
Дата: 27.07.10 12:38
Оценка:
МессаджБокс из конструктора?
Сильно!
Re: Демонстрационный код
От: RedUser Россия  
Дата: 27.07.10 13:23
Оценка:
#include "..\..\- Mein\GameApp.h"
#include "..\..\Service\Service.h"
"- Mein" — так извращаться в названиях директорий не стоит.
И вообще, Mein — это не Main с ошибкой случайно?
Лучше настроить, чтобы путь к заголовкам указывался при сборке, а в коде писать так:
#include "GameApp.h"
#include "Service.h"
Вообще, заголовки, которые используются другими модулями программы, обычно кладут куда-нибудь в include в корне проекта, а не в директорию с реализацией.

if (true || ::GetAsyncKeyState(VK_SPACE))
Какой смысл у данной конструкции?

Закомментированный код я бы из демонстрационного примера убрал, чтобы он никого не смущал.
Re: Демонстрационный код
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 27.07.10 15:10
Оценка: 1 (1) +1 -1
Здравствуйте, Northaunt, Вы писали:

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


Из бросающегося в глаза:

using std::string — не знаю, кому как, но я не люблю такие вещи. Либо уж std::string variable;, либо using namespace std;
— Почти полное отсутствие осмысленных комментариев, некий намёк на них есть только там, где очень длинный код разбивается на блоки. Правда, для этого лучше разбить код на относительно короткие функции;
— ИМХО, самый серьёзный недостаток: нет толковой обработки ошибок (например, пачка вызовов Device->CreateTexture);
— Зачем-то неровно оттабулированы парные скобки в объявлениях методов. С пробелами между параметрами и скобками вообще бардак какой-то: что-то отогнано чуть ли не за правую границу экрана, что-то навалено одно на одно;
— Сумасшедшая длина метода InitVertexBuffers.

Ну и, конечно, закомментированный код из демонстрационного примера лучше бы убрать. Не то, чтобы его не бывает в реальном продуктовом коде (бывает, ещё как бывает), просто здесь у тебя своего рода театр, так хоть сцену подмети.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[2]: Демонстрационный код
От: bnk СССР http://unmanagedvisio.com/
Дата: 27.07.10 15:14
Оценка:
Здравствуйте, RedUser, Вы писали:

RU>[/ccode]"- Mein" — так извращаться в названиях директорий не стоит.


IMHO, это не баг, это фича —
главная директория тогда получается первая по порядку, если стоит сортировка по алфавиту.

RU>И вообще, Mein — это не Main с ошибкой случайно?


Я думаю это на немецком ("Mein" = "My"). Может либа имеет немецкие корни?

RU>Лучше настроить, чтобы путь к заголовкам указывался при сборке, а в коде писать так:

RU>
RU>#include "GameApp.h"
RU>#include "Service.h"
Вообще, заголовки, которые используются другими модулями программы, обычно кладут куда-нибудь в include в корне проекта, а не в директорию с реализацией.


IMHO, то что он написал — вполне нормально.
Вдруг у тебя два файла с одинаковым именем в разных INCLUDE-папках? Получишь проблему на ровном месте.
Re[2]: Ещё
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 27.07.10 15:26
Оценка: 1 (1) +1
Сразу не заметил:

— Довольно длинная D3DXVECTOR3 передаётся по значению. Скорее всего, это не страшно в данном случае, если бы не остальные наблюдения;
— Параметры типа string передаются по значению (const std::string & отменили?);
— В единственном месте, где string передаётся по ссылке эта ссылка должна быть константной, чтобы не морочить голову пользователю.

Кстати, автор знает про существование ключевого слова const?
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re: Демонстрационный код
От: Ytz https://github.com/mtrempoltsev
Дата: 27.07.10 15:32
Оценка: 3 (3) +3
Здравствуйте, Northaunt, Вы писали:

N>Я начинающий программист на С++, ищу работу. Часто просят отослать пример кода. Вот только, после того как я пересылаю его, на другой стороне полная тишина.


Это предсказуемо, так как много кода непонятного назначения. Вот у меня сразу вопрос — какую задачу решает код? Поэтому:
1. Выкинь свой код
2. Возьми стандарт кодирования серьезной организации (например от Qt), вызубри его и четко следуй тому, что там написано, а то от смешения стилей и дикого форматирования волосы шевелятся
3. Напиши например реализацию 2-3 дерева
4. Задокументируй открытые методы своего контейнера в стиле Doxygen
5. Напиши юнит-тесты и короткую демонстрационную программу, чтобы люди сразу видели как с этим работать.
После этого все будет выглядеть аккуратно и на слабое знание языка люди закроют глаза, так как будут думать, что парень толковый и аккуратный — научится.
Re: Демонстрационный код
От: okman Беларусь https://searchinform.ru/
Дата: 27.07.10 15:57
Оценка:
Здравствуйте, Northaunt.

Думаю, мало кому из работодателей понравится замысловатый код, предназначенный, скажем, для обработки
видеопотока данных или шифрования, даже если он чрезвычайно эффективен. Лучше смотрится реализация
относительно простых алгоритмов, но выполненная в качественном стиле, с согласованными именами,
комментариями. Про юнит-тесты вообще молчу.
Re[2]: Демонстрационный код
От: Nuseraro Россия  
Дата: 27.07.10 17:56
Оценка:
Ytz>Это предсказуемо, так как много кода непонятного назначения. Вот у меня сразу вопрос — какую задачу решает код? Поэтому:
Ytz>1. Выкинь свой код
...

К сожалению Ytz прав, таких людей чтобы заценили сложность программирования решения уравнений Навье-Стокса немного.
Homo Guglens
Re[3]: Ещё
От: Northaunt  
Дата: 27.07.10 18:32
Оценка:
Да уж, отсылать это было ошибкой. Спасибо тем, кто заставил себя просмотреть все. Если я правильно понял, основные проблемы это: ужасный стиль, комментарии и непонятно что тут вообще делается. Я, скорее всего, последую советам Ytz, но это займет время. А в качестве временного варианта я откопал старый код, маленький класс управления камерой в 3D. Я постарался учесть все ошибки (константы, передачи по ссылкам, изврат в конструкторах, форматирование и т.д.), но, конечно же, наделав много новых. Это, надеюсь, последний раз, постараюсь больше не напрягать.



#ifndef __CCamera_H__
#define __CCamera_H__


#include <d3dx9.h>
#include "\Mechanic\CPlayer.h"


class CPlayer;



//-------------------------------------------------------------------------
// Base CCamera class
//-------------------------------------------------------------------------
class CCamera 
{ 

public: 

    // Constructors & Destructors 
    CCamera( const CCamera * pCamera ); 
    CCamera(); 
    virtual ~CCamera(); 
 

    // Public Functions 
    void  SetFOV        (float FOV) { FOV = FOV; ProjDirty = true; } 
    void  SetViewport   (long Left, long Top, long Width, long Height, float NearClip, 
                         float FarClip, LPDIRECT3DDEVICE9 pDevice = NULL ); 
 
    //Update States
    void  UpdateRenderView  ( LPDIRECT3DDEVICE9 pD3DDevice ); 
    void  UpdateRenderProj  ( LPDIRECT3DDEVICE9 pD3DDevice ); 
     
      
    // Get Functions
    float               GetFOV         ( ) const    { return FOV;  } 
    float               GetNearClip    ( ) const    { return NearClip; } 
    float               GetFarClip     ( ) const    { return FarClip; } 
 
    const D3DVIEWPORT9& GetViewport    ( ) const    { return Viewport; } 
    CPlayer *            GetPlayer      ( ) const    { return Player;  } 
    const D3DXVECTOR3&  GetPosition    ( ) const    { return Position;  } 
    const D3DXVECTOR3&  GetLook        ( ) const    { return Look;  } 
    const D3DXVECTOR3&  GetUp          ( ) const    { return Up;    } 
    const D3DXVECTOR3&  GetRight       ( ) const    { return Right; } 
    const D3DXMATRIX&   GetViewMatrix  ( ); 
    const D3DXMATRIX&   GetProjMatrix  ( ); 
     
 

    // Public virtual functions 
    virtual void   AttachToPlayer   ( CPlayer * pPlayer )                {}
    virtual void   SetPosition        (const D3DXVECTOR3& position)        {Position = position; ViewDirty = true;}
    virtual void   Move                (const D3DXVECTOR3& vecShift)        {Position += vecShift; ViewDirty = true;} 
    virtual void   Rotate            ( float x, float y, float z )        {}
    virtual void   RotateByMatrix    (const D3DXQUATERNION& Quaternion)    {}
    virtual void   Update            ( float TimeScale)                    {} 
    virtual void   SetCameraDetails    ( const CCamera * pCamera )            {} 
 


protected: 
     
    // Variables 
    CPlayer          *Player;        // The player object we are attached to 
    D3DXMATRIX       View;            // Cached view matrix 
    D3DXMATRIX       Proj;            // Cached projection matrix 
    bool             ViewDirty;     // View matrix dirty ? 
    bool             ProjDirty;     // Proj matrix dirty ? 
     

    // Perspective Projection parameters 
    float           FOV;            // FOV Angle. 
    float           NearClip;       // Near Clip Plane Distance 
    float           FarClip;        // Far Clip Plane Distance 
    D3DVIEWPORT9    Viewport;        // The viewport details into which we are rendering. 
 

    // Cameras current position & orientation 
    D3DXVECTOR3     Position;        // Camera Position 
    D3DXVECTOR3     Up;                // Camera Up Vector 
    D3DXVECTOR3     Look;            // Camera Look Vector 
    D3DXVECTOR3     Right;            // Camera Right Vector 
}; 



//-------------------------------------------------------------------------
// First Person
//-------------------------------------------------------------------------
class CCameraFirstPerson : public CCamera 
{ 

public: 

    //Contructors 
    CCameraFirstPerson    ( const CCamera * pCamera ); 
    CCameraFirstPerson    (); 
 
    
    //Public Base Class Overrides 
    void    Rotate           ( float x, float y, float z ); 
    void    RotateByMatrix   ( const D3DXQUATERNION& Quaternion);
    void    SetCameraDetails ( const CCamera * pCamera ); 
    void    AttachToPlayer   ( CPlayer * pPlayer ); 
};



#endif // __CCamera_H__






#include "CCamera.h"



//-------------------------------------------------------------------------
//
// Camera
//
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
// Default Constructor
//-------------------------------------------------------------------------
CCamera::CCamera() 
{ 
    // Reset / Clear all required values 
    Player         = NULL; 
    Right        = D3DXVECTOR3( 1.0f, 0.0f, 0.0f ); 
    Up           = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); 
    Look         = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); 
    Position     = D3DXVECTOR3( 0.0f, 3.0f, -5.0f ); 
 
    FOV            = 90.0f; 
    NearClip       = 1.0f; 
    FarClip        = 1000.0f;

    Viewport.X      = 0; 
    Viewport.Y      = 0; 
    Viewport.Width  = 1280; 
    Viewport.Height = 960; 
    Viewport.MinZ   = 0.0f; 
    Viewport.MaxZ   = 1.0f; 
 
    // Set matrices to identity 
    D3DXMatrixIdentity( &View ); 
    D3DXMatrixIdentity( &Proj ); 
}



//-------------------------------------------------------------------------
// Copy Constructor
//-------------------------------------------------------------------------
CCamera::CCamera( const CCamera * pCamera ) 
{ 
    // Reset / Clear all required values 
    Player      = NULL; 
    Right       = D3DXVECTOR3( 1.0f, 0.0f, 0.0f ); 
    Up          = D3DXVECTOR3( 0.0f, 1.0f, 0.0f ); 
    Look        = D3DXVECTOR3( 0.0f, 0.0f, 1.0f ); 
    Position    = D3DXVECTOR3( 0.0f, 0.0f, 0.0f ); 
 
    FOV            = 90.0f; 
    NearClip       = 1.0f; 
    FarClip            = 1000.0f; 

    Viewport.X      = 0; 
    Viewport.Y      = 0; 
    Viewport.Width  = 1280; 
    Viewport.Height = 960; 
    Viewport.MinZ   = 0.0f; 
    Viewport.MaxZ   = 1.0f; 
 
    // Set matrices to identity 
    D3DXMatrixIdentity( &View ); 
    D3DXMatrixIdentity( &Proj ); 
} 


//-------------------------------------------------------------------------
// Viewport parameters
//-------------------------------------------------------------------------
void CCamera::SetViewport( long Left, long Top, long Width, long Height, float NearClip,
                           float FarClip, LPDIRECT3DDEVICE9 pDevice ) 
{ 
    // Set viewport sizes 
    Viewport.X      = Left; 
    Viewport.Y      = Top; 
    Viewport.Width  = Width; 
    Viewport.Height = Height; 
    Viewport.MinZ   = 0.0f; 
    Viewport.MaxZ   = 1.0f; 
    NearClip       = NearClip; 
    FarClip        = FarClip; 
    ProjDirty      = true; 
 
    // Update device if requested 
    if ( pDevice ) pDevice->SetViewport( &Viewport ); 
} 


//-------------------------------------------------------------------------
// Return Perspective Projection matrix (Recalculate if dirty)
//-------------------------------------------------------------------------
const D3DXMATRIX& CCamera::GetProjMatrix()  
{ 
    // Only update matrix if something has changed 
    if ( ProjDirty )  
    {      
        float fAspect = (float)Viewport.Width / (float)Viewport.Height; 
 
        // Set the perspective projection matrix 
        D3DXMatrixPerspectiveFovLH(&Proj, D3DX_PI * 0.5f, (float)1280 / (float)960, 1.0f, 1000.0f);
             
        // Proj Matrix has been updated 
        ProjDirty = false;  
    } 

    // Return the projection matrix. 
    return Proj; 
}



//-------------------------------------------------------------------------
// Update Projection device transform
//-------------------------------------------------------------------------
void CCamera::UpdateRenderProj( LPDIRECT3DDEVICE9 pD3DDevice ) 
{   
    if (!pD3DDevice) return; 
    pD3DDevice->SetTransform( D3DTS_PROJECTION, &GetProjMatrix() ); 
} 



//-------------------------------------------------------------------------
// Update View device transform
//-------------------------------------------------------------------------
void CCamera::UpdateRenderView( LPDIRECT3DDEVICE9 pD3DDevice ) 
{   
    if (!pD3DDevice) return; 
    pD3DDevice->SetTransform( D3DTS_VIEW, &GetViewMatrix() ); 
} 



//-------------------------------------------------------------------------
// Return View matrix (Recalculate if dirty)
//-------------------------------------------------------------------------
const D3DXMATRIX& CCamera::GetViewMatrix() 
{ 
    // Only update matrix if something has changed 
    if ( ViewDirty )  
    { 
        D3DXVec3Normalize( &Look, &Look ); 
        D3DXVec3Cross( &Right, &Up, &Look ); 
        D3DXVec3Normalize( &Right, &Right ); 
        D3DXVec3Cross( &Up, &Look, &Right ); 
        D3DXVec3Normalize( &Up, &Up ); 
 
        //Set view matrix values 
        View._11 = Right.x;View._12 = Up.x;View._13 = Look.x; 
        View._21 = Right.y;View._22 = Up.y;View._23 = Look.y; 
        View._31 = Right.z;View._32 = Up.z;View._33 = Look.z; 
        View._41 =- D3DXVec3Dot( &Position, &Right ); 
        View._42 =- D3DXVec3Dot( &Position, &Up    ); 
        View._43 =- D3DXVec3Dot( &Position, &Look  );

        // View Matrix has been updated 
        ViewDirty = false; 
    }  

    // Return the view matrix. 
    return View; 
}



//-------------------------------------------------------------------------
//
// First Person
//
//-------------------------------------------------------------------------

//-------------------------------------------------------------------------
// Contructor
//-------------------------------------------------------------------------
CCameraFirstPerson::CCameraFirstPerson( const CCamera * pCamera ) 
{ 
    // Update the CCamera from the camera passed 
    SetCameraDetails( pCamera ); 
}



//-------------------------------------------------------------------------
// Setup First Person camera
//-------------------------------------------------------------------------
void CCameraFirstPerson::SetCameraDetails( const CCamera * pCamera ) 
{ 
    // Validate Parameters 
    if (!pCamera) return; 
 
    // Reset / Clear all required values 
    Position    = pCamera->GetPosition(); 
    Right   = pCamera->GetRight(); 
    Look    = pCamera->GetLook(); 
    Up      = pCamera->GetUp(); 
    FOV       = pCamera->GetFOV(); 
    NearClip  = pCamera->GetNearClip(); 
    FarClip   = pCamera->GetFarClip(); 
    Viewport   = pCamera->GetViewport(); 
    
    ViewDirty = true; 
    ProjDirty = true; 
}



//-------------------------------------------------------------------------
// Rotate camera
//-------------------------------------------------------------------------
void CCameraFirstPerson::Rotate( float x, float y, float z ) 
{ 
    D3DXMATRIX Rotate; 

    if ( x != 0 )  
    { 
        D3DXMatrixRotationAxis( &Rotate, &Player->GetRight(), D3DXToRadian( x ) ); 
        D3DXVec3TransformNormal( &Look, &Look, &Rotate ); 
        D3DXVec3TransformNormal( &Up, &Up, &Rotate ); 
        D3DXVec3TransformNormal( &Right, &Right, &Rotate );
    }  
 
    if ( y != 0 )  
    { 
        D3DXMatrixRotationAxis( &Rotate, &Player->GetUp(), D3DXToRadian( y ) ); 
        D3DXVec3TransformNormal( &Look, &Look, &Rotate ); 
        D3DXVec3TransformNormal( &Up, &Up, &Rotate ); 
        D3DXVec3TransformNormal( &Right, &Right, &Rotate ); 
    }  
 
    if ( z != 0 )  
    { 
        D3DXMatrixRotationAxis( &Rotate, &Player->GetLook(), D3DXToRadian( z ) ); 
        D3DXVec3TransformNormal( &Look, &Look, &Rotate ); 
        D3DXVec3TransformNormal( &Up, &Up, &Rotate ); 
        D3DXVec3TransformNormal( &Right, &Right, &Rotate ); 
    }  
         
    // Set view matrix as dirty
    ViewDirty = true; 
} 


//-------------------------------------------------------------------------
// Rotate camera by Quaternion
//-------------------------------------------------------------------------
void CCameraFirstPerson::RotateByMatrix(const D3DXQUATERNION& sQuaternion)
{
     D3DXMATRIX Rotate;
     static D3DXVECTOR3 Look(Look), Up(Up), Right(Right);

     //Get Rotation matrix from Quaternion
     D3DXMatrixRotationQuaternion(&Rotate,&Quaternion);    
     
     //Rotate
     D3DXVec3TransformNormal( &Look, &Look, &Rotate ); 
     D3DXVec3TransformNormal( &Up, &Up, &Rotate ); 
     D3DXVec3TransformNormal( &Right, &Right, &Rotate );

         
    // Set view matrix as dirty
    ViewDirty = true; 
}


//-------------------------------------------------------------------------
// COnnect camera to player
//-------------------------------------------------------------------------
void CCameraFirstPerson::AttachToPlayer( CPlayer * pPlayer )
{
    Player = pPlayer;
}
Re[4]: Ещё
От: Northaunt  
Дата: 27.07.10 18:35
Оценка:
Кстати, глюки со смещением, не моих рук дело, в окне Visual Studio все ровно. Это при отправке сообщения строчки начинает косить
Re[5]: Ещё
От: Roman Odaisky Украина  
Дата: 27.07.10 20:37
Оценка: +1
Здравствуйте, Northaunt, Вы писали:

N>Кстати, глюки со смещением, не моих рук дело, в окне Visual Studio все ровно. Это при отправке сообщения строчки начинает косить


Твоих. Ты явно выравниваешь колонки табуляциями, чего делать нельзя (расползется при другом размере табуляции).

Табуляции допустимы только для отступов, и то спорно (я вот использую пробелы вообще везде).
До последнего не верил в пирамиду Лебедева.
Re: Демонстрационный код
От: minorlogic Украина  
Дата: 27.07.10 21:26
Оценка: +1
По моему мнению, хороший код для джуниора.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Ищу работу, 3D, SLAM, computer graphics/vision.
Re[5]: Ещё
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 27.07.10 22:24
Оценка:
Здравствуйте, Northaunt, Вы писали:

N>Кстати, глюки со смещением, не моих рук дело, в окне Visual Studio все ровно. Это при отправке сообщения строчки начинает косить


Твоих, твоих. Ctrl-R,W — посмотри, где у тебя табуляции, где пробелы.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re: Демонстрационный код
От: landerhigh Пират  
Дата: 27.07.10 22:41
Оценка: +1
Здравствуйте, Northaunt, Вы писали:

N>Я начинающий программист на С++, ищу работу.


Одна проблема — приведенный код — это не C++ код. В лучшем случае это с натяжкой можно назвать "C с классами".
Если хочешь найти работу именно на C++, нужно придумать пример именно C++ кода.
Re[4]: Ещё
От: Геннадий Васильев Россия http://www.livejournal.com/users/gesha_x
Дата: 27.07.10 22:48
Оценка: 1 (1) +2
Здравствуйте, Northaunt, Вы писали:

N>Да уж, отсылать это было ошибкой. Спасибо тем, кто заставил себя просмотреть все. Если я правильно понял, основные проблемы это: ужасный стиль, комментарии и непонятно что тут вообще делается. Я, скорее всего, последую советам Ytz, но это займет время. А в качестве временного варианта я откопал старый код, маленький класс управления камерой в 3D. Я постарался учесть все ошибки (константы, передачи по ссылкам, изврат в конструкторах, форматирование и т.д.), но, конечно же, наделав много новых. Это, надеюсь, последний раз, постараюсь больше не напрягать.


На мой взгляд, значительно лучше. Правда, обработка ошибок так и не появилась. Или это в графических приложениях не принято?

Насчёт code convention... Я, лично, не думаю, что сам по себе стиль кодирования играет большую роль при приёме на работу, за исключением, наверное, мешанины из пробелов с табуляциями — её может быть просто неудобно читать. То есть, предпочитаешь ты венгерку, Camel, или, там, stl-like — не суть важно. Это всё управляется внутрифирменными соглашениями, потому при необходимости может быть "перенастроено". Скорее, важно другое: на сколько последовательно ты сам придерживаешься выбранного тобой стиля. Если уж переменные-члены класса именуются с большой буквы, шут с ним, пусть именуются с большой буквы, но везде. Если ты отделяешь скобки пробелами — тоже, отделяй тогда уж везде. На практике, разумеется, не всегда всё шоколадно, но тут тебя никто не торопит с подготовкой примеров, можно отсмотреть и повнимательнее.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.