littles_de
Grünschnabel
Hallo liebes Forum!
Bin noch recht unerfahren in der Programmierung und habe mir mittlerweile einige Direct X Tutorials durchgelesen und dann einfach mal drauf los Programmiert. Mein Prog läuft jetzt auch, jedoch würde ich den Code gerne etwas "sauberer" aufsetzen. ich hoffe ich finde hier etwas hilfe, da ich mir gleich einen sauberen Programmierstil zulegen will. Natürlich wäre auch jeder Verbesserungsvorschlag (gerade bei der Beleuchtung!!) eine Riesen hilfe.
Aber jetzt erst mal zum Code:
Vielen Dank für eure Hilfe im vorraus.
littles
Bin noch recht unerfahren in der Programmierung und habe mir mittlerweile einige Direct X Tutorials durchgelesen und dann einfach mal drauf los Programmiert. Mein Prog läuft jetzt auch, jedoch würde ich den Code gerne etwas "sauberer" aufsetzen. ich hoffe ich finde hier etwas hilfe, da ich mir gleich einen sauberen Programmierstil zulegen will. Natürlich wäre auch jeder Verbesserungsvorschlag (gerade bei der Beleuchtung!!) eine Riesen hilfe.
Aber jetzt erst mal zum Code:
Code:
// Windows header | Direct3D header | Eigene header | Multimedia header
#include <windows.h>
#include "stdafx.h"
#include <d3d9.h>
#include <d3dx9.h>
#include <mmsystem.h>
#include "Text.h"
#include "Sound.h"
//Bildschirmauflösung
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT 800
// Direct3D Library files
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
// Windows Multimedia Library files
#pragma comment (lib, "winmm.lib")
// globale deklarationen
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
LPDIRECT3DINDEXBUFFER9 i_buffer = NULL;
LPDIRECT3DTEXTURE9 g_pSphere = NULL;
LPDIRECT3DTEXTURE9 g_pCube = NULL;
LPDIRECT3DTEXTURE9 g_pTube = NULL;
LPD3DXMESH meshXFile; // mesh pointer
LPD3DXMESH meshXFile2;
D3DMATERIAL9* material;
DWORD numMaterials; // anzahl an materials im mesh
//Konstante für Textur und Mesh
//Mesh von X- File
#define x_EARTH L"res\\X Files\\tellus.X"
#define x_TUBE L"res\\X Files\\universe.X"
//Textur
#define i_EARTH L"res\\img\\map.png"
#define i_CUBE L"res\\img\\cellceiling.jpg"
#define i_TUBE L"res\\img\\stars.png"
// Funktionsprototypen
void initD3D(HWND hWnd);
void render_frame(void);
void cleanD3D(void);
void init_graphics(void);
void init_light(void);
void loadTexture(void);
//Größe ändern
HRESULT ScaleMesh(ID3DXMesh *pMesh, float scale, D3DXVECTOR3 *offset);
// WindowProc prototyp
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
//Struktur für XYZ Koordinaten | Normals für Licht usw. | Texturkoordinaten
struct CUSTOMVERTEX {FLOAT X, Y, Z; D3DVECTOR NORMAL;FLOAT tu,tv; };
//Erstelle ein angepasstes Flexible Vertex Format
#define CUSTOMFVF ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1 )
// WinMain Funktion
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hWnd;
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_HAND);
wc.lpszClassName = L"WindowClass";
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL,
L"WindowClass",
m_TITEL,
WS_OVERLAPPEDWINDOW,
0,
0,
SCREEN_WIDTH,
SCREEN_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd, nCmdShow);
initD3D(hWnd);
OpenSong();
//main Endlosschleife
MSG msg;
while(TRUE)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message == WM_QUIT)
break;
render_frame();
}
cleanD3D();
return msg.wParam;
}
// Haupt message handler des programms
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_SYSCOMMAND:
{
switch (wParam)
{
//Screensaver unterdrücken
case SC_SCREENSAVE:
return 0;
}
break;
}
//Mousehandler
case WM_LBUTTONDOWN:
{
PlaySong();
break;
}
case WM_MBUTTONDOWN:
{
PostQuitMessage(0);
return 0;
}
case WM_RBUTTONDOWN:
{
PauseSong();
break;
}
case WM_KEYDOWN:
{
switch( wParam )
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
break;
}
//Beenden
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
void initD3D(HWND hWnd)
{
// ?Direct X Version feststellen?
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
//Hardware
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
//Titel Font
D3DXCreateFont(d3ddev,
30, 0,
FW_BOLD,
0,
FALSE,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE,
TEXT("Old English Text MT"),
&m_titleFnt );
//Normal Font
D3DXCreateFont(d3ddev,
20, 0,
FW_BOLD,
0,
FALSE,
DEFAULT_CHARSET,
OUT_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE,
TEXT("Garamond"),
&m_normalFnt );
init_graphics();
init_light();
loadTexture();
d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE); // turn on the 3D lighting
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer
d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(5, 5, 5)); // ambient light
d3ddev->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); //Normals für Licht usw.
}
void render_frame(void)
{
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->BeginScene();
// Sicht auf die Scene einstellen
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (0.0f, 30.0f, 60.0f), // the camera position
&D3DXVECTOR3 (0.0f, 10.0f, 0.0f), // the look-at position
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); // the up direction
d3ddev->SetTransform(D3DTS_VIEW, &matView);
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(7),
(FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT,
1.0f, // the near view-plane
100.0f); // the far view-plane
d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);
//Objekte Zeichnen
//2D Text
DisplayTitel();
DisplayBeschreibung();
//Flexible Vertex Format
d3ddev->SetFVF(CUSTOMFVF);
//Sphere
// Um die Y - Achse drehen
static float index = 0.0f; index-=0.04f; // float value der sich stetig erhöht
D3DXMATRIX matTranslate2; // world transform matrix
D3DXMatrixRotationY( &matTranslate2, D3DXToRadian( index ) );
// world transform matrix
d3ddev->SetTransform(D3DTS_WORLD, &(matTranslate2));
//Textur der Sphere
d3ddev->SetTexture(0, g_pSphere);
//Sphere zeichnen
for(DWORD i = 0; i < numMaterials; i++)
{
d3ddev->SetMaterial(&material[i]);
meshXFile->DrawSubset(i);
}
//Tube
static float index2 = 0.0f; index2-=0.00325f; // float value der sich stetig erhöht
D3DXMATRIX matTranslate3; // world transform matrix
D3DXMatrixRotationY( &matTranslate3, D3DXToRadian( index2 ) );
// world transform matrix
d3ddev->SetTransform(D3DTS_WORLD, &(matTranslate3));
//Textur des Tube
d3ddev->SetTexture(0, g_pTube);
//Tube zeichnen
for(DWORD i = 0; i < numMaterials; i++)
{
d3ddev->SetMaterial(&material[i]);
meshXFile2->DrawSubset(i);
}
//Cube
//Den Cube um die Sphere rotieren lassen
D3DXMATRIX matTranslate; // world transform matrix
static float index3 = 0.0f; index3+=0.015f;
D3DXMatrixTranslation(&matTranslate,
(float)sin(index3) * 5.0f,
10.0f,
(float)cos(index3) * 5.0f);
d3ddev->SetTransform(D3DTS_WORLD, &(matTranslate)); // world transform matrix
// vertex and index buffers
d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
d3ddev->SetIndices(i_buffer);
//Textur des Cubes
d3ddev->SetTexture(0, g_pCube);
//Zeichne den Cube
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12);
d3ddev->EndScene();
d3ddev->Present(NULL, NULL, NULL, NULL);
}
void loadTexture( void )
{
D3DXCreateTextureFromFile( d3ddev,i_CUBE , &g_pCube);
D3DXCreateTextureFromFile( d3ddev, i_EARTH, &g_pSphere );
D3DXCreateTextureFromFile( d3ddev, i_TUBE, &g_pTube );
d3ddev->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
d3ddev->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
}
//Aufräumen
void cleanD3D(void)
{
v_buffer->Release();
i_buffer->Release();
d3ddev->Release();
d3d->Release();
}
void init_graphics(void)
{
//Cube
CUSTOMVERTEX vertices[] =
{
{ /*XYZ*/0.3f, 0.3f, 0.0f, /*Normal*/0.0f, 0.0f, 1.0f, /*Tex1*/0.0f,0.0f }, // Seite 1
{ /*XYZ*/0.0f, 0.3f, 0.0f, /*Normal*/0.0f, 0.0f, 1.0f, /*Tex1*/1.0f,0.0f },
{ /*XYZ*/0.3f, 0.0f, 0.0f, /*Normal*/0.0f, 0.0f, 1.0f, /*Tex1*/0.0f,1.0f },
{ /*XYZ*/0.0f, 0.0f, 0.0f, /*Normal*/0.0f, 0.0f, 1.0f, /*Tex1*/1.0f,1.0f },
{ /*XYZ*/0.3f, 0.3f, 0.3f, /*Normal*/0.0f, 0.0f, -1.0f,/*Tex1*/1.0f,0.0f }, // Seite 2
{ /*XYZ*/0.3f, 0.0f, 0.3f, /*Normal*/0.0f, 0.0f, -1.0f,/*Tex1*/1.0f,1.0f },
{ /*XYZ*/0.0f, 0.3f, 0.3f, /*Normal*/0.0f, 0.0f, -1.0f,/*Tex1*/0.0f,0.0f },
{ /*XYZ*/0.0f, 0.0f, 0.3f, /*Normal*/0.0f, 0.0f, -1.0f,/*Tex1*/0.0f,1.0f },
{ /*XYZ*/0.3f, 0.0f, 0.3f, /*Normal*/0.0f, 1.0f, 0.0f, /*Tex1*/0.0f,0.0f }, // Seite 3
{ /*XYZ*/0.3f, 0.0f, 0.0f, /*Normal*/0.0f, 1.0f, 0.0f, /*Tex1*/1.0f,0.0f },
{ /*XYZ*/0.0f, 0.0f, 0.3f, /*Normal*/0.0f, 1.0f, 0.0f, /*Tex1*/0.0f,1.0f },
{ /*XYZ*/0.0f, 0.0f, 0.0f, /*Normal*/0.0f, 1.0f, 0.0f, /*Tex1*/1.0f,1.0f },
{ /*XYZ*/0.3f, 0.3f, 0.3f, /*Normal*/0.0f, -1.0f, 0.0f,/*Tex1*/0.0f,0.0f }, // Seite 4
{ /*XYZ*/0.0f, 0.3f, 0.3f, /*Normal*/0.0f, -1.0f, 0.0f,/*Tex1*/1.0f,0.0f },
{ /*XYZ*/0.3f, 0.3f, 0.0f, /*Normal*/0.0f, -1.0f, 0.0f,/*Tex1*/0.0f,1.0f },
{ /*XYZ*/0.0f, 0.3f, 0.0f, /*Normal*/0.0f, -1.0f, 0.0f,/*Tex1*/1.0f,1.0f },
{ /*XYZ*/0.0f, 0.3f, 0.3f, /*Normal*/1.0f, 0.0f, 0.0f, /*Tex1*/0.0f,0.0f }, // Seite 5
{ /*XYZ*/0.0f, 0.0f, 0.3f, /*Normal*/1.0f, 0.0f, 0.0f, /*Tex1*/1.0f,0.0f },
{ /*XYZ*/0.0f, 0.3f, 0.0f, /*Normal*/1.0f, 0.0f, 0.0f, /*Tex1*/0.0f,1.0f },
{ /*XYZ*/0.0f, 0.0f, 0.0f, /*Normal*/1.0f, 0.0f, 0.0f, /*Tex1*/1.0f,1.0f },
{ /*XYZ*/0.3f, 0.3f, 0.3f, /*Normal*/-1.0f, 0.0f, 0.0f,/*Tex1*/1.0f,0.0f }, // Seite 6
{ /*XYZ*/0.3f, 0.3f, 0.0f, /*Normal*/-1.0f, 0.0f, 0.0f,/*Tex1*/1.0f,1.0f },
{ /*XYZ*/0.3f, 0.0f, 0.3f, /*Normal*/-1.0f, 0.0f, 0.0f,/*Tex1*/0.0f,0.0f },
{ /*XYZ*/0.3f, 0.0f, 0.0f, /*Normal*/-1.0f, 0.0f, 0.0f,/*Tex1*/0.0f,1.0f },
};
// create a vertex buffer interface called v_buffer
d3ddev->CreateVertexBuffer(24*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
VOID* pVoid; // void pointer
// lock v_buffer und lade die vertices
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
short indices[] =
{
0, 1, 2, // Seite 1
2, 1, 3,
4, 5, 6, // Seite 2
6, 5, 7,
8, 9, 10, // Seite 3
10, 9, 11,
12, 13, 14, // Seite 4
14, 13, 15,
16, 17, 18, // Seite 5
18, 17, 19,
20, 21, 22, // Seite 6
22, 21, 23,
};
d3ddev->CreateIndexBuffer(36*sizeof(short),
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&i_buffer,
NULL);
// lock i_buffer und lade die vertices
i_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, indices, sizeof(indices));
i_buffer->Unlock();
//Planet von .X File
LPD3DXBUFFER bufXFileMaterial;
D3DXLoadMeshFromX(x_EARTH, // .X file
D3DXMESH_SYSTEMMEM, // mesh in den system speicher laden
d3ddev, // Direct3D Device
NULL,
&bufXFileMaterial, // materials
NULL, // keine effect instances
&numMaterials, // die anzahl an materials in dem model
&meshXFile); // das mesh
D3DXMATERIAL* tempMaterials = (D3DXMATERIAL*)bufXFileMaterial->GetBufferPointer();
// neuer material buffer für jedes material im mesh
material = new D3DMATERIAL9[numMaterials];
for(DWORD i = 0; i < numMaterials; i++)
{
material[i] = tempMaterials[i].MatD3D; // material info
material[i].Ambient = material[i].Diffuse;
}
ScaleMesh(meshXFile,0.15f,0);
//Tube
D3DXLoadMeshFromX(x_TUBE, // .X file
D3DXMESH_SYSTEMMEM, // mesh in den system speicher laden
d3ddev, // Direct3D Device
NULL,
&bufXFileMaterial, // materials
NULL, // keine effect instances
&numMaterials, // die anzahl an materials in dem model
&meshXFile2); // das mesh
D3DXMATERIAL* tempMaterials2 = (D3DXMATERIAL*)bufXFileMaterial->GetBufferPointer();
// neuer material buffer für jedes material im mesh
material = new D3DMATERIAL9[numMaterials];
for(DWORD i = 0; i < numMaterials; i++)
{
material[i] = tempMaterials[i].MatD3D; // material info
material[i].Ambient = material[i].Diffuse;
}
}
//Beleuchtung
void init_light(void)
{
D3DLIGHT9 light;
D3DMATERIAL9 material;
ZeroMemory(&light, sizeof(light));
light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);
light.Position = D3DXVECTOR3(10.0f, 5.0f, 3.0f);
light.Direction = D3DXVECTOR3(-1.0f, 0.0f, -1.3f);
light.Range = 80.0f;
light.Attenuation0 = 0.0f;
light.Attenuation1 = 0.125f;
light.Attenuation2 = 0.0f;
light.Phi = D3DXToRadian(100.0f); //äußerer Radius
light.Theta = D3DXToRadian(80.0f); //innerer Radius
light.Falloff = 1.0f;
d3ddev->SetLight(0, &light);
d3ddev->LightEnable(0, TRUE);
ZeroMemory(&material, sizeof(D3DMATERIAL9));
material.Diffuse = D3DXCOLOR(0.8f, 0.8f, 0.8f, 0.8f);
material.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
d3ddev->SetMaterial(&material);
}
//Größe des Mesh anpassen
HRESULT ScaleMesh(ID3DXMesh *pMesh, float scale, D3DXVECTOR3 *offset=NULL)
{
BYTE *ptr=NULL;
HRESULT hr;
D3DXVECTOR3 vOff;
// fehler melden wenn kein mesh pointer
if (!pMesh)
return D3DERR_INVALIDCALL;
// wähle default oder eigene Position
if (offset)
vOff=*offset;
else
vOff=D3DXVECTOR3(0.0f,65.0f,0.0f);
DWORD numVerts=pMesh->GetNumVertices();
// FVF flags
DWORD fvf=pMesh->GetFVF();
// vertex size berechnen
DWORD vertSize=D3DXGetFVFVertexSize(fvf);
// lock vertex buffer
if (FAILED( hr=pMesh->LockVertexBuffer(0,(void**)&ptr)))
// return on failure
return hr;
for (DWORD i=0;i<numVerts;i++) {
// pointer to location
D3DXVECTOR3 *vPtr=(D3DXVECTOR3 *) ptr;
// scale
*vPtr+=vOff;
vPtr->x*=scale;
vPtr->y*=scale;
vPtr->z*=scale;
// increment pointer to next vertex
ptr+=vertSize;
}
// unlock vertex buffer
if (FAILED(hr=pMesh->UnlockVertexBuffer()))
// return on failure
return hr;
// return success to caller
return S_OK;
}
Vielen Dank für eure Hilfe im vorraus.
littles