Я начинающий программист на С++, ищу работу. Часто просят отослать пример кода. Вот только, после того как я пересылаю его, на другой стороне полная тишина. Я каждый раз объяснял, что сложных, хорошо написанных и спроектированных программ у меня нет (мои проекты связаны с 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);
}
Возможно код будет кому-то в тему, но в общем случае я бы продпочел "чистый" код без идиотических 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
Навскидку. Если D3DXCreateEffectFromFile обломится в конструкторе, то объект окажется в не пойми каком состоянии. Пустым конструктором нужно сделать минимальную инициализацию, а загрузку откуда-нибудь (например, из файла) -- отдельными методами. Сейчас же, если на стеке завести несколько экземпляров Fluid3D, они все полезут в один и тот-же файл. Ну, и показывать "коробки" посреди конструктора тоже не очень правильно, -- обработка ошибок -- вопрос клиентского кода.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Northaunt.
Думаю, мало кому из работодателей понравится замысловатый код, предназначенный, скажем, для обработки
видеопотока данных или шифрования, даже если он чрезвычайно эффективен. Лучше смотрится реализация
относительно простых алгоритмов, но выполненная в качественном стиле, с согласованными именами,
комментариями. Про юнит-тесты вообще молчу.
Кстати, глюки со смещением, не моих рук дело, в окне Visual Studio все ровно. Это при отправке сообщения строчки начинает косить
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!