[PR]
×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
プログラミング、3DCGとその他いろいろについて
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
#using<System.Windows.Forms.dll>
#using<System.Drawing.dll>//ClientSizeを使うのに必要
#using<System.dll>
#include<d3d10.h>
#include<d3dx10.h<
using namespace System;
using namespace System::Windows::Forms;
struct VertexPositionColor
{
D3DXVECTOR3 Position;
D3DXVECTOR4 Color;
};
ref class Game : Form
{
ID3D10Device* graphicsDevice;
IDXGISwapChain* swapChain;
ID3D10RenderTargetView* renderTargetView;
ID3D10Effect *effect;
ID3D10InputLayout* vertexLayout;
ID3D10Buffer* vertexBuffer;
public:
void Run()
{
InitDevice();
Show();
while(Created)
{
Draw();
Application::DoEvents();
}
}
private:
void InitDevice()
{
createGraphicsDevice();
createRenderTargetView();
setupViewport();
LoadGraphicsContent();
}
void LoadGraphicsContent()
{
//シェーダーの設定
ID3D10Effect* effect;
HRESULT result = D3DX10CreateEffectFromFile(
"MyShader.fx",
NULL,
NULL,
"fx_4_0",
D3D10_SHADER_ENABLE_STRICTNESS,
0,
graphicsDevice,
NULL,
NULL,
&effect,
NULL,
NULL
);
if(FAILED(result))
throw gcnew Exception("couldn't create effect object");
this->effect = effect;
//頂点データのレイアウトの設定
D3D10_INPUT_ELEMENT_DESC vertexElements[] =
{
{"SV_Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0},
{"Color", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D10_APPEND_ALIGNED_ELEMENT, D3D10_INPUT_PER_VERTEX_DATA, 0}
};
D3D10_PASS_DESC passDesc;
effect->GetTechniqueByName("MyTechnique")->GetPassByIndex(0)->GetDesc(&passDesc);
ID3D10InputLayout *vertexLayout;
result = graphicsDevice->CreateInputLayout(
vertexElements,
2,
passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize,
&vertexLayout
);
if(FAILED(result))
throw gcnew Exception("couldn't create InputLayout");
this->vertexLayout = vertexLayout;
graphicsDevice->IASetInputLayout(vertexLayout);
//頂点バッファの設定
VertexPositionColor vertices[] =
{
{D3DXVECTOR3(0, 0.5f, 0), D3DXVECTOR4(1, 1, 1, 1)},
{D3DXVECTOR3(0.5f, 0, 0), D3DXVECTOR4(0, 0, 1, 1)},
{D3DXVECTOR3(-0.5f, 0, 0), D3DXVECTOR4(1, 0, 0, 1)}
};
D3D10_SUBRESOURCE_DATA initData;
initData.pSysMem = vertices;
D3D10_BUFFER_DESC bufferDesc;
ZeroMemory(&bufferDesc, sizeof(bufferDesc));
bufferDesc.Usage = D3D10_USAGE_DEFAULT;
bufferDesc.ByteWidth = sizeof(VertexPositionColor) * 3;
bufferDesc.BindFlags = D3D10_BIND_VERTEX_BUFFER;
ID3D10Buffer *vertexBuffer;
result = graphicsDevice->CreateBuffer(
&bufferDesc,
&initData,
&vertexBuffer
);
if(FAILED(result))
throw gcnew Exception("couldn't create Vertex Buffer");
this->vertexBuffer = vertexBuffer;
unsigned int stride = sizeof(VertexPositionColor);
unsigned int offset = 0;
graphicsDevice->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
//頂点バッファが三角形のリストとして描画されるようにセット
graphicsDevice->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
~Game(){ this->!Game(); }
!Game()
{
if(graphicsDevice) graphicsDevice->ClearState();
if(vertexBuffer) vertexBuffer->Release();
if(vertexLayout) vertexLayout->Release();
if(effect) effect->Release();
if(renderTargetView) renderTargetView->Release();
if(swapChain) swapChain->Release();
if(graphicsDevice) graphicsDevice->Release();
}
void Draw()
{
float cornflowerBlue[] = {0.39, 0.58, 0.93, 1};
graphicsDevice->ClearRenderTargetView(renderTargetView, cornflowerBlue);
//三角形の3D空間の中での動きをあらわすマトリックスです。
//ここでは、時間によってz座標が[-1 ~ -3]の間を動きまわります。
//(xとyは動かない)
D3DXMATRIX worldTransform;
D3DXMatrixTranslation(
&worldTransform,
0, 0, (float)Math::Sin(D3DXToRadian(Environment::TickCount / 20.0)) - 2
);
//三角形に遠近法の効果を与えるマトリックスです。
//視野の角度は90°です。
//また、あまり見た目に影響を与えませんが、
//描画される領域は画面からの距離が[0.1f ~ 1000]に設定されていて、
//この領域を外れると、三角形は描画されなくなります。
D3DXMATRIX projectionTransform;
D3DXMatrixPerspectiveFovRH(
&projectionTransform,
D3DXToRadian(90),
(float)ClientSize.Width / ClientSize.Height,
0.1f, 1000
);
//上の2つのマトリックスを組み合わせて、シェーダーに送り込みます。
//つまり、「三角形のz座標を動かしてから、遠近法っぽい効果を適用する」
//ことを意味するマトリックスを新たに作り、
//それをエフェクトオブジェクトにセットしています。
//(実際の変換はDrawの時、HLSLのシェーダープログラムの中で)
effect->GetVariableByName("Transform")->AsMatrix()->SetMatrix(
(float*)&(worldTransform * projectionTransform)
);
effect->GetTechniqueByName("MyTechnique")->GetPassByIndex(0)->Apply(0);
graphicsDevice->Draw( 3, 0);
swapChain->Present(0, 0);
}
void createGraphicsDevice()
{
DXGI_SWAP_CHAIN_DESC swapChainDescription;
ZeroMemory( &swapChainDescription, sizeof(swapChainDescription) );
swapChainDescription.BufferCount = 1;
swapChainDescription.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDescription.OutputWindow = (HWND)(this->Handle.ToInt32());
swapChainDescription.SampleDesc.Count = 1;
swapChainDescription.Windowed = TRUE;
ID3D10Device *graphicsDevice;
IDXGISwapChain *swapChain;
HRESULT result = D3D10CreateDeviceAndSwapChain(
NULL,
D3D10_DRIVER_TYPE_REFERENCE,
NULL,
0,
D3D10_SDK_VERSION,
&swapChainDescription,
&swapChain,
&graphicsDevice
);
if( FAILED(result) )
throw gcnew Exception("Couldn't create Graphics Device");
this->graphicsDevice = graphicsDevice;
this->swapChain = swapChain;
}
void createRenderTargetView()
{
ID3D10Texture2D *backBuffer;
HRESULT result = swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*)&backBuffer);
if( FAILED(result) )
throw gcnew Exception("Couldn't get BackBuffer from swap chain.");
ID3D10RenderTargetView* renderTargetView;
result = graphicsDevice->CreateRenderTargetView(backBuffer, NULL, &renderTargetView);
backBuffer->Release();
if( FAILED(result) )
throw gcnew Exception("Couldn't create RenderTargetView.");
this->renderTargetView = renderTargetView;
graphicsDevice->OMSetRenderTargets(1, &renderTargetView, NULL);
}
void setupViewport()
{
D3D10_VIEWPORT viewport;
viewport.Width = Width;
viewport.Height = Height;
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
graphicsDevice->RSSetViewports( 1, &viewport );
}
};
int main()
{
Game ^game = gcnew Game();
game->Run();
}
matrix Transform;
struct VertexPositionColor
{
float4 Position : SV_Position;
float4 Color : COLOR;
};
VertexPositionColor MyVertexShader(VertexPositionColor input)
{
input.Position = mul(input.Position, Transform);
return input;
}
float4 MyPixelShader(VertexPositionColor input) : SV_Target
{
return input.Color;
}
technique10 MyTechnique
{
pass
{
SetVertexShader(CompileShader(vs_4_0, MyVertexShader()));
SetPixelShader(CompileShader(ps_4_0, MyPixelShader()));
}
}
D3DXMATRIX operator * ( CONST D3DXMATRIX& ) const; D3DXMATRIX& operator *= ( CONST D3DXMATRIX& );
D3DXMATRIX* D3DXMatrixTranslation(
D3DXMATRIX *outMatrix,
float x,
float y,
float z
);
D3DXMATRIX * D3DXMatrixPerspectiveFovRH(
D3DXMATRIX *outMatrix,
float fieldOfViewY,
float aspectRatio,
float nearPlaneDistance,
float farPlaneDistance
);
ID3D10EffectVariable* GetVariableByName(
LPCSTR name
);
ID3D10EffectMatrixVariable* AsMatrix();
HRESULT SetMatrix(
float *data
);