Jump to content
  • Advertisement
Sign in to follow this  
sauronette

Rendering a cute 2D scrolling map inside a window

This topic is 4463 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi Everyone, I am a relative noobie to game programming (especially Direct X) and I wanted to ask a couple of specific questions that I am sure some genius here readily knows. I have read alot of the tutorials on creating a 2D tiling engine (non isometric) just 32 x 32px tiling, but I can't figure out a couple of details with the implementation. I want to basically do something very simple at first to learn: Example... 1. Create an array [x][y] and fill it with stuff to represent bitmaps "1111111111111111" "1 2 1" "1 222 1" "11 222 11111111 "11 111111111111" "1111111111111111" 2. Set up a loop to read in all the elements to the array so we can look at individual array elements to see what's in there. 3. Set up Direct X and get ready to Render 4. Here's where I fall down the stairs. I do not understand how you get the cute graphic tiles INSIDE c++ or how you translate the ASCII array into graphics? In the end, I know that you render the scene by writing to the Direct X back buffer and the Blit it, but getting to that point makes me scratch my head. 5. The tutorial "Tile Engine Gold" is a perfect example of what I want to do, but the graphics files and map are in something called ".dat" files, and a ".map" file. So I can't see inside those to really really look at the code and how it's done. Does anyone have a full example of a little piece of code that lets you scroll around a 2d Tiled map in a window? Thanks!

Share this post


Link to post
Share on other sites
Advertisement
Oh, boy.


Well, you seem to at least have something of a clue as far as what you'd like to do, and I'm quite happy you didn't make a "I'd like to make a MMORPG just like Everquest but different!" post as your first post.

RE: #4:

Typically, you'd load a bitmap or bitmaps for your tiles.

You might have multiple tiles on a bitmap, but for now, I'll suggest having one bitmap==one tile.

In DirectX, you would put these bitmaps onto surfaces/textures(depending on your rendering method).

Your tiles can be stored in an array, and the values in your map array would be indices into the array of tiles. Although, since you are using the character ' '(space) for empty, and '1' and '2' for tiles, you may need a translation layer in between to convert the value into an index into your tile array.

As far as scrolling is concerned, the only thing that change is where tile (0,0) is drawn, and rerender.


Share this post


Link to post
Share on other sites
Hehe, no, I have been working non-stop for about 3 months doing this. It is way too complex to think about mastering something like that just starting out. I can't even get a bitmap on the screen yet.

But I do wish to get the bare bones help in getting to the point where I have a window that has a map inside it and I can design a big map and move a character around it (2D) I want an excuse to create cute potions and treasure in photoshop and scroll around with it (This means layers... i know i know.. later) I will settle for a floor tile and a wall for now. Maybe just a floor :)


I would actually use something like this..

"11111111111111"
"1.....3333...1"
"1.....3333...1"
"1..11111111111"


So, correct me if I am wrong, but here are the steps...

1. Define the Char for the array and read in the data to the array
map [x][y]

2. Load a bitmap image (I am assuming just using C stuff, like fopen?
and associate this bitmap with a variable? (This code is where I
need help)

3. Write some code that says... if 1, then use grass bitmap, if 3 use
wall bitmap, and so on... (need help here too)

4. Then write some code that makes Direct X write this array stuffed
full o' bitmaps to the surface. (need help here too)

[Edited by - sauronette on March 15, 2006 6:57:10 PM]

Share this post


Link to post
Share on other sites
Okay, let's take a step back and assess:

Thus far, you have established a platform of Windows(implicit with DirectX), and C++ as your language.

Next question: Direct3D or DirectDraw for rendering?

Also, if this is in a window, is DirectX even necessary at all, or would GDI suffice? If DirectDraw was the plan, then SDL becomes an option.

Share this post


Link to post
Share on other sites
Yes, I am using C++, and Windows, and DirectX 9.0
That entails using Direct3D for rendering. Don't wanna use GDI or DirectDraw.
Here is my code thus far. I have my window nice and spiffy, and have extracted the rendering part into a function called RenderFrame() where I begin the scene, clear the buffer, and then go! go! go!

The biggest issue for me is where do I put the map array, and how does it fit into the game loop? I suppose I put the definition in WinMain.h, and also load the bitmap there also after parsing the array structure, and then do a for loop in the RenderFrame() function to output to the surface?

Here's my code so far...

WINMAIN.cpp

#include "stdafx.h"
#include "WinMain.h"

#define WINDOW_TITLE "Sauronette's spiffy 2D tile map"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define WINDOWED TRUE

LPDIRECT3D9 g_pD3D9 = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
D3DDISPLAYMODE g_displayMode;
D3DPRESENT_PARAMETERS g_D3Dpp;
HWND g_hWnd;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
{
// Define the window
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_CUNIT ) );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = WINDOW_TITLE;
wcex.hIconSm = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_CUNIT ) );

// Register the window
RegisterClassEx( &wcex );

// Create the window
g_hWnd = CreateWindow( WINDOW_TITLE, WINDOW_TITLE, (WINDOWED) ? WS_OVERLAPPEDWINDOW : WS_EX_TOPMOST, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, hInstance, 0 );

// Adjust to actual desired size
RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
AdjustWindowRect( &rect, GetWindowLong( g_hWnd, GWL_style ), FALSE );
SetWindowPos( g_hWnd, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE );

ShowWindow( g_hWnd, SW_SHOW );
UpdateWindow( g_hWnd );

// Create Direct3D Object
g_pD3D9 = Direct3DCreate9( D3D_SDK_VERSION );
if ( !g_pD3D9 )
{
MessageBox( 0, "Direct3DCreate9() - Failed", 0, 0 );
return 0;
}

// Get display mode
g_pD3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &g_displayMode );

// Check for hardware T&L
D3DCAPS9 D3DCaps;
g_pD3D9->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3DCaps );
DWORD vertexProcessing = 0;
if ( D3DCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
{
vertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
// Check for pure device
if ( D3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE )
{
vertexProcessing |= D3DCREATE_PUREDEVICE;
}
}
else
{
vertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}

// Fill out the presentation parameters
if ( !BuildPresentationParameters() )
{
MessageBox( 0, "Unable to find a valid DepthStencil Format", 0, 0 );
SAFE_RELEASE( g_pD3D9 );
return 0;
}

// Create the device
if ( FAILED( g_pD3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, vertexProcessing, &g_D3Dpp, &g_pD3DDevice ) ) )
{
SAFE_RELEASE( g_pD3D9 );
MessageBox( 0, "CreateDevice() - Failed", 0, 0 );
return 0;
}

// Main loop
MSG msg;
while ( 1 )
{
// Did we recieve a message?
if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if ( msg.message == WM_QUIT)
{
break;
}
TranslateMessage( &msg );
DispatchMessage ( &msg );
}
else
{
RenderFrame();
}
}

// Give back resources
SAFE_RELEASE( g_pD3DDevice );
SAFE_RELEASE( g_pD3D9 );

return 0;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
BuildPresentationParameters
Purpose:
Builds the D3DPRESENT_PARAMETERS structure using the current window size.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

BOOL BuildPresentationParameters()
{
ZeroMemory( &g_D3Dpp, sizeof(g_D3Dpp) );
D3DFORMAT adapterFormat = (WINDOWED) ? g_displayMode.Format : D3DFMT_X8R8G8B8;
if ( SUCCEEDED( g_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) )
{
g_D3Dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
}
else if ( SUCCEEDED( g_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) )
{
g_D3Dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
}
else if ( SUCCEEDED( g_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
{
g_D3Dpp.AutoDepthStencilFormat = D3DFMT_D16;
}
else
{
return false;
}

g_D3Dpp.BackBufferWidth = (WINDOWED) ? 0 : g_displayMode.Width;
g_D3Dpp.BackBufferHeight = (WINDOWED) ? 0 : g_displayMode.Height;
g_D3Dpp.BackBufferFormat = adapterFormat;
g_D3Dpp.BackBufferCount = 1;
g_D3Dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
g_D3Dpp.MultiSampleQuality = 0;
g_D3Dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_D3Dpp.hDeviceWindow = g_hWnd;
g_D3Dpp.Windowed = WINDOWED;
g_D3Dpp.EnableAutoDepthStencil = TRUE;
g_D3Dpp.FullScreen_RefreshRateInHz = (WINDOWED) ? 0 : g_displayMode.RefreshRate;
g_D3Dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

return TRUE;
}


// Function to Render the Current Frame
void RenderFrame()
{
g_pD3DDevice->Clear( 0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 100 ), 1.0f, 0 );
g_pD3DDevice->BeginScene();

// Render the frame

g_pD3DDevice->EndScene();
g_pD3DDevice->Present( 0, 0, 0, 0 );
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Application event handler.
Parameters:
[in] hWnd - Unique handle to the window.
[in] message - Incoming message.
[in] wParam - Parameter of the message (unsigned int).
[in] lParam - Parameter of the message (long).
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
case WM_PAINT:
if ( g_pD3DDevice )
{
RenderFrame();
}
ValidateRect( hWnd, 0 );
return 0;
case WM_KEYDOWN:
switch ( wParam )
{
case VK_ESCAPE:
PostQuitMessage( 0 );
break;
}
return 0;
}
return DefWindowProc( hWnd, message, wParam, lParam );
}

Share this post


Link to post
Share on other sites
Suggested locations for things:
(look for /*TODO: blah blah*/)

#include "stdafx.h"
#include "WinMain.h"
/*TODO: additional includes*/

#define WINDOW_TITLE "Sauronette's spiffy 2D tile map"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define WINDOWED TRUE

LPDIRECT3D9 g_pD3D9 = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
D3DDISPLAYMODE g_displayMode;
D3DPRESENT_PARAMETERS g_D3Dpp;
HWND g_hWnd;
/*TODO: additional variables*/

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
{
// Define the window
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_CUNIT ) );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = WINDOW_TITLE;
wcex.hIconSm = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_CUNIT ) );

// Register the window
RegisterClassEx( &wcex );

// Create the window
g_hWnd = CreateWindow( WINDOW_TITLE, WINDOW_TITLE, (WINDOWED) ? WS_OVERLAPPEDWINDOW : WS_EX_TOPMOST, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, hInstance, 0 );

// Adjust to actual desired size
RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
AdjustWindowRect( &rect, GetWindowLong( g_hWnd, GWL_style ), FALSE );
SetWindowPos( g_hWnd, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE );

ShowWindow( g_hWnd, SW_SHOW );
UpdateWindow( g_hWnd );

// Create Direct3D Object
g_pD3D9 = Direct3DCreate9( D3D_SDK_VERSION );
if ( !g_pD3D9 )
{
MessageBox( 0, "Direct3DCreate9() - Failed", 0, 0 );
return 0;
}

// Get display mode
g_pD3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &g_displayMode );

// Check for hardware T&L
D3DCAPS9 D3DCaps;
g_pD3D9->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3DCaps );
DWORD vertexProcessing = 0;
if ( D3DCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
{
vertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
// Check for pure device
if ( D3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE )
{
vertexProcessing |= D3DCREATE_PUREDEVICE;
}
}
else
{
vertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}

// Fill out the presentation parameters
if ( !BuildPresentationParameters() )
{
MessageBox( 0, "Unable to find a valid DepthStencil Format", 0, 0 );
SAFE_RELEASE( g_pD3D9 );
return 0;
}

// Create the device
if ( FAILED( g_pD3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, vertexProcessing, &g_D3Dpp, &g_pD3DDevice ) ) )
{
SAFE_RELEASE( g_pD3D9 );
MessageBox( 0, "CreateDevice() - Failed", 0, 0 );
return 0;
}

/*TODO: additional setup*/

// Main loop
MSG msg;
while ( 1 )
{
// Did we recieve a message?
if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if ( msg.message == WM_QUIT)
{
break;
}
TranslateMessage( &msg );
DispatchMessage ( &msg );
}
else
{
RenderFrame();
}
}

// Give back resources
SAFE_RELEASE( g_pD3DDevice );
SAFE_RELEASE( g_pD3D9 );

/*TODO: additional cleanup*/

return 0;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
BuildPresentationParameters
Purpose:
Builds the D3DPRESENT_PARAMETERS structure using the current window size.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

BOOL BuildPresentationParameters()
{
ZeroMemory( &g_D3Dpp, sizeof(g_D3Dpp) );
D3DFORMAT adapterFormat = (WINDOWED) ? g_displayMode.Format : D3DFMT_X8R8G8B8;
if ( SUCCEEDED( g_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) )
{
g_D3Dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
}
else if ( SUCCEEDED( g_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) )
{
g_D3Dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
}
else if ( SUCCEEDED( g_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
{
g_D3Dpp.AutoDepthStencilFormat = D3DFMT_D16;
}
else
{
return false;
}

g_D3Dpp.BackBufferWidth = (WINDOWED) ? 0 : g_displayMode.Width;
g_D3Dpp.BackBufferHeight = (WINDOWED) ? 0 : g_displayMode.Height;
g_D3Dpp.BackBufferFormat = adapterFormat;
g_D3Dpp.BackBufferCount = 1;
g_D3Dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
g_D3Dpp.MultiSampleQuality = 0;
g_D3Dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_D3Dpp.hDeviceWindow = g_hWnd;
g_D3Dpp.Windowed = WINDOWED;
g_D3Dpp.EnableAutoDepthStencil = TRUE;
g_D3Dpp.FullScreen_RefreshRateInHz = (WINDOWED) ? 0 : g_displayMode.RefreshRate;
g_D3Dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

return TRUE;
}


// Function to Render the Current Frame
void RenderFrame()
{
g_pD3DDevice->Clear( 0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 100 ), 1.0f, 0 );
g_pD3DDevice->BeginScene();

// Render the frame

g_pD3DDevice->EndScene();
g_pD3DDevice->Present( 0, 0, 0, 0 );
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Application event handler.
Parameters:
[in] hWnd - Unique handle to the window.
[in] message - Incoming message.
[in] wParam - Parameter of the message (unsigned int).
[in] lParam - Parameter of the message (long).
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
case WM_PAINT:
if ( g_pD3DDevice )
{
RenderFrame();
}
ValidateRect( hWnd, 0 );
return 0;
case WM_KEYDOWN:
switch ( wParam )
{
case VK_ESCAPE:
PostQuitMessage( 0 );
break;
}
return 0;
}
return DefWindowProc( hWnd, message, wParam, lParam );
}




Overview of what you need to do:

You are going to need a bitmap or bitmaps.

You are going to need to load this into an IDirect3DTexture9. I suggest doing this through the function D3DXCreateTextureFromFile or D3DXCreateTextureFromFileEx. The header for these functions are "D3dx9tex.h", so you'll need to add that to your list of includes.

You will need to set up a vertex type. You'll need to configure the device for that vertex type and set some rendering states and perhaps some texture stage states. You'll need to turn off lighting(I think).

When drawing, you'll need to set up vertices, and draw them.

Yes, it is a lot to do.

Things to add in specific TODO areas:

/*TODO: additional includes*/
An include for D3dx9tex.h

/*TODO: additional variables*/
A custom vertex structure
your map array declaration

/*TODO: additional setup*/
Setting up your map array
Setting up your D3Ddevice's FVF, turning off lighting, and any rendering values for the device
Loading the texture or textures(D3DXCreateTextureFromFile or D3DXCreateTextureFromFileEx)

/*TODO: additional cleanup*/
Releasing texture(s), similar to what you are already doing with other Direct3D object.

// Render the frame
selecting the texture(s) you want to draw(SetTexture)
setting up the vertices
drawing the polygons(DrawPrimitiveUP)

Share this post


Link to post
Share on other sites
Thanks so much for taking the time to look at my code and give me some excellent hints on how to proceed. Being the curious girl that I am it's important for me to understand how and why I am using this. Basically what I am doing is making Direct3D render two triangles that end up being a block/square? and then laying a texture on top of this block.

So logically we have this->

MapArray[x][y] This holds the number of tiles in the map, x,y pointing to
a certain tile at the intersection of this vertex.

But, on some other logical layer, i.e. the vertex buffer, or the place that holds the vertexs.. there will have to be some kind of pointer to this... perhaps another array?

So logically this occurs

MapArray[x][y] points to another place that holds [x+y+, x+y-, x-y-, x-y+)
the four coordinates to draw our box. Once the box is drawn we then put a
texture on top of that.

Perhaps I am looking at this in overkill. Is this basically what is happening? Is it possible that we don't have to draw two triangles at all, but can just go ahead and draw a box? Would that be simpler? I think these questions lead up to how to declare the custom vertex structure and make the map array sync with it.

You guys probably know a much simpler way of looking at it! Lemme know!

Share this post


Link to post
Share on other sites
Hi there! So far so good. I have almost all the sections completed that you gave me hints for... But my primitive doesn't render. I saw speckled dots at first, and now after more tweeking a black window. (boo hoo) :~( I wanted to set up and render a few simple triangles before tackling the next issue...i.e associating the character array with a bitmap and then associating that with a vertex and then making that blit to the screen.

Does anyone see anything standing out in the code below that would cause rendering to fail... also is there any code in here that is completely non-essential for 2D style tile stuff?


#include "stdafx.h"
#include "WinMain.h"

#define WINDOW_TITLE "Improved DirectX Initialization"
#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define WINDOWED TRUE

// Set up the FVF
#define D3DFVF_CUSTOMVERTEX D3DFVF_XYZRHW

LPDIRECT3D9 g_pD3D9 = NULL;
LPDIRECT3DDEVICE9 g_pD3DDevice = NULL;
D3DDISPLAYMODE g_displayMode;
D3DPRESENT_PARAMETERS g_D3Dpp;

// make a pointer to where the Texture is
IDirect3DTexture9 *g_pTexture;

// make a pointer to the vertex buffer
IDirect3DVertexBuffer9 *g_pVB;

HWND g_hWnd;
/*TODO: additional variables*/

//A custom vertex structure
struct CUSTOMVERTEX
{
float x, y, z;
DWORD color;
};

CUSTOMVERTEX vertices[] =
{
{-10.0f, -10.0f, 10.0f, D3DCOLOR_XRGB( 255, 255, 255 )}, // Bottom left vertex
{ 0.0f, 10.0f, 10.0f, D3DCOLOR_XRGB( 255, 255, 255 )}, // Top vertex
{ 10.0f, 10.0f, 10.0f, D3DCOLOR_XRGB( 255, 255, 255 )} // Bottom right vertex
};


//your map array declaration
char map[12][12] = {
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2},
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}};




int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
{
// Define the window
WNDCLASSEX wcex;
wcex.cbSize = sizeof( WNDCLASSEX );
wcex.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_CUNIT ) );
wcex.hCursor = LoadCursor( NULL, IDC_ARROW );
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = WINDOW_TITLE;
wcex.hIconSm = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_CUNIT ) );

// Register the window
RegisterClassEx( &wcex );

// Create the window
g_hWnd = CreateWindow( WINDOW_TITLE, WINDOW_TITLE, (WINDOWED) ? WS_OVERLAPPEDWINDOW : WS_EX_TOPMOST, CW_USEDEFAULT, CW_USEDEFAULT, WINDOW_WIDTH, WINDOW_HEIGHT, 0, 0, hInstance, 0 );

// Adjust to actual desired size
RECT rect = { 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT };
AdjustWindowRect( &rect, GetWindowLong( g_hWnd, GWL_style ), FALSE );
SetWindowPos( g_hWnd, 0, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_NOMOVE );

ShowWindow( g_hWnd, SW_SHOW );
UpdateWindow( g_hWnd );

// Create Direct3D Object
g_pD3D9 = Direct3DCreate9( D3D_SDK_VERSION );
if ( !g_pD3D9 )
{
MessageBox( 0, "Direct3DCreate9() - Failed", 0, 0 );
return 0;
}

// Get display mode
g_pD3D9->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &g_displayMode );

// Check for hardware T&L
D3DCAPS9 D3DCaps;
g_pD3D9->GetDeviceCaps( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &D3DCaps );
DWORD vertexProcessing = 0;
if ( D3DCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT )
{
vertexProcessing = D3DCREATE_HARDWARE_VERTEXPROCESSING;
// Check for pure device
if ( D3DCaps.DevCaps & D3DDEVCAPS_PUREDEVICE )
{
vertexProcessing |= D3DCREATE_PUREDEVICE;
}
}
else
{
vertexProcessing = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}

// Fill out the presentation parameters
if ( !BuildPresentationParameters() )
{
MessageBox( 0, "Unable to find a valid DepthStencil Format", 0, 0 );
SAFE_RELEASE( g_pD3D9 );
return 0;
}

// Create the device
if ( FAILED( g_pD3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, vertexProcessing, &g_D3Dpp, &g_pD3DDevice ) ) )
{
SAFE_RELEASE( g_pD3D9 );
MessageBox( 0, "CreateDevice() - Failed", 0, 0 );
return 0;
}


/*TODO: additional setup*/
// Setting up your map array
// Setting up your D3Ddevice's FVF, turning off lighting, and any rendering values for the device

// Create our vertex buffer for rendering polygons at super speed
if( FAILED( g_pD3DDevice->CreateVertexBuffer( 3*sizeof(CUSTOMVERTEX),
0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
{
SAFE_RELEASE( g_pD3D9);
MessageBox( 0, "Create Vertex Buffer - Failed", 0, 0 );
return 0;
}

// Fill the Vertex Buffer
void *pVertices;
if( FAILED( g_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ) ) )
{
SAFE_RELEASE( g_pD3D9);
MessageBox( 0, "Can't fill Vertex Buffer - Failed", 0, 0 );
return 0;
}

memcpy( pVertices, vertices, sizeof(vertices) );

g_pVB->Unlock();


// Loading the texture or textures(D3DXCreateTextureFromFile or D3DXCreateTextureFromFileEx) - DONE
if ( FAILED( D3DXCreateTextureFromFile( g_pD3DDevice, "media/tile.bmp", &g_pTexture ) ) )
{
SAFE_RELEASE( g_pD3D9 );
MessageBox( 0, "Loading Texture - Failed", 0, 0 );
return 0;
}


// Main loop
MSG msg;
while ( 1 )
{
// Did we recieve a message?
if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
{
if ( msg.message == WM_QUIT)
{
break;
}
TranslateMessage( &msg );
DispatchMessage ( &msg );
}
else
{
RenderFrame();
}
}

// Give back resources
SAFE_RELEASE( g_pD3DDevice );
SAFE_RELEASE( g_pD3D9 );

/*TODO: additional cleanup*/
// Releasing texture(s), similar to what you are already doing with other Direct3D object. - DONE
SAFE_RELEASE( g_pTexture );


return 0;
}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
BuildPresentationParameters
Purpose:
Builds the D3DPRESENT_PARAMETERS structure using the current window size.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

BOOL BuildPresentationParameters()
{
ZeroMemory( &g_D3Dpp, sizeof(g_D3Dpp) );
D3DFORMAT adapterFormat = (WINDOWED) ? g_displayMode.Format : D3DFMT_X8R8G8B8;
if ( SUCCEEDED( g_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24S8 ) ) )
{
g_D3Dpp.AutoDepthStencilFormat = D3DFMT_D24S8;
}
else if ( SUCCEEDED( g_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D24X8 ) ) )
{
g_D3Dpp.AutoDepthStencilFormat = D3DFMT_D24X8;
}
else if ( SUCCEEDED( g_pD3D9->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, adapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
{
g_D3Dpp.AutoDepthStencilFormat = D3DFMT_D16;
}
else
{
return false;
}

g_D3Dpp.BackBufferWidth = (WINDOWED) ? 0 : g_displayMode.Width;
g_D3Dpp.BackBufferHeight = (WINDOWED) ? 0 : g_displayMode.Height;
g_D3Dpp.BackBufferFormat = adapterFormat;
g_D3Dpp.BackBufferCount = 1;
g_D3Dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
g_D3Dpp.MultiSampleQuality = 0;
g_D3Dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
g_D3Dpp.hDeviceWindow = g_hWnd;
g_D3Dpp.Windowed = WINDOWED;
g_D3Dpp.EnableAutoDepthStencil = TRUE;
g_D3Dpp.FullScreen_RefreshRateInHz = (WINDOWED) ? 0 : g_displayMode.RefreshRate;
g_D3Dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;

return TRUE;
}


// Function to Render the Current Frame
void RenderFrame()
{
g_pD3DDevice->Clear( 0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 0, 0, 100 ), 1.0f, 0 );
g_pD3DDevice->BeginScene();


// Render the frame
// selecting the texture(s) you want to draw(SetTexture)
// setting up the vertices
// drawing the polygons(DrawPrimitiveUP)

g_pD3DDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
g_pD3DDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pD3DDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 1, vertices, sizeof( CUSTOMVERTEX ) );


g_pD3DDevice->EndScene();
g_pD3DDevice->Present( 0, 0, 0, 0 );

}

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Summary: Application event handler.
Parameters:
[in] hWnd - Unique handle to the window.
[in] message - Incoming message.
[in] wParam - Parameter of the message (unsigned int).
[in] lParam - Parameter of the message (long).
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
switch ( message )
{
case WM_DESTROY:
PostQuitMessage( 0 );
return 0;
case WM_PAINT:
if ( g_pD3DDevice )
{
RenderFrame();
}
ValidateRect( hWnd, 0 );
return 0;
case WM_KEYDOWN:
switch ( wParam )
{
case VK_ESCAPE:
PostQuitMessage( 0 );
break;
}
return 0;
}
return DefWindowProc( hWnd, message, wParam, lParam );
}



[Edited by - sauronette on March 20, 2006 8:15:18 PM]

Share this post


Link to post
Share on other sites
You need to actually change your custom vertex structure to include the rhw, your FVF is D3DFVF_XYZRHW so you should have

struct CUSTOMVERTEX {
float x, y, z, rhw;
DWORD color;
};

so then set all rhw to 1.0f when you define your quads.

Share this post


Link to post
Share on other sites
yeppie. Tried that already. Used the code from the direct x SDK. Still no triangle for me.



struct CUSTOMVERTEX
{
float x, y, z, rhw;
DWORD color;
};

CUSTOMVERTEX vertices[] =
{
{-10.0f, -10.0f, 10.0f, 1.0f }, // Bottom left vertex
{ 0.0f, 10.0f, 10.0f, 1.0f }, // Top vertex
{ 10.0f, 10.0f, 10.0f, 1.0f } // Bottom right vertex
};

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!