Nanashi-softプログラマ専用DirectX11開発


◇DirectX11プログラミング -新システム(sgc5)のソース-

もはや新システムの説明はムリっぽいので(説明するにはそれをプログラミングするより高度な理解が必要)
なんかこう……テレパスで感じ取って下さい(ぉ ←

無言で新システムのソースを貼っていきます(*'-')
まとめたりとかしていません。投げ捨てです(ぉ

・main.cpp~初期化完了まで
#include <windows.h>
#include <d3d11.h>
#include <d3dx11.h>
#include <xnamath.h>

#include <stdio.h>

#include "vs.h" //Vertex Shader
#include "ps.h" //Pixcel Shader
#include "ps_2.h" //Pixcel Shader 2

#include "modeldata.h" //モデルデータ保管クラス
#include "pmd.h" //PMDローダークラス

#pragma once
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dx11.lib")

#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }

//ウィンドウのコールバック関数
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message){
case WM_CLOSE:
PostMessage(hWnd, WM_DESTROY, 0, 0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}

return(DefWindowProc(hWnd, message, wParam, lParam));
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
//ウィンドウクラスを登録して
TCHAR szWindowClass[] = "3DDISPPG";
WNDCLASS wcex;
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
RegisterClass(&wcex);

//ウィンドウをクリエイト
HWND hWnd;
hWnd = CreateWindow(szWindowClass,
"3D Disp Pg",
WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
0,
0,
1920,
1080,
NULL,
NULL,
hInstance,
NULL);

D3D_DRIVER_TYPE driverTypes[] = {
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
};
UINT numDriverTypes = ARRAYSIZE(driverTypes);

DXGI_SWAP_CHAIN_DESC hDXGISwapChainDesc;
hDXGISwapChainDesc.BufferDesc.Width = 1980;
hDXGISwapChainDesc.BufferDesc.Height = 1080;
hDXGISwapChainDesc.BufferDesc.RefreshRate.Numerator = 0;
hDXGISwapChainDesc.BufferDesc.RefreshRate.Denominator = 1;
hDXGISwapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
hDXGISwapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
hDXGISwapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
hDXGISwapChainDesc.SampleDesc.Count = 1;
hDXGISwapChainDesc.SampleDesc.Quality = 0;
hDXGISwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
hDXGISwapChainDesc.BufferCount = 3;
hDXGISwapChainDesc.OutputWindow = hWnd;
hDXGISwapChainDesc.Windowed = TRUE;
hDXGISwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
hDXGISwapChainDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;

//デバイスとスワップチェインを一気に生成
HRESULT hr;
D3D_DRIVER_TYPE hDriverType = D3D_DRIVER_TYPE_NULL;
IDXGISwapChain* hpDXGISwpChain = NULL;
ID3D11Device* hpDevice = NULL;
ID3D11DeviceContext* hpDeviceContext = NULL;
D3D_FEATURE_LEVEL hFeatureLevel = D3D_FEATURE_LEVEL_11_0;
for(UINT driverTypeIndex=0; driverTypeIndex < numDriverTypes; driverTypeIndex++){
hDriverType = driverTypes[driverTypeIndex];
hr = D3D11CreateDeviceAndSwapChain(NULL, hDriverType, NULL, 0, NULL, 0, D3D11_SDK_VERSION, &hDXGISwapChainDesc, &hpDXGISwpChain, &hpDevice, &hFeatureLevel, &hpDeviceContext);
if(SUCCEEDED(hr)){
break;
}
}
if(FAILED(hr)){
MessageBoxW(hWnd, L"D3D11CreateDeviceAndSwapChain", L"Err", MB_ICONSTOP);
goto End;
}

//スワップチェインのバックバッファ取得
ID3D11Texture2D* hpBackBuffer = NULL;
if(FAILED(hpDXGISwpChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&hpBackBuffer))){
MessageBoxW(hWnd, L"SwpChain GetBuffer", L"Err", MB_ICONSTOP);
goto End;
}

//そのバックバッファから描画ターゲット生成
ID3D11RenderTargetView *hpRenderTargetView = NULL;
if(FAILED(hpDevice->CreateRenderTargetView(hpBackBuffer, NULL, &hpRenderTargetView))){
MessageBoxW(hWnd, L"CreateRenderTargetView", L"Err", MB_ICONSTOP);
goto End;
}

//ステンシル用テクスチャー作成
ID3D11Texture2D* hpTexture2dDepth = NULL;
D3D11_TEXTURE2D_DESC hTexture2dDesc;
hTexture2dDesc.Width = hDXGISwapChainDesc.BufferDesc.Width;
hTexture2dDesc.Height = hDXGISwapChainDesc.BufferDesc.Height;
hTexture2dDesc.MipLevels = 1;
hTexture2dDesc.ArraySize = 1;
hTexture2dDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
hTexture2dDesc.SampleDesc = hDXGISwapChainDesc.SampleDesc;
hTexture2dDesc.Usage = D3D11_USAGE_DEFAULT;
hTexture2dDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
hTexture2dDesc.CPUAccessFlags = 0;
hTexture2dDesc.MiscFlags = 0;
if(FAILED(hpDevice->CreateTexture2D(&hTexture2dDesc, NULL, &hpTexture2dDepth))){
MessageBoxW(hWnd, L"CreateTexture2D", L"Err", MB_ICONSTOP);
goto End;
}

//ステンシルターゲット作成
ID3D11DepthStencilView* hpDepthStencilView = NULL;
D3D11_DEPTH_STENCIL_VIEW_DESC hDepthStencilViewDesc;
hDepthStencilViewDesc.Format = hTexture2dDesc.Format;
hDepthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
hDepthStencilViewDesc.Flags = 0;
if(FAILED(hpDevice->CreateDepthStencilView(hpTexture2dDepth, &hDepthStencilViewDesc, &hpDepthStencilView))){
MessageBoxW(hWnd, L"CreateDepthStencilView", L"Err", MB_ICONSTOP);
goto End;
}

//その描画ターゲットとステンシルターゲットコンテキストに設定
hpDeviceContext->OMSetRenderTargets(1, &hpRenderTargetView, hpDepthStencilView);

//ブレンディングステート生成
ID3D11BlendState* hpBlendState = NULL;
D3D11_BLEND_DESC BlendStateDesc;
BlendStateDesc.AlphaToCoverageEnable = FALSE;
BlendStateDesc.IndependentBlendEnable = FALSE;
for(int i=0; i < 8; i++){
BlendStateDesc.RenderTarget[i].BlendEnable = TRUE;
BlendStateDesc.RenderTarget[i].SrcBlend = D3D11_BLEND_SRC_ALPHA;
BlendStateDesc.RenderTarget[i].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
BlendStateDesc.RenderTarget[i].BlendOp = D3D11_BLEND_OP_ADD;
BlendStateDesc.RenderTarget[i].SrcBlendAlpha = D3D11_BLEND_ONE;
BlendStateDesc.RenderTarget[i].DestBlendAlpha = D3D11_BLEND_ZERO;
BlendStateDesc.RenderTarget[i].BlendOpAlpha = D3D11_BLEND_OP_ADD;
BlendStateDesc.RenderTarget[i].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
}
hpDevice->CreateBlendState(&BlendStateDesc, &hpBlendState);

//そのブレンディングをコンテキストに設定
float blendFactor[4] = {D3D11_BLEND_ZERO, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO, D3D11_BLEND_ZERO};
hpDeviceContext->OMSetBlendState(hpBlendState, blendFactor, 0xffffffff);

//ビューポート設定
D3D11_VIEWPORT vp;
vp.TopLeftX = 0;
vp.TopLeftY = 0;
vp.Width = (float)hDXGISwapChainDesc.BufferDesc.Width;
vp.Height = (float)hDXGISwapChainDesc.BufferDesc.Height;
vp.MinDepth = 0.0f;
vp.MaxDepth = 1.0f;
hpDeviceContext->RSSetViewports(1, &vp);

//ポリゴン頂点構造体
struct Vertex3D {
float pos[3]; //x-y-z
float col[4]; //r-g-b-a
float tex[2]; //x-y
};

//頂点レイアウト
//5番目のパラメータは先頭からのバイト数なので,COLORにはPOSITIONのfloat型4バイト×3を記述
D3D11_INPUT_ELEMENT_DESC hInElementDesc[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 4*3, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 4*3 + 4*4, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};

//それらをシェーダーに送る
struct ConstantBuffer
{
XMMATRIX mWorld;
XMMATRIX mView;
XMMATRIX mProjection;
};
//constantバッファ生成
ID3D11Buffer* hpConstantBuffer = NULL;
D3D11_BUFFER_DESC hBufferDesc;
hBufferDesc.ByteWidth = sizeof(ConstantBuffer);
hBufferDesc.Usage = D3D11_USAGE_DEFAULT;
hBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
hBufferDesc.CPUAccessFlags = 0;
hBufferDesc.MiscFlags = 0;
hBufferDesc.StructureByteStride = sizeof(float);
if(FAILED(hpDevice->CreateBuffer(&hBufferDesc, NULL, &hpConstantBuffer))){
MessageBoxW(hWnd, L"Create ConstantBuffer", L"Err", MB_ICONSTOP);
goto End;
}

//描画時に使用する変数を宣言
ConstantBuffer hConstantBuffer;
XMMATRIX hWorld; //ワールド変換行列
XMMATRIX hView; //ビュー変換行列
XMMATRIX hProjection; //透視射影変換行列

//初期化ここまで
// =====================================================
PMDデータの解析部分です
テクスチャーの透過部分を反映させる為に,bmp形式を png形式に勝手に変更しているところを注意して下さい
本来なら,自力で BMP形式を透過ありテクスチャーに変換して設定すべきですが,その方法がまだわかっていない為です

・main.cpp~PMDデータセット完了まで
	modeldata *hModelData = new modeldata();	//モデルデータ保管クラス生成

//pmdクラスを生成する。その際にコンストラクタにファイル名を教える
const int MODELDATA_MAX = 2;
char *pmdfile[] = {
"kagaminelin.pmd",
"hatsunemiku.pmd"
};

//モデルデータ分を予めGPUにセットする
for(int mdcnt=0; mdcnt < MODELDATA_MAX; mdcnt++){
pmd *modeldata = new pmd(pmdfile[mdcnt]);
// == PMDデータ読み込みここから ==
//頂点データを取得
int TYOUTEN = modeldata->vert_count;

Vertex3D *hVectorData;
hVectorData = new Vertex3D[TYOUTEN];

for(int i=0; i < TYOUTEN; i++){
hVectorData[i].pos[0] = modeldata->vertex[i].pos[0];
hVectorData[i].pos[1] = modeldata->vertex[i].pos[1];
hVectorData[i].pos[2] = modeldata->vertex[i].pos[2];
hVectorData[i].col[0] = 0.0f;
hVectorData[i].col[1] = 0.0f;
hVectorData[i].col[2] = 0.0f;
hVectorData[i].col[3] = 0.0f;
hVectorData[i].tex[0] = modeldata->vertex[i].uv[0];
hVectorData[i].tex[1] = modeldata->vertex[i].uv[1];
}

//インデックスデータを取得
int INDEXSU = modeldata->face_vert_count;

unsigned short *hIndexData;
hIndexData = new unsigned short[INDEXSU];

for(int i=0; i < INDEXSU; i++){
hIndexData[i] = modeldata->face_vert_index[i];
}

//カラーデータを取得
int COLORSU = modeldata->material_count;
//LPCSTRとかわけわかんないので,普通にCで書くよ
#define MATERIAL_FILENAME_MAX 21
char *texture_file = new char[COLORSU * MATERIAL_FILENAME_MAX];
memset(&texture_file[0], 0, COLORSU * MATERIAL_FILENAME_MAX);

int cnt_idx = 0; //インデックスカウンター
for(int i=0; i < COLORSU; i++){
//マテリアルにあるカウンター分回す
for(unsigned long j=0; j < modeldata->material[i].face_vert_count; j++){
//インデックスから頂点座標の行数を取り出す
int pos_vec = modeldata->face_vert_index[cnt_idx];
cnt_idx++; //インデックスカウンターを進める

//その頂点座標のカラーが現在のマテリアルカラー
hVectorData[pos_vec].col[0] = modeldata->material[i].diffuse_color[0]; //R
hVectorData[pos_vec].col[1] = modeldata->material[i].diffuse_color[1]; //G
hVectorData[pos_vec].col[2] = modeldata->material[i].diffuse_color[2]; //B
hVectorData[pos_vec].col[3] = modeldata->material[i].alpha; //A
}
//テクスチャー設定
//最後にNULLは保障されていないらしいので。。。
char w[MATERIAL_FILENAME_MAX];
memset(&w, 0, sizeof(w));
memcpy(&w, &modeldata->material[i].texture_file_name[0], MATERIAL_FILENAME_MAX - 1);
//テクスチャー名は0クリアされている保障は無かったし。。。
if(w[0] != 0){
//bmpの場合pngに変更
int w2 = 0;
while(w[w2] != 0){
w2++;
}
w2--;
if( (w[w2] == 'p' || w[w2] == 'P')
&& (w[w2-1] == 'm' || w[w2-1] == 'M')
&& (w[w2-2] == 'b' || w[w2-2] == 'B')
&& w[w2-3] == '.'){
w[w2] = 'g';
w[w2-1] = 'n';
w[w2-2] = 'p';
}

memcpy(&texture_file[i*MATERIAL_FILENAME_MAX], w, MATERIAL_FILENAME_MAX-1);
}

}
// == PMDデータ読み込みここまで ==

//モデルデータクラスの状況取得
//次のオブジェ番号を取得
int hObjNum = hModelData->getObjMax();
//次の頂点バッファー番号を取得
int hVctBufNum = hModelData->getMaxVctBufNum();
//次のインデックスバッファー番号を取得
int hIdxBufNum = hModelData->getMaxIdxBufNum();

// == GPUにデータ送信 ==
//頂点バッファ作成
D3D11_BUFFER_DESC hBufferDesc;
hBufferDesc.ByteWidth = sizeof(Vertex3D) * TYOUTEN;
hBufferDesc.Usage = D3D11_USAGE_DEFAULT;
hBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
hBufferDesc.CPUAccessFlags = 0;
hBufferDesc.MiscFlags = 0;
hBufferDesc.StructureByteStride = sizeof(float);

D3D11_SUBRESOURCE_DATA hSubResourceData;
hSubResourceData.pSysMem = hVectorData;
hSubResourceData.SysMemPitch = 0;
hSubResourceData.SysMemSlicePitch = 0;

if(FAILED(hpDevice->CreateBuffer(&hBufferDesc, &hSubResourceData, &hModelData->vctBuf[hVctBufNum]))){
MessageBoxW(hWnd, L"CreateBuffer", L"Err", MB_ICONSTOP);
goto End;
}

//インデックスバッファ作成
hBufferDesc.ByteWidth = sizeof(unsigned short) * INDEXSU;
hBufferDesc.Usage = D3D11_USAGE_DEFAULT;
hBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
hBufferDesc.CPUAccessFlags = 0;
hBufferDesc.MiscFlags = 0;
hBufferDesc.StructureByteStride = sizeof(unsigned short);

hSubResourceData.pSysMem = hIndexData;
hSubResourceData.SysMemPitch = 0;
hSubResourceData.SysMemSlicePitch = 0;

if(FAILED(hpDevice->CreateBuffer(&hBufferDesc, &hSubResourceData, &hModelData->idxBuf[hIdxBufNum]))){
MessageBoxW(hWnd, L"CreateBuffer Index", L"Err", MB_ICONSTOP);
goto End;
}

// == モデルデータクラスにデータをセット ==
//PMDデータはマテリアル単位で分割すればシェーダーを適切に当てられる(はず)
int hIdxStaWork = 0;
for(int i=0; i < COLORSU; i++){
//モデルデータ保管を生成(PMDのマテリアル単位に)
int hModelId = hModelData->newData();

//同一モデルとしてオブジェ番号をセット
hModelData->setObjNum(hModelId, hObjNum);

//頂点データはモデルデータ単位で同じ
hModelData->setVctCnt(hModelId, TYOUTEN);
hModelData->setVctBufNum(hModelId, hVctBufNum);

//そのマテリアルのインデックス数を取得
int hIdxCnt = modeldata->material[i].face_vert_count;

//インデックス情報をセット
hModelData->setIdxCnt(hModelId, hIdxCnt);
hModelData->setIdxSta(hModelId, hIdxStaWork);
hModelData->setIdxBufNum(hModelId, hIdxBufNum);

//テクスチャー情報をセット
//なぜかID3D11ShaderResourceViewをnewすると怒られるので,この場で生成してモデルデータクラスにセットする
if(texture_file[i*MATERIAL_FILENAME_MAX] != 0x00){
//テクスチャーファイルを読み込み
D3DX11_IMAGE_LOAD_INFO LoadInfo;
LoadInfo.Width = 0;
LoadInfo.Height = 0;
LoadInfo.Depth = 0;
LoadInfo.FirstMipLevel = 0;
LoadInfo.MipLevels = D3DX11_DEFAULT,
LoadInfo.Usage = D3D11_USAGE_DEFAULT;
LoadInfo.BindFlags = D3D11_BIND_SHADER_RESOURCE;
LoadInfo.CpuAccessFlags = 0;
LoadInfo.MiscFlags = 0;
LoadInfo.Format = DXGI_FORMAT_R32G32B32_FLOAT;
LoadInfo.Filter = D3DX11_FILTER_TRIANGLE;
LoadInfo.MipFilter = D3DX11_FILTER_TRIANGLE;
LoadInfo.pSrcInfo = NULL;

ID3D11ShaderResourceView* hpShaderResourceView = NULL;

LPCSTR file;
char w[MATERIAL_FILENAME_MAX];
memcpy(w, &texture_file[i*MATERIAL_FILENAME_MAX], MATERIAL_FILENAME_MAX);
file = w;
if(FAILED(D3DX11CreateShaderResourceViewFromFile(hpDevice, file, &LoadInfo, NULL, &hpShaderResourceView, NULL))){
MessageBoxW(hWnd, L"D3DX11CreateShaderResourceViewFromFile", L"Err", MB_ICONSTOP);
goto End;
}

//テクスチャー情報をセット
//次のテクスチャー番号を取得
int hTexSta = hModelData->getTexMax();
hModelData->setTexCnt(hModelId, 1);
hModelData->setTexSta(hModelId, hTexSta);
hModelData->setTexSRV(hTexSta, 0, hpShaderResourceView);
hModelData->setPsNum(hModelId, 1); //PSにテクスチャー描画をセット
}else{
hModelData->setPsNum(hModelId, 0); //PSにマテリアル描画をセット
}

//描画フラグをするに設定
hModelData->setDrawYes(hModelId, 1);

hIdxStaWork += hIdxCnt;
}

// == データ保管ここまで ==
delete []texture_file;

hVectorData = NULL;
}
描画がなかなか安定せず,苦労しました
結局,全体的に必要なデータをクラスに放り込んで管理するようにする事で解決しています

・main.cpp~最後まで
	//プリミティブ(ポリゴンの形状)をコンテキストに設定
hpDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// hpDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

//予めHLSLをコンパイルしてヘッダーに追加しておきます

//頂点レイアウト作成
ID3D11InputLayout* hpInputLayout = NULL;
if(FAILED(hpDevice->CreateInputLayout(hInElementDesc, ARRAYSIZE(hInElementDesc), &g_vs_main, sizeof(g_vs_main), &hpInputLayout))){
MessageBoxW(hWnd, L"CreateInputLayout", L"Err", MB_ICONSTOP);
goto End;
}

//頂点レイアウトをコンテキストに設定
hpDeviceContext->IASetInputLayout(hpInputLayout);

//頂点シェーダー生成
ID3D11VertexShader* hpVertexShader;
if(FAILED(hpDevice->CreateVertexShader(&g_vs_main, sizeof(g_vs_main), NULL, &hpVertexShader))){
MessageBoxW(hWnd, L"CreateVertexShader", L"Err", MB_ICONSTOP);
goto End;
}

//ラスタライザー生成
ID3D11RasterizerState* hpRasterizerState = NULL;
D3D11_RASTERIZER_DESC hRasterizerDesc = {
D3D11_FILL_SOLID,
// D3D11_FILL_WIREFRAME,
D3D11_CULL_NONE, //ポリゴンの裏表を無くす
FALSE,
0,
0.0f,
FALSE,
FALSE,
FALSE,
FALSE,
FALSE
};
if(FAILED(hpDevice->CreateRasterizerState(&hRasterizerDesc, &hpRasterizerState))){
MessageBoxW(hWnd, L"CreateRasterizerState", L"Err", MB_ICONSTOP);
goto End;
}

//ラスタライザーをコンテキストに設定
hpDeviceContext->RSSetState(hpRasterizerState);

//ピクセルシェーダー生成(マテリアル描画用)
// ID3D11PixelShader* hpPixelShaders = new ID3D11PixelShader[2]; //←できない
ID3D11PixelShader* hpPixelShader;
if(FAILED(hpDevice->CreatePixelShader(&g_ps_main, sizeof(g_ps_main), NULL, &hpPixelShader))){
MessageBoxW(hWnd, L"CreateVertexShader", L"Err", MB_ICONSTOP);
goto End;
}

//ピクセルシェーダー2生成(テクスチャー描画用)
ID3D11PixelShader* hpPixelShader2;
if(FAILED(hpDevice->CreatePixelShader(&g_ps_main2, sizeof(g_ps_main2), NULL, &hpPixelShader2))){
MessageBoxW(hWnd, L"CreateVertexShader 2", L"Err", MB_ICONSTOP);
goto End;
}

//グラフィックパイプライン処理
//頂点シェーダーをコンテキストに設定
hpDeviceContext->VSSetShader(hpVertexShader, NULL, 0);
//ハルシェーダーは無し
hpDeviceContext->HSSetShader(NULL, NULL, 0 );
//テッセレーターは無し
//ドメインシェーダーは無し
hpDeviceContext->DSSetShader(NULL, NULL, 0 );
//ジオメトリシェーダーは無し
hpDeviceContext->GSSetShader(NULL, NULL, 0 );

//メインループ
MSG hMsg;
while(true){
while(PeekMessageW(&hMsg, NULL, 0, 0, PM_REMOVE)){
if(hMsg.message == WM_QUIT){
goto End;
}
TranslateMessage(&hMsg);
DispatchMessage(&hMsg);
}

//背景クリア
float ClearColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
hpDeviceContext->ClearRenderTargetView(hpRenderTargetView, ClearColor);
hpDeviceContext->ClearDepthStencilView(hpDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);

//カメラデータセット
hModelData->setCamEye(0, 0.0f, 10.0f, -20.0f, 0.0f); //カメラの位置
hModelData->setCamAt(0, 0.0f, 10.0f, 0.0f, 0.0f); //焦点の位置
hModelData->setCamUp(0, 0.0f, 1.0f, 0.0f, 0.0f);
hModelData->setCamFov(0, 60.0f, 16.0f/9.0f, 0.1f, 1000.0f);

//オブジェ単位に表示場所を設定
hModelData->setObjIdentity(1);
hModelData->setObjTranslation(1, 5.0, 0.0, 0.0);
hModelData->setObjIdentity(2);
hModelData->setObjTranslation(2, -5.0, 0.0, 0.0);

//最大セット可能モデルデータ数までループする
for(int mdcnt=0; mdcnt < hModelData->getMaxModelId(); mdcnt++){
//描画するデータが存在するか?
if (hModelData->getDrawYes(mdcnt)){
//シェーダーに送信
hConstantBuffer.mWorld = hModelData->getObjWld(hModelData->getObjNum(mdcnt));
hConstantBuffer.mView = hModelData->getCamView(0);
hConstantBuffer.mProjection = hModelData->getProjection(0);
hpDeviceContext->UpdateSubresource(hpConstantBuffer, 0, NULL, &hConstantBuffer, 0, 0);
hpDeviceContext->VSSetConstantBuffers(0, 1, &hpConstantBuffer);

//頂点バッファー切り替え
UINT hStrides = sizeof(Vertex3D);
UINT hOffsets = 0;
hpDeviceContext->IASetVertexBuffers(0, 1, &hModelData->vctBuf[hModelData->getVctBufNum(mdcnt)], &hStrides, &hOffsets);

//インデックスバッファー切り替え
hpDeviceContext->IASetIndexBuffer(hModelData->idxBuf[hModelData->getIdxBufNum(mdcnt)], DXGI_FORMAT_R16_UINT, 0);

//テクスチャー切り替え
ID3D11ShaderResourceView* hpShaderResourceViews[] = { hModelData->getTexSRV(hModelData->getTexSta(mdcnt), 0) };
hpDeviceContext->PSSetShaderResources(0, 1, hpShaderResourceViews);

//ピクセルシェーダー切り替え
if(hModelData->getPsNum(mdcnt) == 0){
hpDeviceContext->PSSetShader(hpPixelShader2, NULL, 0);
}else if(hModelData->getPsNum(mdcnt) == 1){
hpDeviceContext->PSSetShader(hpPixelShader, NULL, 0);
}

//インデックス描画
hpDeviceContext->DrawIndexed(hModelData->getIdxCnt(mdcnt), hModelData->getIdxSta(mdcnt), 0);
}
}

hpDXGISwpChain->Present(0, 0);
}

End:
//ポインタで生成したものはリリースする必要がある
//どの変数か識別し易いように,hpで始めてある
SAFE_RELEASE(hpPixelShader);
SAFE_RELEASE(hpVertexShader);
SAFE_RELEASE(hpInputLayout);
SAFE_RELEASE(hpRasterizerState);
//↓初期化
SAFE_RELEASE(hpRenderTargetView);
SAFE_RELEASE(hpBackBuffer);
SAFE_RELEASE(hpDXGISwpChain);
SAFE_RELEASE(hpDeviceContext);
SAFE_RELEASE(hpDevice);

return 0;
}
モデルデータを管理するクラスです
クラスと言うより,構造体的な使い方をしています

最初に定義しているstatic const郡は適当です(^^;

publicにバッファーポインタを置いているのは,本来すべきではありません(ぁ
ですが,ポインタを渡した後,うっかり変数をクリアしてしまうミスが多発した為(私的に(^^),やむおうえず直接アクセスすることにしました
なぜか,=NULLとかすると,中身が消えちゃうんですよ(当たり前)

・modeldata.h
#include <d3d11.h>
#include <xnamath.h>
#define D3DX_PI ((FLOAT) 3.141592654f)
#define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f))

class modeldata{
public:
static const int MAX_MODEL_ID = 256*256; //最大セット可能モデルデータ
static const int MAX_INDEX = 256*256*256; //最大インデックス数
static const int MAX_VECTOR = 256*256*256; //最大頂点数
static const int MAX_VTX_BUF = 256; //最大頂点バッファー
static const int MAX_IDX_BUF = 256; //最大インデックスバッファー
static const int MAX_TEXTURE = 128; //最大テクスチャー枚数(制限がコレっぽいが,今ひとつ確証は持てない)
static const int MAX_OBJET = 256; //最大セット可能なオブジェデータ
static const int MAX_CAMERA = 1; //とりあえずカメラは1台だけ

//頂点バッファー保存場所
ID3D11Buffer *vctBuf[MAX_VTX_BUF];
//インデックスバッファー保存場所
ID3D11Buffer *idxBuf[MAX_IDX_BUF];
private:
//管理用変数
int datYes[MAX_MODEL_ID]; //データが存在するか?
int drawYes[MAX_MODEL_ID]; //描画するか?

//モデルデータ保管用
//モデルデータヘッダー情報
int idxCnt[MAX_MODEL_ID]; //インデックス数
int idxSta[MAX_MODEL_ID]; //インデックス開始番号
int vctCnt[MAX_MODEL_ID]; //頂点数
int texCnt[MAX_MODEL_ID]; //テクスチャー数(最大1枚)
int texSta[MAX_MODEL_ID]; //テクスチャーデータ開始番号
int psNum[MAX_MODEL_ID]; //ピクセルシェーダー番号
int objNum[MAX_MODEL_ID]; //オブジェ番号
int vctBufNum[MAX_MODEL_ID]; //頂点バッファー番号
int idxBufNum[MAX_MODEL_ID]; //インデックスバッファー番号

//オブジェ管理データ
XMMATRIX objWld[MAX_OBJET];

//テクスチャーデータ保存場所
//ピクセルシェーダーHLSL的に,各モデルデータには1つだけしかテクスチャーを扱えない
ID3D11ShaderResourceView *texSRV[MAX_TEXTURE][1];

//カメラ用情報
float camEye[MAX_CAMERA][4]; //カメラの位置
float camAt[MAX_CAMERA][4]; //焦点の位置
float camUp[MAX_CAMERA][4]; //上の向き
float camFov[MAX_CAMERA][4]; //パースペクティブ射影行列作成

public:
//コンストラクタ
modeldata();

//デストラクタ
~modeldata();

//新しいモデルデータを生成
int newData();

//描画フラグを変更(モデルID, 0:描画しない/1:描画する)
void setDrawYes(int,int);

//保管モデルデータ最大数取得
int getMaxModelId(void);

//データが存在するかを返す
int getDatYes(int);

//描画するかを返す
int getDrawYes(int);

//頂点データ用メソッド郡
//頂点数をセット(モデルID,頂点数)
void setVctCnt(int,int);

//保管頂点バッファーデータ最大数取得
int getMaxVctBufNum(void);

//頂点バッファー番号をセット
void setVctBufNum(int,int);

//頂点バッファー番号を返す
int getVctBufNum(int);

//インデックスデータ用メソッド郡
//インデックス数をセット(モデルID,頂点数)
void setIdxCnt(int,int);

//インデックスデータ開始番号をセット(モデルID,開始番号)
void setIdxSta(int,int);

//インデックス数を返す(モデルID)
int getIdxCnt(int);

//インデックス開始番号を返す(モデルID)
int getIdxSta(int);

//保管頂点インデックスバッファーデータ最大数取得
int getMaxIdxBufNum(void);

//インデックスバッファー番号をセット
void setIdxBufNum(int,int);

//インデックスバッファー番号を返す
int getIdxBufNum(int);

//テクスチャーデータ用メソッド郡
//セットされている最大のテクスチャー番号を返す(次の開始位置が返る)
int getTexMax(void);

//テクスチャー数をセット(モデルID,頂点数)
void setTexCnt(int,int);

//テクスチャーデータ開始番号をセット(モデルID,開始番号)
void setTexSta(int,int);

//テクスチャーデータをセット(テクスチャー番号,カウント,テクスチャーデータ)
void setTexSRV(int,int,ID3D11ShaderResourceView*);

//テクスチャーデータを返す(テクスチャー番号,カウント)
ID3D11ShaderResourceView *getTexSRV(int,int);

//ピクセルシェーダー番号セット(モデルID,0:マテリアル/1:テクスチャー)
void setPsNum(int,int);

//テクスチャー開始番号を返す(モデルID)
int getTexSta(int);

//ピクセルシェーダー番号を返す(モデルID)
int getPsNum(int);

//カメラ用メソッド郡
void setCamEye(int,float,float,float,float);
void setCamAt(int,float,float,float,float);
void setCamUp(int,float,float,float,float);
void setCamFov(int,float,float,float,float);
//ビューを計算して返す
XMMATRIX getCamView(int);
//プロジェクションを計算して返す
XMMATRIX getProjection(int);

//オブジェ用メソッド郡
//セットされている最大のオブジェ番号を返す(次の開始位置が返る)
int getObjMax(void);
void setObjNum(int,int);
int getObjNum(int);
//ワールド座標を取得
XMMATRIX getObjWld(int);
//初期化(オブジェ番号)
void setObjIdentity(int);
//移動(オブジェ番号,X,Y,Z)
void setObjTranslation(int,float,float,float);
};
モデルデータの必要なデータを正確に出し入れできるようにする事が目的の部分です
メインのソースを見た時に,setで入れて,getで出している。という事が雰囲気でわかるようになるので,ミスを減らせました

・modeldata.cpp~頂点・インデックス・テクスチャーデータまで
#include "modeldata.h"
#include <windows.h>

//コンストラクタ
modeldata::modeldata()
{
for(int mdcnt=0; mdcnt < MAX_MODEL_ID; mdcnt++){
datYes[mdcnt] = 0; //データは存在しない
drawYes[mdcnt] = 0; //描画しない
idxCnt[mdcnt] = 0;
idxSta[mdcnt] = 0;
vctCnt[mdcnt] = 0;
texCnt[mdcnt] = 0;
texSta[mdcnt] = 0;
psNum[mdcnt] = 0;
objNum[mdcnt] = 0;
vctBufNum[mdcnt] = 0;
idxBufNum[mdcnt] = 0;
}
}

//デストラクタ
modeldata::~modeldata()
{
}

//新しいモデルデータを生成
int modeldata::newData(){
for(int mdcnt=0; mdcnt < MAX_MODEL_ID; mdcnt++){
if(datYes[mdcnt] == 0){
datYes[mdcnt] = 1; //データは存在する
return mdcnt; //生成したモデルデータのカウントを返す
}
}

return -1; //生成エラー
}

//描画フラグを変更(モデルID, 0:描画しない/1:描画する)
void modeldata::setDrawYes(int modelId, int flag){
drawYes[modelId] = flag;
}

//頂点数をセット(モデルID,頂点数)
void modeldata::setVctCnt(int modelId, int hVctCnt){
vctCnt[modelId] = hVctCnt;
}

//保管頂点バッファーデータ最大数取得
int modeldata::getMaxVctBufNum(void){
//最終位置を探す
int hMaxVctBufNum = 0;
for(int i=0; i < MAX_MODEL_ID; i++){
if(hMaxVctBufNum < vctBufNum[i]){
hMaxVctBufNum = vctBufNum[i];
}
}

//次の値にする
hMaxVctBufNum++;

return hMaxVctBufNum;
}

//頂点バッファー番号をセット
void modeldata::setVctBufNum(int modelId, int hVctBufNum){
vctBufNum[modelId] = hVctBufNum;
}

//頂点バッファー番号を返す
int modeldata::getVctBufNum(int modelId){
return vctBufNum[modelId];
}

//保管モデルデータ最大数取得
int modeldata::getMaxModelId(){
return MAX_MODEL_ID;
}

//データが存在するかを返す
int modeldata::getDatYes(int hIdxNum){
return datYes[hIdxNum];
}

//描画するかを返す
int modeldata::getDrawYes(int hIdxNum){
return drawYes[hIdxNum];
}

//インデックス数をセット(モデルID,頂点数)
void modeldata::setIdxCnt(int modelId, int hIdxCnt){
idxCnt[modelId] = hIdxCnt;
}

//インデックスデータ開始番号をセット(モデルID,開始番号)
void modeldata::setIdxSta(int modelId, int hIdxSta){
idxSta[modelId] = hIdxSta;
}

//保管インデックスバッファーデータ最大数取得
int modeldata::getMaxIdxBufNum(void){
//最終位置を探す
int hMaxIdxBufNum = 0;
for(int i=0; i < MAX_MODEL_ID; i++){
if(hMaxIdxBufNum < idxBufNum[i]){
hMaxIdxBufNum = idxBufNum[i];
}
}

//次の値にする
hMaxIdxBufNum++;

return hMaxIdxBufNum;
}

//インデックスバッファー番号をセット
void modeldata::setIdxBufNum(int modelId, int hIdxBufNum){
idxBufNum[modelId] = hIdxBufNum;
}

//インデックスバッファー番号を返す
int modeldata::getIdxBufNum(int modelId){
return idxBufNum[modelId];
}

//セットされている最大のテクスチャー番号を返す(次の開始位置が返る)
int modeldata::getTexMax(void){
//最終位置を探す
int hMaxTexSta = 0;
int hMaxTexCnt = 0;
for(int i=0; i < MAX_MODEL_ID; i++){
if(hMaxTexSta < texSta[i]){
hMaxTexSta = texSta[i];
hMaxTexCnt = texCnt[i];
}
}

//それに,それ自身の頂点数を加算した値がラスト
hMaxTexSta += hMaxTexCnt;

return hMaxTexSta;
}

//テクスチャーをセット(モデルID,テクスチャー数)
void modeldata::setTexCnt(int modelId, int hTexCnt){
texCnt[modelId] = hTexCnt;
}

//テクスチャーデータ開始番号をセット(モデルID,開始番号)
void modeldata::setTexSta(int modelId, int hTexSta){
texSta[modelId] = hTexSta;
}

//テクスチャーデータをセット(モデルid,テクスチャーID,テクスチャーデータ)
void modeldata::setTexSRV(int modelId, int id, ID3D11ShaderResourceView* hSRV){
texSRV[modelId][id] = hSRV;
}

//テクスチャーデータを返す(モデルid,テクスチャーID)
ID3D11ShaderResourceView *modeldata::getTexSRV(int modelId, int id){
return texSRV[modelId][id];
}

//ピクセルシェーダー番号セット(モデルID,0:マテリアル/1:テクスチャー)
void modeldata::setPsNum(int modelId,int hPsNum){
psNum[modelId] = hPsNum;
}

//インデックス数を返す
int modeldata::getIdxCnt(int hIdxNum){
return idxCnt[hIdxNum];
}

//インデックス開始番号を返す
int modeldata::getIdxSta(int hIdxNum){
return idxSta[hIdxNum];
}

//テクスチャー開始番号を返す(モデルID)
int modeldata::getTexSta(int hIdxNum){
return texSta[hIdxNum];
}

//ピクセルシェーダー番号を返す(モデルID)
int modeldata::getPsNum(int hIdxNum){
return psNum[hIdxNum];
}
ついでに,カメラデータの管理も組み込みました
そのうち,カメラを動かす事を考えると,モデルとの連携が必要になるのではないか? と思います

それと PMDファイル単位をオブジェと読んで,一まとめにくくって操作する仕組みも組み込みました
こうすることで,ミクは左,リンは右,のように指示を出せます

・modeldata.cpp~最後まで
//カメラ用メソッド郡
void modeldata::setCamEye(int hCamNum,float hEyeX,float hEyeY,float hEyeZ,float hEyeW){
camEye[hCamNum][0] = hEyeX;
camEye[hCamNum][1] = hEyeY;
camEye[hCamNum][2] = hEyeZ;
camEye[hCamNum][3] = hEyeW;
}
void modeldata::setCamAt(int hCamNum,float hAtX,float hAtY,float hAtZ,float hAtW){
camAt[hCamNum][0] = hAtX;
camAt[hCamNum][1] = hAtY;
camAt[hCamNum][2] = hAtZ;
camAt[hCamNum][3] = hAtW;
}
void modeldata::setCamUp(int hCamNum,float hUpX,float hUpY,float hUpZ,float hUpW){
camUp[hCamNum][0] = hUpX;
camUp[hCamNum][1] = hUpY;
camUp[hCamNum][2] = hUpZ;
camUp[hCamNum][3] = hUpW;
}
void modeldata::setCamFov(int hCamNum,float hFovAngY,float hAspHByW,float hNearZ,float hFarZ){
camFov[hCamNum][0] = hFovAngY;
camFov[hCamNum][1] = hAspHByW;
camFov[hCamNum][2] = hNearZ;
camFov[hCamNum][3] = hFarZ;
}
//ビューを計算して返す
XMMATRIX modeldata::getCamView(int hCamNum){
XMVECTOR hEye = XMVectorSet(camEye[hCamNum][0], camEye[hCamNum][1], camEye[hCamNum][2], camEye[hCamNum][3]); //カメラ
XMVECTOR hAt = XMVectorSet(camAt[hCamNum][0], camAt[hCamNum][1], camAt[hCamNum][2], camAt[hCamNum][3]); //焦点の位置
XMVECTOR hUp = XMVectorSet(camUp[hCamNum][0], camUp[hCamNum][1], camUp[hCamNum][2], camUp[hCamNum][3]);
XMMATRIX hView = XMMatrixLookAtLH(hEye, hAt, hUp);
return XMMatrixTranspose(hView);
}
//プロジェクションを計算して返す
XMMATRIX modeldata::getProjection(int hCamNum){
XMMATRIX hProjection = XMMatrixPerspectiveFovLH(D3DXToRadian(camFov[hCamNum][0]), camFov[hCamNum][1], camFov[hCamNum][2], camFov[hCamNum][3]);
return XMMatrixTranspose(hProjection);
}

//オブジェ用メソッド郡
//セットされている最大のオブジェ番号を返す(次の開始位置が返る)
int modeldata::getObjMax(void){
//最大のオブジェ番号を探す
int hMaxObj = 0;
for(int i=0; i < MAX_MODEL_ID; i++){
if(hMaxObj < objNum[i]){
hMaxObj = objNum[i];
}
}

//次の開始位置にする
hMaxObj++;

return hMaxObj;
}
void modeldata::setObjNum(int hIdxNum,int hObjNum){
objNum[hIdxNum] = hObjNum;
}
int modeldata::getObjNum(int hIdxNum){
return objNum[hIdxNum];
}
//ワールド座標を取得
XMMATRIX modeldata::getObjWld(int hObjNum){
return XMMatrixTranspose(objWld[hObjNum]);
}
//初期化(オブジェ番号)
void modeldata::setObjIdentity(int hObjNum){
objWld[hObjNum] = XMMatrixIdentity();
}
//移動(オブジェ番号,X,Y,Z)
void modeldata::setObjTranslation(int hObjNum,float hX,float hY,float hZ){
XMMATRIX hMatrix = XMMatrixTranslation(hX, hY, hZ);
objWld[hObjNum] = XMMatrixMultiply(objWld[hObjNum], hMatrix);
}
PMDデータを読み込むプログラムのヘッダーです
前にも書きましたが,アラインメント制御をオフる必要があります
ちなみに gccは #pragma pack(1)~#pragma pack()です

・pmd.h
class pmd{
public:
#pragma pack(push,1) //アラインメント制御をオフる
//ヘッダー
struct t_header{
unsigned char magic[3];
float version;
unsigned char model_name[20];
unsigned char comment[256];
};
t_header header;
//頂点リスト
unsigned long vert_count;
struct t_vertex{
float pos[3];
float normal_vec[3];
float uv[2];
unsigned short bone_num[2];
unsigned char bone_weight;
unsigned char edge_flag;
};
t_vertex *vertex;
//面頂点リスト
unsigned long face_vert_count;
unsigned short *face_vert_index;
//材質リスト
unsigned long material_count;
struct t_material{
float diffuse_color[3];
float alpha;
float specularity;
float specular_color[3];
float mirror_color[3];
unsigned char toon_index;
unsigned char edge_flag;
unsigned long face_vert_count;
char texture_file_name[20];
};
t_material *material;
#pragma pack(pop) //アラインメント制御エンド

//コンストラクタ
pmd(char *);

//デストラクタ
~pmd();
};
PMDデータを読み込むプログラム部分です
構造体に放り込んでいっているだけです(PMDはそういう形式のフォーマット)

なんかフォーマットがおかしいと思ったら,TSXBINで見てみれば良いでしょう

・pmd.cpp
#include "pmd.h"
#include <windows.h>
#include <stdio.h>

//コンストラクタ
pmd::pmd(char *filename)
{
FILE *hFP;
hFP = fopen(filename, "rb");
if(hFP != 0){
//ヘッダー読み込み
fread(&header, sizeof(struct t_header), 1, hFP);

//頂点数読み込み
fread(&vert_count, sizeof(vert_count), 1, hFP);

//頂点データ読み込み
vertex = new t_vertex[vert_count];
fread(vertex, 38, vert_count, hFP);

//面頂点リスト読み込み
fread(&face_vert_count, sizeof(face_vert_count), 1, hFP);

//面頂点リストデータ読み込み
face_vert_index = new unsigned short[face_vert_count];
fread(face_vert_index, 2, face_vert_count, hFP);

//材質リスト材質数
fread(&material_count, sizeof(material_count), 1, hFP);

//材質リストデータ読み込み
material = new t_material[material_count];
fread(material, 70, material_count, hFP);

fclose(hFP);
}else{
MessageBoxW(NULL, L"fopen", L"Err", MB_ICONSTOP);
}
}

//デストラクタ
pmd::~pmd(void)
{
delete [] vertex;
delete [] face_vert_index;
delete [] material;
}
頂点シェーダーHLSLです
これはそのままです

コンパイルコマンドも書いておくと
"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Utilities\bin\x64\fxc.exe" vs.fx /T vs_4_0 /E vs_main /Fh vs.h
・vs.fx
//入力用
struct vertexIn
{
float4 pos : POSITION0;
float4 col : COLOR0;
float2 tex : TEXCOORD0;
};

//出力用
struct vertexOut
{
float4 pos : SV_POSITION;
float4 col : COLOR;
float2 tex : TEXCOORD0;
};

//変換用行列
cbuffer ConstantBuffer : register(b0)
{
matrix World; //ワールド変換行列
matrix View; //ビュー変換行列
matrix Projection; //透視射影変換行列
}

vertexOut vs_main(vertexIn IN)
{
vertexOut OUT;

OUT.pos = mul(IN.pos, World);
OUT.pos = mul(OUT.pos, View);
OUT.pos = mul(OUT.pos, Projection);
OUT.col = IN.col;
OUT.tex = IN.tex;

return OUT;
}
ピクセルシェーダーのHLSLです
これには2つのプログラムが入っています

ps_mainがテクスチャー用
ps_main2がマテリアル用
です

コンパイル時に切り分けます
"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Utilities\bin\x64\fxc.exe" ps.fx /T ps_4_0 /E ps_main /Fh ps.h

"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Utilities\bin\x64\fxc.exe" ps.fx /T ps_4_0 /E ps_main2 /Fh ps_2.h

//入力用
struct pixcelIn
{
float4 pos : SV_POSITION;
float4 col : COLOR;
float2 tex : TEXCOORD0;
};

Texture2D txDiffuse : register(t0);
SamplerState samLinear : register(s0);

float4 ps_main(pixcelIn IN) : SV_Target
{
pixcelIn OUT;

OUT.col = txDiffuse.Sample(samLinear, IN.tex);

//なんか妙に明るくなるので,少し暗くする
OUT.col.r -= 0.3f;
OUT.col.g -= 0.3f;
OUT.col.b -= 0.3f;

return OUT.col;
}

float4 ps_main2(pixcelIn IN) : SV_Target
{
pixcelIn OUT;

//カラーをそのまま返す
OUT.col = IN.col;

//なんか妙に明るくなるので,少し暗くする
OUT.col.r -= 0.3f;
OUT.col.g -= 0.3f;
OUT.col.b -= 0.3f;

return OUT.col;
}
今までのソースをまとめて実行すると,こういう風に描画されます

まだバグがあります
ステージを追加すると,テクスチャーが飛んじゃうとか,妙に小さいとかw
↓こんな感じに

データによってはアクセス違反でコケる場合もあります
その辺りは,研究を進めながらボチボチ修正していきます


○VPVP
http://www.geocities.jp/higuchuu4/index.htm
MikuMikuDance(DirectX9 Ver)付属の初音ミク.pmdと鏡音リン.pmdをお借りしました


TOPプログラマ専用DirectX11開発

ネコミトリ 詰めロイヤルマリッジ+ネコミトリ りうるうり -ノーマル-+