Trying to do a little DirectX stuff... I've installed the latest SDK (from Dec 05, no less). When I go to compile, I get these errors under VC6:
C:\Program Files\Microsoft Visual Studio\MyProjects\trans_sprite\game.cpp(107) : error C2065: 'D3DXSPRITE_ALPHABLEND' : undeclared identifier
C:\Program Files\Microsoft Visual Studio\MyProjects\trans_sprite\game.cpp(118) : error C2660: 'Draw' : function does not take 5 parameters
There's several files here, so bear with me....
dxgraphics.h
Code:
#ifndef _DXGRAPHICS_H
#define _DXGRAPHICS_H
//function prototypes
int Init_Direct3D(HWND, int, int, int);
LPDIRECT3DSURFACE9 LoadSurface(char *, D3DCOLOR);
LPDIRECT3DTEXTURE9 LoadTexture(char *, D3DCOLOR);
//variable declarations
extern LPDIRECT3D9 d3d;
extern LPDIRECT3DDEVICE9 d3ddev;
extern LPDIRECT3DSURFACE9 backbuffer;
#endif
game.h
Code:
#ifndef _GAME_H
#define _GAME_H
#include <d3d9.h>
#include <d3dx9.h>
#include <d3dx9math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "dxgraphics.h"
//application title
#define APPTITLE "Trans_Sprite"
//screen setup
#define FULLSCREEN 0 //0 = windowed, 1 = fullscreen
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
//macros to read the keyboard asynchronously
#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code)((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
//function prototypes
int Game_Init(HWND);
void Game_Run(HWND);
void Game_End(HWND);
//sprite structure
typedef struct {
int x,y;
int width,height;
int movex,movey;
int curframe,lastframe;
int animdelay,animcount;
int scalex, scaley;
int rotation, rotaterate;
} SPRITE;
#endif
winmain.cpp
Code:
#include <d3d9.h>
#include <d3dx9.h>
#include <time.h>
#include <stdio.h>
#include "dxgraphics.h"
#include "game.h"
//window event callback function
LRESULT WINAPI WinProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
switch( msg )
{
case WM_DESTROY:
//release the Direct3D device
if (d3ddev != NULL)
d3ddev->Release();
//release the Direct3D object
if (d3d != NULL)
d3d->Release();
//call the "front-end" shutdown function
Game_End(hWnd);
//tell Windows to kill this program
PostQuitMessage(0);
return 0;
}
return DefWindowProc( hWnd, msg, wParam, lParam );
}
//helper function to set up the window properties
ATOM MyRegisterClass(HINSTANCE hInstance)
{
//create the window class structure
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
//fill the struct with info
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = APPTITLE;
wc.hIconSm = NULL;
//set up the window with the class info
return RegisterClassEx(&wc);
}
//entry point for a Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HWND hWnd;
// register the class
MyRegisterClass(hInstance);
//set up the screen in windowed or fullscreen mode?
DWORD style;
if (FULLSCREEN)
style = WS_EX_TOPMOST | WS_VISIBLE | WS_POPUP;
else
style = WS_OVERLAPPED;
//create a new window
hWnd = CreateWindow(
APPTITLE, //window class
APPTITLE, //title bar
style, //window style
CW_USEDEFAULT, //x position of window
CW_USEDEFAULT, //y position of window
SCREEN_WIDTH, //width of the window
SCREEN_HEIGHT, //height of the window
NULL, //parent window
NULL, //menu
hInstance, //application instance
NULL); //window parameters
//was there an error creating the window?
if (!hWnd)
return FALSE;
//display the window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
if (!Init_Direct3D(hWnd, SCREEN_WIDTH, SCREEN_HEIGHT, FULLSCREEN))
return 0;
//initialize the game
if (!Game_Init(hWnd))
{
MessageBox(hWnd, "Error initializing the game", "Error", MB_OK);
return 0;
}
// main message loop
int done = 0;
while (!done)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
//look for quit message
if (msg.message == WM_QUIT)
done = 1;
//decode and pass messages on to WndProc
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
//process game loop (else prevents running after window is closed)
Game_Run(hWnd);
}
return msg.wParam;
}
dxgraphics.cpp
Code:
#include <d3d9.h>
#include <d3dx9.h>
#include "dxgraphics.h"
//variable declarations
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
LPDIRECT3DSURFACE9 backbuffer = NULL;
int Init_Direct3D(HWND hwnd, int width, int height, int fullscreen)
{
//initialize Direct3D
d3d = Direct3DCreate9(D3D_SDK_VERSION);
if (d3d == NULL)
{
MessageBox(hwnd, "Error initializing Direct3D", "Error", MB_OK);
return 0;
}
//set Direct3D presentation parameters
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = (!fullscreen);
d3dpp.SwapEffect = D3DSWAPEFFECT_COPY;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = width;
d3dpp.BackBufferHeight = height;
d3dpp.hDeviceWindow = hwnd;
//create Direct3D device
d3d->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
if (d3ddev == NULL)
{
MessageBox(hwnd, "Error creating Direct3D device", "Error", MB_OK);
return 0;
}
//clear the backbuffer to black
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
//create pointer to the back buffer
d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer);
return 1;
}
LPDIRECT3DSURFACE9 LoadSurface(char *filename, D3DCOLOR transcolor)
{
LPDIRECT3DSURFACE9 image = NULL;
D3DXIMAGE_INFO info;
HRESULT result;
//get width and height from bitmap file
result = D3DXGetImageInfoFromFile(filename, &info);
if (result != D3D_OK)
return NULL;
//create surface
result = d3ddev->CreateOffscreenPlainSurface(
info.Width, //width of the surface
info.Height, //height of the surface
D3DFMT_X8R8G8B8, //surface format
D3DPOOL_DEFAULT, //memory pool to use
&image, //pointer to the surface
NULL); //reserved (always NULL)
if (result != D3D_OK)
return NULL;
//load surface from file into newly created surface
result = D3DXLoadSurfaceFromFile(
image, //destination surface
NULL, //destination palette
NULL, //destination rectangle
filename, //source filename
NULL, //source rectangle
D3DX_DEFAULT, //controls how image is filtered
transcolor, //for transparency (0 for none)
NULL); //source image info (usually NULL)
//make sure file was loaded okay
if (result != D3D_OK)
return NULL;
return image;
}
LPDIRECT3DTEXTURE9 LoadTexture(char *filename, D3DCOLOR transcolor)
{
//the texture pointer
LPDIRECT3DTEXTURE9 texture = NULL;
//the struct for reading bitmap file info
D3DXIMAGE_INFO info;
//standard Windows return value
HRESULT result;
//get width and height from bitmap file
result = D3DXGetImageInfoFromFile(filename, &info);
if (result != D3D_OK)
return NULL;
//create the new texture by loading a bitmap image file
D3DXCreateTextureFromFileEx(
d3ddev, //Direct3D device object
filename, //bitmap filename
info.Width, //bitmap image width
info.Height, //bitmap image height
1, //mip-map levels (1 for no chain)
D3DPOOL_DEFAULT, //the type of surface (standard)
D3DFMT_UNKNOWN, //surface format (default)
D3DPOOL_DEFAULT, //memory class for the texture
D3DX_DEFAULT, //image filter
D3DX_DEFAULT, //mip filter
transcolor, //color key for transparency
&info, //bitmap file info (from loaded file)
NULL, //color palette
&texture ); //destination texture
//make sure the bitmap textre was loaded correctly
if (result != D3D_OK)
return NULL;
return texture;
}
game.cpp
Code:
#include "game.h"
LPDIRECT3DTEXTURE9 kitty_image[7];
SPRITE kitty;
LPDIRECT3DSURFACE9 back;
LPD3DXSPRITE sprite_handler;
HRESULT result;
//timing variable
long start = GetTickCount();
//initializes the game
int Game_Init(HWND hwnd)
{
char s[20];
int n;
//set random number seed
srand(time(NULL));
//create sprite handler object
result = D3DXCreateSprite(d3ddev, &sprite_handler);
if (result != D3D_OK)
return 0;
//load the sprite animation
for (n=0; n<6; n++)
{
//set up the filename
sprintf(s,"cat%d.bmp",n+1);
//load texture with "pink" as the transparent color
kitty_image[n] = LoadTexture(s, D3DCOLOR_XRGB(255,0,255));
if (kitty_image[n] == NULL)
return 0;
}
//load the background image
back = LoadSurface("background.bmp", NULL);
//initialize the sprite's properties
kitty.x = 100;
kitty.y = 150;
kitty.width = 96;
kitty.height = 96;
kitty.curframe = 0;
kitty.lastframe = 5;
kitty.animdelay = 2;
kitty.animcount = 0;
kitty.movex = 8;
kitty.movey = 0;
//return okay
return 1;
}
//the main game loop
void Game_Run(HWND hwnd)
{
//make sure the Direct3D device is valid
if (d3ddev == NULL)
return;
//after short delay, ready for next frame?
//this keeps the game running at a steady frame rate
if (GetTickCount() - start >= 30)
{
//reset timing
start = GetTickCount();
//move the sprite
kitty.x += kitty.movex;
kitty.y += kitty.movey;
//"warp" the sprite at screen edges
if (kitty.x > SCREEN_WIDTH - kitty.width)
kitty.x = 0;
if (kitty.x < 0)
kitty.x = SCREEN_WIDTH - kitty.width;
//has animation delay reached threshold?
if (++kitty.animcount > kitty.animdelay)
{
//reset counter
kitty.animcount = 0;
//animate the sprite
if (++kitty.curframe > kitty.lastframe)
kitty.curframe = 0;
}
}
//start rendering
if (d3ddev->BeginScene())
{
//erase the entire background
d3ddev->StretchRect(back, NULL, backbuffer, NULL, D3DTEXF_NONE);
//start sprite handler
sprite_handler->Begin(D3DXSPRITE_ALPHABLEND);
//create vector to update sprite position
D3DXVECTOR3 position((float)kitty.x, (float)kitty.y, 0);
//draw the sprite
sprite_handler->Draw(
kitty_image[kitty.curframe],
NULL,
NULL,
&position,
D3DCOLOR_XRGB(255,255,255));
//stop drawing
sprite_handler->End();
//stop rendering
d3ddev->EndScene();
}
//display the back buffer on the screen
d3ddev->Present(NULL, NULL, NULL, NULL);
//check for escape key (to exit program)
if (KEY_DOWN(VK_ESCAPE))
PostMessage(hwnd, WM_DESTROY, 0, 0);
}
//frees memory and cleans up before the game ends
void Game_End(HWND hwnd)
{
int n;
for (n=0; n<6; n++)
if (kitty_image[n] != NULL)
kitty_image[n]->Release();
if (back != NULL)
back->Release();
if (sprite_handler != NULL)
sprite_handler->Release();
}
Any thoughts??? I looked at the Draw function in the MSDN library, and according to them it does take 5 parameters... :P
Thanks!
-Max