#include <windows.h>
#include <TCHAR.h>
#include <string>
#include <sstream>
#include <d3d9.h>
#include <d3dx9.h>
#ifdef _DEBUG
#define D3D_DEBUG_INFO
#endif
#ifndef UNICODE
typedef std::string tstring;
typedef std::stringstream tstringstream;
#else
typedef std::wstring tstring;
typedef std::wstringstream tstringstream;
#endif
struct Vertex
{
D3DXVECTOR3 pos;
unsigned color;
D3DXVECTOR2 tex;
};
tstring AppName = TEXT("Alpha Blending wird getestet!");
const float ScreenX = 640;
const float ScreenY = 480;
LPDIRECT3D9 D3D;
LPDIRECT3DDEVICE9 D3DDevice;
PDIRECT3DTEXTURE9 chess = NULL;
float timeSum = 0.0f;
Vertex triangle[3];
Vertex rectangle[4];
PDIRECT3DTEXTURE9 GroundTexture = NULL; // Textur des Bodens
LPD3DXMESH GroundModel = NULL; // Bodenmodell
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
bool InitD3D(HWND Window);
bool InitScene();
void ShutdownScene();
void ShutdownD3D();
bool Render(float NumSecsPassed);
bool Move(float NumSecsPassed);
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPTSTR szCmdLine, int iCmdShow)
{
HWND hwnd;
MSG msg;
msg.message = WM_NULL;
WNDCLASS wndclass;
wndclass.style = 0;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)0;
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = AppName.c_str();
if(!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("RegisterClass failed. Maybe you don't have Windows NT?"), AppName.c_str(), MB_ICONERROR);
return 0;
}
tstringstream errorStream;
hwnd = CreateWindow(AppName.c_str(), AppName.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, (int)ScreenX, (int)ScreenY, NULL, NULL, hInstance, NULL);
if(hwnd == NULL)
{
errorStream << TEXT("Failed to create the Window! Error Code: ") << GetLastError();
MessageBox(0, errorStream.str().c_str(), AppName.c_str(), MB_ICONERROR);
return 0;
}
if(!InitD3D(hwnd))
return 0;
if(!InitScene())
return 0;
ShowWindow(hwnd, iCmdShow);
UpdateWindow(hwnd);
unsigned startTime, endTime;
float timeCycle = 0;
while(msg.message != WM_QUIT)
{
startTime = timeGetTime();
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(!Move(timeCycle))
msg.message = WM_QUIT;
if(!Render(timeCycle))
msg.message = WM_QUIT;
endTime = timeGetTime();
timeCycle = (float)(endTime - startTime) / 1000.0f;
}
ShutdownScene();
ShutdownD3D();
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
switch(message)
{
case WM_CREATE:
return 0;
case WM_PAINT:
BeginPaint(hwnd, &ps);
EndPaint(hwnd, &ps);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
bool InitD3D(HWND Window)
{
D3D = Direct3DCreate9(D3D_SDK_VERSION);
if(!D3D)
{
MessageBox(0, TEXT("Failed to create Direct3D!"), AppName.c_str(), MB_ICONERROR);
return false;
}
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = Window;
if(D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Window,
D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &D3DDevice) != D3D_OK)
{
MessageBox(0, TEXT("Failed to create the Direct3D Device!"), AppName.c_str(), MB_ICONERROR);
return false;
}
return true;
}
bool InitScene()
{
if(D3DDevice->SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) != D3D_OK)
{
MessageBox(0, TEXT("Failed to set Vertex Format!"), AppName.c_str(), MB_ICONERROR);
return false;
}
//D3DDevice->SetRenderState(D3DRS_LIGHTING, false);
D3DDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
D3DDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
// Licht
D3DLIGHT9 Light;
Light.Type = D3DLIGHT_POINT;
D3DCOLORVALUE color = {1.0f, 1.0f, 1.0f, 1.0f };
Light.Diffuse = color;
Light.Ambient = color;
Light.Specular = color;
Light.Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
Light.Range = 500.0f;
Light.Attenuation0 = 0.0f;
Light.Attenuation1 = 0.025f;
Light.Attenuation2 = 0.0f;
D3DDevice->SetLight(0, &Light);
D3DDevice->LightEnable(0, TRUE);
float Aspect = ScreenX / ScreenY;
D3DXMATRIX projection;
D3DXMatrixPerspectiveFovLH(&projection, 90.0f * 0.0174532925199432957692369076848f, Aspect, 0.1f, 100.0f);
D3DDevice->SetTransform(D3DTS_PROJECTION, &projection);
triangle[0].pos = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
triangle[0].color = D3DCOLOR_ARGB(120, 255, 0, 0);
triangle[0].tex.x = 0.5f;
triangle[0].tex.y = 0.0f;
triangle[1].pos = D3DXVECTOR3(1.0f, -1.0f, 0.0f);
triangle[1].color = D3DCOLOR_ARGB(120, 0, 255, 0);
triangle[1].tex.x = 1.0f;
triangle[1].tex.y = 1.0f;
triangle[2].pos = D3DXVECTOR3(-1.0f, -1.0f, 0.0f);
triangle[2].color = D3DCOLOR_ARGB(120, 0, 0, 255);
triangle[2].tex.x = 0.0f;
triangle[2].tex.y = 1.0f;
rectangle[0].pos = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
rectangle[0].color = D3DCOLOR_ARGB(120, 255, 0, 0);
rectangle[0].tex.x = 0.0f;
rectangle[0].tex.y = 0.0f;
rectangle[1].pos = D3DXVECTOR3(1.0f, 1.0f, 0.0f);
rectangle[1].color = D3DCOLOR_ARGB(120, 0, 255, 0);
rectangle[1].tex.x = 1.0f;
rectangle[1].tex.y = 0.0f;
rectangle[2].pos = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
rectangle[2].color = D3DCOLOR_ARGB(120, 0, 0, 255);
rectangle[2].tex.x = 0.0f;
rectangle[2].tex.y = 1.0f;
rectangle[3].pos = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
rectangle[3].color = D3DCOLOR_ARGB(120, 0, 0, 0);
rectangle[3].tex.x = 1.0f;
rectangle[3].tex.y = 1.0f;
if(D3DXCreateTextureFromFileEx(D3DDevice, TEXT("Texture.bmp"), D3DX_DEFAULT, D3DX_DEFAULT,
D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE,
D3DX_DEFAULT, 0, NULL, NULL, &chess) != D3D_OK)
{
MessageBox(0, TEXT("Failed to Create the Texture!"), AppName.c_str(), MB_ICONERROR);
return false;
}
if(D3DXCreateTextureFromFileEx(D3DDevice, TEXT("Ground.bmp"), D3DX_DEFAULT, D3DX_DEFAULT,
D3DX_DEFAULT, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE,
D3DX_DEFAULT, 0, NULL, NULL, &GroundTexture) != D3D_OK)
{
MessageBox(0, TEXT("Failed to Create the Texture Ground!"), AppName.c_str(), MB_ICONERROR);
return false;
}
// Das Bodenmodell laden
if(D3DXLoadMeshFromX(TEXT("Ground.x"), D3DXMESH_MANAGED, D3DDevice,
NULL, NULL, NULL, NULL, &GroundModel) != D3D_OK)
{
MessageBox(0, TEXT("Failed to Create the Mesh Ground!"), AppName.c_str(), MB_ICONERROR);
return false;
}
return true;
}
void ShutdownScene()
{
}
void ShutdownD3D()
{
D3DDevice->Release();
D3D->Release();
}
bool Render(float NumSecsPassed)
{
D3DXMATRIX rotation;
D3DXMatrixRotationY(&rotation, 90.0f * 0.0174532925199432957692369076848f * (timeSum));
D3DXMATRIX translation;
D3DXMatrixTranslation(&translation, -2.0f, 0.0f, 4.0f);
D3DXMATRIX world = rotation * translation;
D3DXMATRIX translationRect;
D3DXMatrixTranslation(&translationRect, 2.0f, 0.0f, 4.0f);
D3DXMATRIX translationGround;
D3DXMatrixTranslation(&translationGround, 0.0f, -20.0f, 0.0f);
D3DXMATRIX worldRect = rotation * translationRect;
D3DXMATRIX worldGround = rotation * translationGround;
if(D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0),
1.0f, 0) != D3D_OK)
{
MessageBox(0, TEXT("D3DDevice->Clear failed!"), AppName.c_str(), MB_ICONERROR);
return false;
}
D3DMATERIAL9 Material;
D3DCOLORVALUE colordif = {0.5f, 0.8f, 0.8f, 0.8f };
D3DCOLORVALUE colorspec = {0.5f, 0.3f, 0.3f, 0.3f };
D3DCOLORVALUE coloremi = {0.5f, 0.0f, 0.0f, 0.0f };
Material.Diffuse = colordif;
Material.Ambient = colorspec;
Material.Emissive = coloremi;
Material.Specular = colorspec;
Material.Power = 5.0f;
D3DDevice->SetMaterial(&Material);
D3DDevice->BeginScene();
D3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
D3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
D3DDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
D3DDevice->SetTransform(D3DTS_WORLD, &worldGround);
D3DDevice->SetTexture(0, GroundTexture);
GroundModel->DrawSubset(0);
D3DDevice->SetTexture(0, chess);
D3DDevice->SetTransform(D3DTS_WORLD, &world);
D3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
D3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
D3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
D3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLEND_INVSRCALPHA);
D3DDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
if(D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 1, triangle, sizeof(Vertex)) != D3D_OK)
{
MessageBox(0, TEXT("Failed to draw the triangle!"), AppName.c_str(), MB_ICONERROR);
return false;
}
D3DDevice->SetTransform(D3DTS_WORLD, &worldRect);
if(D3DDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, rectangle, sizeof(Vertex)) != D3D_OK)
{
MessageBox(0, TEXT("Failed to draw the triangle!"), AppName.c_str(), MB_ICONERROR);
return false;
}
D3DDevice->EndScene();
D3DDevice->Present(NULL, NULL, NULL, NULL);
return true;
}
bool Move(float NumSecsPassed)
{
timeSum += NumSecsPassed;
return true;
}