Я начинающий программист на С++, ищу работу. Часто просят отослать пример кода. Вот только, после того как я пересылаю его, на другой стороне полная тишина. Я каждый раз объяснял, что сложных, хорошо написанных и спроектированных программ у меня нет (мои проекты связаны с 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);
}