ich habe eine Minimalanwendung mit DX9 auf Basis der Tutorials im SDK geschrieben. Das Ziel ist es zu lernen wie Postprocessing funktioniert. Aktuell möchte ich mit dem Shader einfach nur das Bild in Graustufen umwandeln. Später soll das Bild über mathematische Funktionen auch noch verzerrt werden.Leider befinde ich mich gerade in einer Sackgasse. Hoffentlich kann mir hier jemand helfen.
Code: Alles auswählen
#include <Windows.h>
#include <tchar.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <d3d9.h>
#include <D3dx9tex.h>
#pragma comment(lib, "D3d9.lib")
#pragma comment(lib, "D3dx9.lib")
#pragma comment(lib, "Winmm.lib")
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
LPDIRECT3DTEXTURE9 g_pObjectTexture = NULL;
LPDIRECT3DTEXTURE9 g_pRenderTexture = NULL;
LPD3DXEFFECT g_pEffect = NULL;
typedef struct
{
D3DXVECTOR3 position; // The position
D3DCOLOR color; // The color
FLOAT tu, tv; // The texture coordinates
} CUSTOMVERTEX;
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1)
char* g_Shader = "texture g_txSrcColor;\n"
"\n"
"sampler2D g_samSrcColor =\n"
"sampler_state\n"
"{\n"
" Texture = <g_txSrcColor>;\n"
" AddressU = Clamp;\n"
" AddressV = Clamp;\n"
" MinFilter = Point;\n"
" MagFilter = Linear;\n"
" MipFilter = Linear;\n"
"};\n"
"\n"
"float3 LuminanceConv = { 0.2125f, 0.7154f, 0.0721f };\n"
"\n"
"float4 PostProcessPS( float2 Tex : TEXCOORD0 ) : COLOR0\n"
"{\n"
" return dot( (float3)tex2D( g_samSrcColor, Tex ), LuminanceConv );\n"
"}\n"
"\n"
"technique PostProcess\n"
"{\n"
" pass p0\n"
" {\n"
" VertexShader = null;\n"
" PixelShader = compile ps_2_0 PostProcessPS();\n"
" ZEnable = false;\n"
" }\n"
"}\n";
BOOL CreateScene()
{
// Use D3DX to create a texture from a file based image
if(FAILED(D3DXCreateTextureFromFile(g_pd3dDevice, _T("banana.bmp"), &g_pObjectTexture)))
{
// If texture is not in current folder, try parent folder
if(FAILED( D3DXCreateTextureFromFile(g_pd3dDevice, _T("..\\banana.bmp"), &g_pObjectTexture)))
{
MessageBox(NULL, _T("Could not find banana.bmp"), _T("Error"), MB_OK);
return FALSE;
}
}
// Create the vertex buffer.
if(FAILED(g_pd3dDevice->CreateVertexBuffer(50 * 2 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL))) return FALSE;
// Fill the vertex buffer. We are setting the tu and tv texture
// coordinates, which range from 0.0 to 1.0
CUSTOMVERTEX* pVertices;
if(FAILED( g_pVB->Lock(0, 0, ( void** )&pVertices, 0))) return FALSE;
for(DWORD i = 0; i < 50; i++)
{
FLOAT theta = ( 2 * M_PI * i ) / ( 50 - 1 );
pVertices[2 * i + 0].position .x = sinf(theta);
pVertices[2 * i + 0].position .y = -1.0f;
pVertices[2 * i + 0].position .z = cosf(theta);
pVertices[2 * i + 0].color = 0xffffffff;
pVertices[2 * i + 0].tu = ((FLOAT)i) / 49;
pVertices[2 * i + 0].tv = 1.0f;
pVertices[2 * i + 1].position.x = sinf(theta);
pVertices[2 * i + 1].position.y = 1.0f;
pVertices[2 * i + 1].position.z = cosf(theta);
pVertices[2 * i + 1].color = 0xff808080;
pVertices[2 * i + 1].tu = ((FLOAT)i) / 49;
pVertices[2 * i + 1].tv = 0.0f;
}
g_pVB->Unlock();
// Create the effect
DWORD dwShaderFlags = 0;
dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
dwShaderFlags |= D3DXSHADER_NO_PRESHADER;
#ifdef _DEBUG
dwShaderFlags |= D3DXSHADER_DEBUG;
#endif
ID3DXBuffer* err = NULL;
if(FAILED(D3DXCreateEffect(g_pd3dDevice, g_Shader, strlen(g_Shader), NULL, NULL, 0, NULL, &g_pEffect, &err))) return FALSE;
g_pEffect->SetTexture("g_txSrcColor", g_pRenderTexture);
return TRUE;
}
void Render()
{
if(NULL == g_pd3dDevice) return;
// Clear the backbuffer to a blue color
g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 255), 1.0f, 0);
// Begin the scene
if(SUCCEEDED(g_pd3dDevice->BeginScene()))
{
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity(&matWorld);
D3DXMatrixRotationX(&matWorld, timeGetTime() / 1000.0f);
g_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
D3DXVECTOR3 vEyePt( 0.0f, 3.0f,-5.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec);
g_pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f);
g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
g_pd3dDevice->SetTexture(0, g_pObjectTexture);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
g_pd3dDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(CUSTOMVERTEX));
g_pd3dDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
//begin the effect
UINT uiPasses = 0;
g_pEffect->Begin(&uiPasses, 0);
for (UINT uiPass = 0; uiPass < uiPasses; uiPass++)
{
//render an effect pass
g_pEffect->BeginPass(uiPass);
//render the rectangle
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2 * 50 - 2);
g_pEffect->EndPass();
}
g_pEffect->End();
g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2 * 50 - 2);
g_pd3dDevice->EndScene();
}
// Present the backbuffer contents to the display
g_pd3dDevice->Present(NULL, NULL, NULL, NULL);
}
LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_KEYDOWN:
if(wParam == VK_ESCAPE) PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
//
// Register class
//
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = _T("DXTest");
wcex.hIconSm = LoadIcon(NULL, (LPCTSTR)IDI_APPLICATION);
if(!RegisterClassEx(&wcex)) return FALSE;
//
// Create window
//
g_hInst = hInstance;
RECT rc = { 0, 0, 800, 600 };
AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE);
g_hWnd = CreateWindow(wcex.lpszClassName, _T("DirectX Test"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, NULL, NULL, hInstance, NULL);
if(!g_hWnd)
return FALSE;
else
ShowWindow(g_hWnd, nShowCmd);
//
// Init D3D
//
if(NULL == (g_pD3D = Direct3DCreate9(D3D_SDK_VERSION))) return FALSE;
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pd3dDevice)))
{
return FALSE;
}
g_pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
//
// Create content
//
if(CreateScene() == FALSE) return FALSE;
//
// Main message loop
//
MSG msg = {0};
while(WM_QUIT != msg.message )
{
if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render();
}
}
//
// Cleanup D3D
//
if(g_pObjectTexture != NULL) g_pObjectTexture->Release();
if(g_pEffect != NULL) g_pEffect->Release();
if(g_pRenderTexture != NULL) g_pRenderTexture->Release();
if(g_pVB != NULL) g_pVB->Release();
if(g_pd3dDevice != NULL) g_pd3dDevice->Release();
if(g_pD3D != NULL) g_pD3D->Release();
UnregisterClass(wcex.lpszClassName, wcex.hInstance);
return (int)msg.wParam;
}
THX
Mr. S