//These are the necessary includes
#define WIN32_LEAN_AND_MEAN //Excludes rarely used stuff
#include <windows.h>
#include <d3dx8.h>
#pragma comment( lib, "d3d8.lib" )//Includes libraries
#pragma comment( lib, "d3dx8.lib" )
//All the function prototypes
void FatalError( const char* p_error_msg );
void FatalError( HRESULT p_hr, const char* p_error_msg );
LRESULT CALLBACK default_window_proc(HWND p_hwnd,UINT p_msg,WPARAM p_wparam,LPARAM p_lparam);
void init_window();
void kill_window();
void init_d3d();
void kill_d3d();
void init_scene();
void kill_scene();
void message_pump();
D3DFORMAT find_16bit_mode();
void render();
void NOP(HINSTANCE p_prev_instance,LPSTR p_cmd_line,int p_show);
//Name of the application
const char g_app_name[] = "Framework for Tutorials";
//Screen window sizes
const int g_width = 640;
const int g_height = 480;
//Global handle to main window
HWND g_main_window = NULL;
//Global handle to our instance
HINSTANCE g_instance;
//Global flag to check if app should end
bool g_app_done = false;
//Main DIRECT3D8 object
IDirect3D8* g_D3D=NULL;
//DIRECT3DDEVICE object
IDirect3DDevice8* g_d3d_device = NULL;
struct my_vertex
{
FLOAT x, y, z;
FLOAT rhw;
FLOAT u, v;
};
#define VERTEXFVF ( D3DFVF_XYZRHW | D3DFVF_TEX1 )
my_vertex g_Square[ 4 ] =
{
{ 150.0f, 150.0f, 0.0f, 1.0f, 0.0f, 0.0f },
{ 150.0f, 300.0f, 0.0f, 1.0f, 0.0f, 1.0f },
{ 300.0f, 150.0f, 0.0f, 1.0f, 1.0f, 0.0f },
{ 300.0f, 300.0f, 0.0f, 1.0f, 1.0f, 1.0f }
};
//Make a vertex buffer
IDirect3DVertexBuffer8* g_VB = NULL;
//Make a texture pointer
IDirect3DTexture8* g_Texture = NULL;
//WinMain function
int APIENTRY WinMain(HINSTANCE p_instance,HINSTANCE p_prev_instance,LPSTR p_cmd_line,int p_show)
{
//Save the instance in the function
g_instance = p_instance;
//Quiet compiler warnings
NOP(p_prev_instance,p_cmd_line,p_show);
//Build window
init_window();
//Build 3D objects
init_d3d();
//Preparation to build objects and other stuff
init_scene();
//Loop until the user aborts
while( !g_app_done )
{
message_pump(); //Check for window messages
render(); // Render stuff
}
//Free all objects and resources
kill_scene();
//Clean up all 3D objects
kill_d3d();
//Close down window
kill_window();
//Exit
return 0;
}
//FUNCTION DEFINITIONS
void NOP(HINSTANCE p_prev_instance,LPSTR p_cmd_line,int p_show)
{
p_prev_instance=p_prev_instance;
p_cmd_line=p_cmd_line;
p_show=p_show;
}
void message_pump()
{
MSG msg;
if(PeekMessage(&msg, NULL, 0, 0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
//Registers a window class and then creates the window
void init_window()
{
ULONG window_width, window_height;
WNDCLASS window_class;
DWORD style;
//Fill in all the fields for the WNDCLASS structure. Window classes
//are a sort of template for window creation. You could create many
//windows using the same window class.
window_class.style = CS_OWNDC;
window_class.cbClsExtra = 0;
window_class.cbWndExtra = 0;
window_class.hInstance = g_instance;
window_class.hIcon = LoadIcon(NULL,IDI_APPLICATION);
window_class.hCursor = LoadCursor(NULL,IDC_ARROW);
window_class.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
window_class.lpszMenuName = NULL;
window_class.lpszClassName = "DH Class";
//Here we provide our default window handler, all windows messages
//will be sent to this function.
window_class.lpfnWndProc = default_window_proc;
//Register the class with windows
if(!RegisterClass(&window_class)){
FatalError("Error registering window class");
}
//When running full screen, we cover the desktop with our window.
//This isn''t necessary, but it provides a smoother transition for the
//user, especially when we''re going to change screen modes.
window_width=GetSystemMetrics(SM_CXSCREEN);
window_height=GetSystemMetrics(SM_CYSCREEN);
style=WS_POPUP;
//Here we actually create the window. For more detail on the various
//parameters please refer to the Win32 documentation.
g_main_window=CreateWindow("DH Class", //name of our registered class
g_app_name, //Window name/title
style, //Style flags
0, //X position
0, //Y position
window_width,//width of window
window_height,//height of window
NULL, //Parent window
NULL, //Menu
g_instance, //application instance handle
NULL); //pointer to window-creation data
if(!g_main_window){
FatalError("Error opening window");
}
//The next 3 lines just make sure that our window is visible and has the
//input focus. It''s not strictly necessary, but it doesn''t hurt to be
//thorough.
ShowWindow(g_main_window,SW_SHOW);
UpdateWindow(g_main_window);
SetFocus(g_main_window);
}
//Unregister and destroy window
void kill_window(){
//Test if our window is valid
if(g_main_window){
if(!DestroyWindow(g_main_window)){
//We failed to destroy our window, this shouldn''t ever happen
MessageBox(NULL,"Destroy Window Failed",g_app_name,MB_OK|MB_ICONERROR|MB_TOPMOST);
}else{
MSG msg;
//Clean up any pending messages
while(PeekMessage(&msg, NULL, 0, 0,PM_REMOVE)){
DispatchMessage(&msg);
}
}
//Set our window handle to NULL just to be safe
g_main_window=NULL;
}
//Unregister our window, if we had opened multiple windows using this
//class, we would have to close all of them before we unregistered the class.
if(!UnregisterClass("DH Class",g_instance)){
MessageBox(NULL,"Unregister Failed",g_app_name,MB_OK|MB_ICONERROR|MB_TOPMOST);
}
}
//Set up Direct3D and create the device
void init_d3d()
{
HRESULT hr;
D3DPRESENT_PARAMETERS d3dpp;
//Create Direct3D8, this is the first thing you have to do in any D3D8 program
//Always pass D3D_SDK_VERSION to the function.
g_D3D = Direct3DCreate8( D3D_SDK_VERSION );
if(!g_D3D ){
FatalError("Direct3DCreate8():Error creating Direct3D.");
}
//Clear out our D3DPRESENT_PARAMETERS structure. Even though we''re going
//to set virtually all of its members, it''s good practice to zero it out first.
ZeroMemory(&d3dpp,sizeof(d3dpp));
//Whether we''re full-screen or windowed these are the same.
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // Throw away previous frames, we don''t need them
d3dpp.hDeviceWindow = g_main_window; //This is our main (and only) window
d3dpp.BackBufferCount= 1; //We only need a single back buffer
//BackBufferWidth/Height have to be set for full-screen apps, these values are
//used (along with BackBufferFormat) to determine the display mode.
//They aren''t needed in windowed mode since the size of the window will be used.
//BackBufferFormat is the pixel format we want.
d3dpp.Windowed = FALSE;
d3dpp.BackBufferWidth = g_width;
d3dpp.BackBufferHeight = g_height;
//In full-screen we need to find a pixel format we like, see find_16bit_mode()
//below for more details.
d3dpp.BackBufferFormat = find_16bit_mode();
//After filling in our D3DPRESENT_PARAMETERS structure, we''re ready to create our device.
//Most of the options in how the device is created are set in the D3DPRESENT_PARAMETERS
//structure.
hr=g_D3D->CreateDevice(D3DADAPTER_DEFAULT, //The default adapter, on a multimonitor system
//there can be more than one.
//Use hardware acceleration rather than the software renderer
D3DDEVTYPE_HAL,
//Our Window
g_main_window,
//Process vertices in software. This is slower than in hardware,
//But will work on all graphics cards.
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
//Our D3DPRESENT_PARAMETERS structure, so it knows what we want to build
&d3dpp,
//This will be set to point to the new device
&g_d3d_device);
if(FAILED(hr)){
FatalError(hr,"CreateDevice():Error creating device");
}
}
//Kill D3D
void kill_d3d(){
if(g_d3d_device){
g_d3d_device->Release();
g_d3d_device=NULL;
}
if(g_D3D){
g_D3D->Release();
g_D3D=NULL;
}
}
//Initialize scene
void init_scene()
{
HRESULT hr;
BYTE* Ptr;
hr = g_d3d_device-> CreateVertexBuffer ( 4 * sizeof( my_vertex ),
D3DUSAGE_WRITEONLY,
VERTEXFVF,
D3DPOOL_MANAGED,
&g_VB );
D3DXCreateTextureFromFile( g_d3d_device, "Texture.bmp", &g_Texture );
hr = g_VB->Lock( 0, 0, &Ptr, 0 );
memcpy( Ptr, g_Square, sizeof( g_Square ) );
}
//Kill scene
void kill_scene()
{
if ( g_VB )
{
g_VB -> Release();
g_VB = NULL;
}
if ( g_Texture )
{
g_Texture-> Release();
g_Texture = NULL;
}
}
//Find 16bit mode
D3DFORMAT find_16bit_mode()
{
HRESULT hr;
//CheckDeviceType() is used to verify that a Device can support a particular display mode.
//First we test for R5G6B5. All 16-bits are used in this format giving us a full 64K worth
//worth of colours
hr=g_D3D->CheckDeviceType(D3DADAPTER_DEFAULT, //Test the primary display device, this is
//necessary because systems can have add-on cards
//or multi-monitor setups
D3DDEVTYPE_HAL, //This states that we want support for this mode
//in hardware rather than emulated in software
D3DFMT_R5G6B5, //The is the primary (viewable) buffer format
D3DFMT_R5G6B5, //This is the back (drawable) buffer format
FALSE); //Is this windowed mode? Nope
if(SUCCEEDED(hr)){
return D3DFMT_R5G6B5;
}
//Next try X1R5G5B5. Since 1 bit is wasted it''s technically a 15-bit mode and only
//provides 32K colours, though you''d be hard pressed to tell the difference between
//15- & 16-bit modes.
hr=g_D3D->CheckDeviceType(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,D3DFMT_X1R5G5B5,D3DFMT_X1R5G5B5,FALSE);
if(SUCCEEDED(hr)){
return D3DFMT_X1R5G5B5;
}
//This is a freaky card. Complain and bail out.
FatalError(hr,"find_16bit_mode():Couldn''t find a decent 16-bit mode");
//Won''t actually hit this line since FatalError() kills us, but it makes the compiler happy.
return (D3DFORMAT)NULL;
}
//Render the scene
void render()
{
g_d3d_device->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
if(SUCCEEDED(g_d3d_device->BeginScene()))
{
g_d3d_device-> SetVertexShader( VERTEXFVF );
g_d3d_device-> SetStreamSource( 0, g_VB, sizeof( my_vertex ) );
g_d3d_device-> SetTexture( 0, g_Texture );
g_d3d_device-> DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
g_d3d_device-> SetTexture( 0, NULL );
g_d3d_device-> EndScene();
g_d3d_device-> Present( NULL, NULL, NULL, NULL );
}
}
//FatalError Closes down all the stuff and notifies user
void FatalError(const char *p_error_msg)
{
kill_scene();
kill_d3d();
kill_window();
//Write our error message out to the debugger (if it''s active)
OutputDebugString( p_error_msg );
OutputDebugString("\n");
MessageBox(NULL, p_error_msg,g_app_name, MB_OK );
exit(5);
}
//Another FatalError
void FatalError(HRESULT p_hr,const char *p_error_msg)
{
char buffer[255];
D3DXGetErrorStringA(p_hr,buffer,250);
strcat(buffer,"\n");
strcat(buffer,p_error_msg);
kill_scene();
kill_d3d();
kill_window();
//Write our error message out to the debugger (if it''s active)
OutputDebugString( buffer );
OutputDebugString("\n");
MessageBox(NULL, buffer,g_app_name, MB_OK );
exit(5);
}
//Windows message handler
LRESULT CALLBACK default_window_proc(HWND p_hwnd,UINT p_msg,WPARAM p_wparam,LPARAM p_lparam)
{
switch(p_msg)
{
case WM_KEYDOWN: // A key has been pressed, end the app
case WM_CLOSE: //User hit the Close Window button, end the app
case WM_LBUTTONDOWN: //user hit the left mouse button
g_app_done=true;
return 0;
case WM_DESTROY: //This window is being destroyed, tell Windows we''re quitting
PostQuitMessage(0);
return 0;
}
return (DefWindowProc(p_hwnd,p_msg,p_wparam,p_lparam));
}
Need help with code
Hi everyone,
Expect posts from me on this forum now :D I''m using Jim Adam''s book and Drunken Hyena''s tutorials. After 4.5 months of C++, it''s a welcoming change :D Anyway, I''m basically playing around at the moment, mixing some of his code with Drunken Hyena''s, and this program isn''t working correctly. I can''t find the problem either. This is supposed to open at fullscreen, display a square, with a texture on it. The screen is constantly flashing a purple like color on opening. The texture is in the correct directory, but I doubt that''s having an impact at the moment. Here''s my code:
Thanks
-Peter
Your code works on mine, but there are a couple of things you need to do.
1. You need to unlock your vertex buffer after you''ve finished writing to it. E.G.
hr = g_VB->Lock( 0, 0, &Ptr, 0 );
memcpy( Ptr, g_Square, sizeof( g_Square ) );
g_VB->Unlock();
2. To make sure your square is visible, you should set the following render states:
g_d3d_device-> SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
g_d3d_device-> SetRenderState( D3DRS_LIGHTING, FALSE );
---------------------------------------
Let''s struggle for our dream of Game!
http://andrewporritt.4t.com
1. You need to unlock your vertex buffer after you''ve finished writing to it. E.G.
hr = g_VB->Lock( 0, 0, &Ptr, 0 );
memcpy( Ptr, g_Square, sizeof( g_Square ) );
g_VB->Unlock();
2. To make sure your square is visible, you should set the following render states:
g_d3d_device-> SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );
g_d3d_device-> SetRenderState( D3DRS_LIGHTING, FALSE );
---------------------------------------
Let''s struggle for our dream of Game!
http://andrewporritt.4t.com
The way his vertices are setup, I would turn culling off, since the first triangle is clockwise, and the second is counter-clockwise.
The culling line had to be in there, because my screen was just completely black without it. Thanks for the help!
-Peter
-Peter
Because he''s using tri-strips, D3D automatically alternates between counter- and clockwise culling
---------------------------------------
Let''s struggle for our dream of Game!
http://andrewporritt.4t.com
---------------------------------------
Let''s struggle for our dream of Game!
http://andrewporritt.4t.com
Welcome, Polish_Peta.
Hope you enjoy your time here
Just a couple of non-D3D guidlines:
- Make sure you read the FAQs. The general Forums FAQ, and the DirectX FAQ.
- Please use descriptive topic titles, so that you can get faster help.
- Generally, you should avoid posting much code - it scares people away
Seriously, a lot of people that want to help don''t have the time to read the whole code, or compile it and try it. So try to narrow down the problem and post the relevant code only.
Regarding D3D:
- I really recommend downloading and installing the DirectX debug runtime, then enabling the debug D3D version (via Control Panel->DirectX) whenever you do D3D development.
The help it provides is invaluable. Whenever something fails, it''ll tell you about it, in a - usually - very clear manner. Posting debug output along with code will also increase the chance of your post being replied to.
If you don''t have Visual Studio (and thus unable to view the debug output from your IDE) you can use debug viewers like dbmon.exe (or any other equivalents). You might also want to try D3DSpy (a tool that comes with the SDK), which tracks D3D calls, errors, and such stuff.
- I recommend following a tutorial series, instead of relying on the Docs. At least for the first few programs you write. I recommend DrunkenHyena''s tutorials. You may also want to look for Andy Pike''s tutorials (I think his website is down...There''s an alternate address though. A google search should find it)
That''s all for now. Good luck in your future endeavors, you''re going to need it
Muhammad Haggag
Hope you enjoy your time here
Just a couple of non-D3D guidlines:
- Make sure you read the FAQs. The general Forums FAQ, and the DirectX FAQ.
- Please use descriptive topic titles, so that you can get faster help.
- Generally, you should avoid posting much code - it scares people away
Seriously, a lot of people that want to help don''t have the time to read the whole code, or compile it and try it. So try to narrow down the problem and post the relevant code only.
Regarding D3D:
- I really recommend downloading and installing the DirectX debug runtime, then enabling the debug D3D version (via Control Panel->DirectX) whenever you do D3D development.
The help it provides is invaluable. Whenever something fails, it''ll tell you about it, in a - usually - very clear manner. Posting debug output along with code will also increase the chance of your post being replied to.
If you don''t have Visual Studio (and thus unable to view the debug output from your IDE) you can use debug viewers like dbmon.exe (or any other equivalents). You might also want to try D3DSpy (a tool that comes with the SDK), which tracks D3D calls, errors, and such stuff.
- I recommend following a tutorial series, instead of relying on the Docs. At least for the first few programs you write. I recommend DrunkenHyena''s tutorials. You may also want to look for Andy Pike''s tutorials (I think his website is down...There''s an alternate address though. A google search should find it)
That''s all for now. Good luck in your future endeavors, you''re going to need it
Muhammad Haggag
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement