Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Por que es tan lento?

Iniciado por McBain, 19 de Junio de 2006, 08:16:56 PM

« anterior - próximo »

McBain

Estoy iniciandome con DirectX. Estoy haciendo un clon del Arkanoid, y la verdad es que el código que tengo hasta ahora es muy lento. Alguien puede decirme el motivo?

App.h

#pragma once

#include "Wind.h"
#include "Engine.h"
#include "HTime.h"
#include "Keyboard.h"
#include "Pad.h"

class App
{
public:
App(void);
bool Init(HINSTANCE hInst,char * Name,char *Title,int x,int y,int width,int height,bool Windowed);
void Run(void);
void Release(void);
~App(void);
private:
Graphic engine;
Wind window;
HTime timer;
Keyboard keyboard;
Pad pad;
Sprite border;
};


App.cpp


#include "App.h"

App::App(void): engine(),window(),timer(),keyboard(), pad(), border()
{
}

App::~App(void)
{
Release();
}

bool App::Init(HINSTANCE hInst,char * Name,char *Title,int x,int y,
  int width,int height,bool Windowed)
{
bool b;
b=window.Init(hInst,Name,Title,x,y,width,height,((Windowed)?(FOR_WINDOWED):(FOR_FULLSCREEN)));
if(!b) return false;
b=engine.Init(window.hWnd(),Windowed,width,height,((Windowed)?(GWINDOW):(GFULL)));
if(!b) Release();
window.Show();
if(FAILED(keyboard.Init(hInst,window.hWnd())))
{
Release();
return false;
}
pad.Prepare();
border.Load("images\\border.tga");
border((float)Sprite::SizeX/2,(float)Sprite::SizeY-150-25);
return b;
}

void App::Release(void)
{
keyboard.Release();
border.Release();
pad.Release();
engine.Release();
}

void App::Run(void)
{
float delta=timer.Elapsed();
keyboard.Update();
if(keyboard.IsPressed(DIK_ESCAPE)) PostQuitMessage(0);
if(keyboard.IsPressed(DIK_LEFT))   pad.MoveLeft(delta);
if(keyboard.IsPressed(DIK_RIGHT))  pad.MoveRight(delta);

engine.Clear(D3DCOLOR_XRGB(0,0,0));
engine.Prepare();
pad.Draw();
border.Draw();
engine.Render();
}


Engine.h

//Necesita d3d9.lib d3dx9.lib
#include <d3d9.h>
#include <d3dx9.h>

class Sprite;
class Graphic;

#include "Graphic.h"
#include "Sprite.h"


Graphic.h

#pragma once


#define GFULL   D3DFMT_A8R8G8B8
#define GWINDOW D3DFMT_UNKNOWN

class Graphic
{
friend class Sprite;
public:
Graphic(void);
bool Init(HWND hWnd,bool Windowed,int sizeX,int sizeY,D3DFORMAT Format=D3DFMT_UNKNOWN);
void Release(void);
void Clear(D3DCOLOR Color)
{
pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET,Color, 1.0f, 0 );
}
void Render(void)
{
pd3dSprite->End();
pd3dDevice->EndScene();
pd3dDevice->Present(NULL,NULL,NULL,NULL);
}
D3DFORMAT Format(void) const
{
return format;
}
void Prepare(void)
{
pd3dDevice->BeginScene();
pd3dSprite->Begin(0);
}
~Graphic(void);
private:
LPDIRECT3D9 pD3D;
LPDIRECT3DDEVICE9 pd3dDevice;
LPDIRECT3DSURFACE9 backbuffer;
LPD3DXSPRITE pd3dSprite;
D3DFORMAT format;
int SizeX,SizeY;
};



Graphic.cpp

#include "Engine.h"

Graphic::Graphic(void)
{
pD3D=NULL;
pd3dDevice=NULL;
backbuffer=NULL;
pd3dSprite=NULL;
SizeX=SizeY=0;
ZeroMemory(&format,sizeof(D3DFORMAT));
}

Graphic::~Graphic(void)
{
Release();
}

void Graphic::Release(void)
{
if(pD3D)
{
if(pd3dDevice)
{
if(pd3dSprite)
{
pd3dSprite->Release();
pd3dSprite=NULL;
}
pd3dDevice->Release();
pd3dDevice=NULL;
}
pD3D->Release();
pD3D=NULL;
}
}

bool Graphic::Init(HWND hWnd,bool Windowed,int sizeX,int sizeY,D3DFORMAT Format)
{
HRESULT hr;
D3DPRESENT_PARAMETERS d3dpp;

pD3D=Direct3DCreate9(D3D_SDK_VERSION);
if(!pD3D) return false;

ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = Windowed;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
format=((Windowed)?(D3DFMT_UNKNOWN):(Format));
d3dpp.BackBufferFormat = Format;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferHeight = sizeY;
d3dpp.BackBufferWidth = sizeX;
d3dpp.hDeviceWindow = hWnd;
SizeX=sizeX;
SizeY=sizeY;
hr = pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,&d3dpp,&pd3dDevice);
if(FAILED(hr))
{
Release();
return false;
}
hr = D3DXCreateSprite(pd3dDevice, &pd3dSprite);
if(FAILED(hr))
{
Release();
return false;
}
Sprite::engine=this;
Sprite::SizeX=sizeX;
Sprite::SizeY=sizeY;
return true;
}


HTime.h

#pragma once
#include <windows.h>

class HTime
{
public:
HTime(void);
void Wait(float ms);
float Elapsed(void);
~HTime(void);
private:
LARGE_INTEGER timerFrequency;
LARGE_INTEGER last;
LARGE_INTEGER now;
};


HTime.cpp

#include "HTime.h"

HTime::HTime(void)
{
QueryPerformanceFrequency(&timerFrequency);
QueryPerformanceCounter(&last);
}

HTime::~HTime(void)
{
}

void HTime::Wait(float ms)
{
LARGE_INTEGER start,moment;
float elap;
QueryPerformanceCounter(&start);
do
{
QueryPerformanceCounter(&moment);
elap=float(moment.QuadPart-start.QuadPart)/(timerFrequency.QuadPart);
}while(elap<ms);
}

float HTime::Elapsed()
{
QueryPerformanceCounter(&now);
return (float)(now.QuadPart-last.QuadPart)/(timerFrequency.QuadPart);
}


Keyboard.h

#pragma once

//Needs dinput8.lib
#define DIRECTINPUT_VERSION 0x0800 //Se pone para eliminar el Warning (le digo que quiero usar DINPUT 8)
#include <dinput.h>

#define KEYDOWN(name, key) (name[key] & 0x80)
const int KEYS = 256;

class Keyboard
{
public:
Keyboard();
Keyboard(HINSTANCE hInst,HWND hWnd){Init(hInst,hWnd);};
HRESULT Init(HINSTANCE hInst,HWND hWnd);
void Update() {lpDIDevice->GetDeviceState(sizeof(buffer),(LPVOID)&buffer);}
bool IsPressed(int key)
{
if(KEYDOWN(buffer,key))
return TRUE;
else return FALSE;
};
void Release();
~Keyboard(){Release();};
private:
LPDIRECTINPUT8  lpDI;
LPDIRECTINPUTDEVICE8  lpDIDevice;
char buffer[KEYS];

};


Keyboard.cpp

#include "Keyboard.h"

Keyboard::Keyboard()
{
lpDI=NULL;
lpDIDevice=NULL;
}
HRESULT Keyboard::Init(HINSTANCE hInst,HWND hWnd)
{
HRESULT hr=DirectInput8Create(hInst, DIRECTINPUT_VERSION,IID_IDirectInput8, (void**)&lpDI, NULL);
if(FAILED(hr))
return hr;
hr=lpDI->CreateDevice(GUID_SysKeyboard, &lpDIDevice, NULL);
if(FAILED(hr))
return hr;
hr=lpDIDevice->SetDataFormat(&c_dfDIKeyboard);
if(FAILED(hr))
return hr;
hr=lpDIDevice->SetCooperativeLevel(hWnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
if(FAILED(hr))
return hr;
hr=lpDIDevice->Acquire();
return hr;
}

void Keyboard::Release()
{
   if(lpDI)
   {
       if(lpDIDevice)
       {
           lpDIDevice->Unacquire();
           lpDIDevice->Release();
           lpDIDevice = NULL;
       }
       lpDI->Release();
       lpDI = NULL;
   }
}


Main.h

#include "App.h"


Main.cpp

#include "Main.h"

INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,INT )
{
MSG msg;
App app;

if(!app.Init(hInst,"Arkanoid","Arkanoid",20,20,640,480,true))
return -1;

msg.message=WM_NULL;
while(WM_QUIT!= msg.message)
{
if(PeekMessage(&msg,NULL,0U,0U,PM_REMOVE))
{
DispatchMessage(&msg);
}
else app.Run();
}
app.Release();
return 0;
}


Sprite.h

#pragma once

class Sprite
{
friend class Graphic;
public:
Sprite(void);
bool Load(const char * File);
void Release(void);
~Sprite(void);
float  X(void)  {return x;};
float  Y(void)  {return y;};
void operator() (float x,float y)
{
this->x=x;
this->y=y;
}
int  Height(void)  {return height;};
int  Width (void)  {return width;};
void Draw(void)
{
engine->pd3dSprite->Draw(texture,NULL,&D3DXVECTOR3((float)(twidth/2),float(theight/2),0.0f),&D3DXVECTOR3(x,y,0.0f),0xFFFFFFFF);
}

static int SizeX,SizeY;
protected:
RECT rect;
float x,y;
int width;
int height;
LPDIRECT3DTEXTURE9 texture;
int theight, twidth;
static Graphic *engine;
};


Sprite.cpp

#include "Engine.h"

int Sprite::SizeX=0;
int Sprite::SizeY=0;
Graphic * Sprite::engine =NULL;

Sprite::Sprite(void)
{
texture=NULL;
rect.bottom=0;
rect.left=0;
rect.right=0;
rect.top=0;
x=y=0;
width=height=0;
twidth=theight=0;
}

Sprite::~Sprite(void)
{
Release();
}

bool Sprite::Load(const char *File)
{
HRESULT hr;
D3DXIMAGE_INFO imageInfo;
D3DSURFACE_DESC surfaceInfo;

hr = D3DXCreateTextureFromFileEx(Sprite::engine->pd3dDevice,File,D3DX_DEFAULT,
D3DX_DEFAULT,D3DX_DEFAULT,0 ,D3DFMT_UNKNOWN,
D3DPOOL_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT,0,
&imageInfo,NULL,&texture);
if(FAILED(hr))
return false;
if(FAILED(texture->GetLevelDesc(0,&surfaceInfo)))
return false;

width=imageInfo.Width;
height=imageInfo.Height;
theight=surfaceInfo.Height;
twidth=surfaceInfo.Width;
//ARREGLAR EN UN FUTURO
rect.top=0;
rect.left=0;
rect.right=twidth;
rect.bottom=theight;
//
return true;
}

void Sprite::Release()
{
if(texture)
{
texture->Release();
texture=NULL;
}
}


Wind.h

#pragma once
#include <windows.h>
#include <string>

#define FOR_FULLSCREEN WS_EX_TOPMOST | WS_POPUP | WS_VISIBLE
#define FOR_WINDOWED   WS_OVERLAPPEDWINDOW

class Wind
{
public:
Wind(void);
bool Init(HINSTANCE hInst,const char * Name,const char * Title,int x, int y, int width,int height,DWORD dwStyle=WS_OVERLAPPEDWINDOW);
void Show(void) const;
~Wind(void);
static LRESULT CALLBACK MsgProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
int Width(void) const
{
return m_width;
}
int Height(void) const
{
return m_height;
}
HWND hWnd(void) const
{
return m_hWnd;
}
private:
WNDCLASSEX m_wc;
HWND m_hWnd;
int m_width;
int m_height;
std::string m_Name;
};


Wind.cpp

#include "Wind.h"

Wind::Wind(void)
{

}

bool Wind::Init(HINSTANCE hInst,const char * Name,const char *Title,int x, int y, int width,int height,DWORD dwStyle)
{
ZeroMemory(&m_wc, sizeof(WNDCLASSEX));
m_wc.cbSize = sizeof( WNDCLASSEX );
m_wc.style  = CS_HREDRAW | CS_VREDRAW;
m_wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
m_wc.lpfnWndProc = (WNDPROC)Wind::MsgProc;
m_wc.lpszClassName = Name;
m_wc.hInstance=hInst;
RegisterClassEx(&m_wc);
m_hWnd=CreateWindow(Name,Title,dwStyle,x,y, width, height,
GetDesktopWindow(), NULL, hInst, NULL);
if(m_hWnd)
{
m_Name=Name;
m_height=height;
m_width=width;
return true;
}
else return false;
}

void Wind::Show(void) const
{
ShowWindow(m_hWnd, SW_SHOWDEFAULT );
UpdateWindow(m_hWnd);
}

LRESULT CALLBACK Wind::MsgProc(HWND hWnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch(msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_SETCURSOR:
       SetCursor(NULL);
       return TRUE;
case WM_ERASEBKGND:
return TRUE;
}
return DefWindowProc( hWnd, msg, wparam, lparam);
}

Wind::~Wind()
{
UnregisterClass( m_Name.c_str() , m_wc.hInstance );
}


Pad.h

#pragma once
#include "Engine.h"

class Pad:public Sprite
{
public:
Pad(void);
void MoveRight(float elapsed);
void MoveLeft (float elapsed);
void Prepare(void)
{
Load("images\\pad.tga");
x=float(Sprite::SizeX)/2.0f;
y=float(Sprite::SizeY-20);
}
~Pad(void);
private:
int lives;
};


Pad.cpp

#include "Pad.h"

const float Speed=1.0f;
Pad::Pad(void):Sprite()
{
lives=3;
}

Pad::~Pad(void)
{
}

void Pad::MoveLeft(float elapsed)
{
x-=(elapsed)*Speed;
}

void Pad::MoveRight(float elapsed)
{
x+=(elapsed)*Speed;
}


Conoceis páginas donde haya tutoriales sobre 2D(DX9). Googleando he encontrado páginas como 32 bits, toymaker..., pero por lo general usan algunas funciones que ya no estan en la versión de febrero.
Con los libros sucede algo parecido, la mayoría que he encontrado son sobre Dx8, y los q son sobre dx9 apenas tratan el 2d y se centran en el 3d.

senior wapo

Cambia D3DDEVTYPE_REF por D3DDEVTYPE_HAL

Que dolor leer todo eso :)

McBain

Muchas gracias senior wapo, ya me tira perfecto.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.