Archived

This topic is now archived and is closed to further replies.

Struggling w/ 2D in Direct3D 9

This topic is 5398 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. I'm a DirectDraw programmer just beginning to learn Direct3D. I followed Parker's tutorial (Dissecting Sprites in Direct3D) to create the following code, but it doesn't display anything. To compound matters, there are no errors or any advice whatsoever from the compiler (I have the maximum debug level on). If anyone could give me any clue what I'm doing wrong, I'd really appreciate it. //Graphics Engine.cpp
  
#include "stdafx.h"
#include "GraphicsEngine.h"

ScGraphics::ScGraphics()
{
	m_centerWindowData.X = 0;
	m_centerWindowData.Y = 0;
	m_centerWindowData.Width = SC::SCREEN_WIDTH;
	m_centerWindowData.Height = SC::SCREEN_HEIGHT;
	m_centerWindowData.MaxZ = 1.0f;
	m_centerWindowData.MinZ = 0.0f;
}

bool ScGraphics::initializeDirect3D(HWND hWnd)
{
	m_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

	if (!m_pD3D)
		return false;


	D3DDISPLAYMODE mode;
	UINT ModeCounter = m_pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);

	if (ModeCounter == 0) return false;

	for (UINT displayMode = 0; displayMode < ModeCounter; displayMode++)
	{
		m_pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, displayMode, &mode);

		if (mode.Width == SC::SCREEN_WIDTH && mode.Height == SC::SCREEN_HEIGHT)
			break;
	}

	if (mode.Width != SC::SCREEN_WIDTH || mode.Height != SC::SCREEN_HEIGHT)
		return false;

	//set up presentation parameters

	D3DPRESENT_PARAMETERS parms;

	//back buffer information

	parms.BackBufferWidth = 0; 
	parms.BackBufferHeight = 0; 
	parms.BackBufferFormat = mode.Format; 
	parms.BackBufferCount = 1; //make one back buffer

	parms.MultiSampleType = D3DMULTISAMPLE_NONE;
	parms.MultiSampleQuality = 0;
	parms.SwapEffect = D3DSWAPEFFECT_COPY; //we want to copy from back buffer to screen

	parms.hDeviceWindow = hWnd; 
	parms.Windowed = TRUE;
	parms.EnableAutoDepthStencil = FALSE;
	parms.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
	parms.Flags = 0 ;
	parms.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;
	parms.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT;

	HRESULT hr = m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &parms ,&m_pDevice);

	bool x = (hr == D3DERR_INVALIDCALL);
	x = (hr == D3DERR_NOTAVAILABLE);
	x = (hr == D3DERR_OUTOFVIDEOMEMORY);

	//attempt to create a HAL device

	if (FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &parms ,&m_pDevice)))
	{ // then create reference device

		if (FAILED(m_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd , D3DCREATE_SOFTWARE_VERTEXPROCESSING , &parms , &m_pDevice)))
			return false;
		else
			m_devType = D3DDEVTYPE_REF;
	}
	else
		m_devType = D3DDEVTYPE_HAL;

	m_centerWindowData.Width = parms.BackBufferWidth;
	m_centerWindowData.Height = parms.BackBufferHeight;
	m_pDevice->SetViewport(&m_centerWindowData);

	m_sprite = new ASprite(m_pDevice);
	m_sprite->init(".\\bitmaps\\ambi4x01.tga");

	return true;
}

void ScGraphics::initialize2DBlitting()
{
	m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

	// Enable alpha blended transparency.

	m_pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
	m_pDevice->SetRenderState(D3DRS_SRCBLEND,  D3DBLEND_SRCALPHA);
	m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);

	m_pDevice->SetTextureStageState(
		0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
	m_pDevice->SetTextureStageState(
		0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
	m_pDevice->SetTextureStageState(
		0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE);

	//m_pDevice->SetVertexShader(NULL);

	m_pDevice->SetFVF(D3DFVF_SPRITEVERTEX);

}

void ScGraphics::DrawAll()
{
	POINT destPoint = { 0, 0 };

	m_pDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 0.0f, 0);

	m_pDevice->BeginScene();
//

	initialize2DBlitting();

	m_sprite->bltSprite(&destPoint);


	m_pDevice->EndScene();
	m_pDevice->Present(NULL,NULL,NULL,NULL);
}
  
//GraphicsEngine.h
  
#include "Sprite.h"

class ScGraphics
{
private:
	void initialize2DBlitting(); // set up the screen for 2D blitting....


public:
	IDirect3D9*			m_pD3D; // IDirect3D9 pointer

	D3DDEVTYPE			m_devType; // Device Type

	IDirect3DDevice9*	m_pDevice; // Pointer to the device

	D3DVIEWPORT9		m_centerWindowData; // Our main viewport (where we "present" our 2D surface)

	ASprite				*m_sprite;

	ScGraphics();
	void DrawAll();

	bool initializeDirect3D(HWND hWnd);
};
  
//Sprites.cpp
  
#include "stdafx.h"
#include "Sprite.h"

SpriteVertex::SpriteVertex()
{
	rhw= 1.0f;
	z = 0.0f;
}

void SpriteVertex::init(float xPos, float yPos, float zPos, float rhwPos, D3DCOLOR acolor, float uPos, float vPos)
{
	x = xPos;
	y = yPos;
	z = zPos;
	rhw = rhwPos;
	m_color = acolor;
	u = uPos;
	v = vPos;
}

ASprite::ASprite(IDirect3DDevice9* pDevice)
{
	m_pDevice = pDevice;

	m_SpriteVertices[0].u = 0.0;
	m_SpriteVertices[0].v = 0.0;
	m_SpriteVertices[1].u = 1.0;
	m_SpriteVertices[1].v = 0.0;
	m_SpriteVertices[2].u = 0.0;
	m_SpriteVertices[2].v = 1.0;
	m_SpriteVertices[3].u = 1.0;
	m_SpriteVertices[3].v = 1.0;

}

void ASprite::bltSprite(POINT* pDest, bool useAlpha, COLOR_CODE color)
{
	D3DSURFACE_DESC SurfaceDesc;
	m_pTexture->GetLevelDesc(0, &SurfaceDesc);

	float z = 0.0f;
	float ex = 0.0f;
	float left   = (float)pDest->x;
	float top    = (float)pDest->y;
	float right  = left + SurfaceDesc.Width;
	float bottom = top + SurfaceDesc.Height;
	float rhw = 1.0f;

	D3DCOLOR defaultColor = D3DCOLOR_XRGB(0,0,0);

	m_SpriteVertices[0].init(left - ex, top - ex, z, rhw, defaultColor, 0, 0);
	m_SpriteVertices[1].init(right + ex, top - ex, z, rhw, defaultColor, 1, 0);
	m_SpriteVertices[2].init(right + ex, bottom + ex, z, rhw, defaultColor, 1, 1);
	m_SpriteVertices[3].init(left - ex, bottom + ex, z, rhw, defaultColor, 0, 1);

	m_pDevice->SetTexture(0, m_pTexture);
	m_pDevice->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, m_SpriteVertices, sizeof(SpriteVertex));
}

bool ASprite::createTextureFromSurface(RECT *pSrcRect)
{
	long width  = pSrcRect->right - pSrcRect->left; 
	long height = pSrcRect->bottom - pSrcRect->top; 

	D3DSURFACE_DESC SurfaceDesc;

	m_thisSurface->GetDesc(&SurfaceDesc);

	if (FAILED(D3DXCreateTexture(m_pDevice, width, height, 
		1, 0, SurfaceDesc.Format, D3DPOOL_DEFAULT, &m_pTexture)))
		return false;

	// Retrieve the surface image of the texture.

	LPDIRECT3DSURFACE9 pTextureSurface;
	LPDIRECT3DTEXTURE9 pTexture = m_pTexture;

	pTexture->GetLevelDesc(0, &SurfaceDesc);
	pTexture->GetSurfaceLevel(0, &pTextureSurface);

	// Create a clean surface to clear the texture with.

	LPDIRECT3DSURFACE9 pCleanSurface;
	D3DLOCKED_RECT lockedRect;

	if (FAILED(m_pDevice->CreateOffscreenPlainSurface(SurfaceDesc.Width, 
		SurfaceDesc.Height, SurfaceDesc.Format, D3DPOOL_SYSTEMMEM, &pCleanSurface, NULL)))
		return false;

	pCleanSurface->LockRect(&lockedRect, NULL, 0);

	memset((BYTE*)lockedRect.pBits, 0, SurfaceDesc.Height * lockedRect.Pitch);
	pCleanSurface->UnlockRect();

	if (FAILED(m_pDevice->UpdateSurface(pCleanSurface, NULL, pTextureSurface, NULL)))
		return false;

	pCleanSurface->Release();

	// Copy the image to the texture.

	POINT destPoint = { 0, 0 };

	if (FAILED(m_pDevice->UpdateSurface(m_thisSurface, pSrcRect, pTextureSurface, &destPoint)))
		return false;

	pTextureSurface->Release();

	return true;
}

bool ASprite::createSurfaceFromFile(char *fileName) 
{

	LPDIRECT3DSURFACE9 LocalSurface;
	D3DXIMAGE_INFO srcInfo;    
//	PALETTEENTRY palette[256]; // Optional


	// A quick hack to get the size of the image into srcInfo.

	if (FAILED(m_pDevice->CreateOffscreenPlainSurface(1, 1, SC_SURFACE_FORMAT, D3DPOOL_DEFAULT, &LocalSurface, NULL)))
		return false;

	if (FAILED(D3DXLoadSurfaceFromFile(LocalSurface, NULL, NULL, fileName, NULL, D3DX_FILTER_NONE, 0, &srcInfo)))
		return false;

	LocalSurface->Release();

	
	if (FAILED(m_pDevice->CreateOffscreenPlainSurface(srcInfo.Width, srcInfo.Height, SC_SURFACE_FORMAT, D3DPOOL_SYSTEMMEM, &m_thisSurface, NULL)))
		return false;

	LocalSurface = m_thisSurface;

	if (FAILED(D3DXLoadSurfaceFromFile(LocalSurface, NULL, NULL, fileName, 
		NULL, D3DX_FILTER_NONE, 0xFF000000, &srcInfo)))
		return false;

	return true;
}

bool ASprite::init(char *pFilename, bool isVertical)
{
	RECT srcRect = { 0, 0, 64, 64 };
	
	if (!createSurfaceFromFile(pFilename))
		return false;

	if (!createTextureFromSurface(&srcRect))
		return false;

	return true;
}
  
//Sprite.h
  
#pragma once
#include <d3dx9tex.h>
#include <d3d9.h>

#define	NUM_SPRITE_VERTICES	4 // how many vertices are used to present a 2D sprite...

#define SPRITE_NAME_LEN     32

const D3DFORMAT SC_SURFACE_FORMAT = D3DFMT_A8R8G8B8;
const DWORD D3DFVF_SPRITEVERTEX = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;

struct SpriteVertex
{
	SpriteVertex();
	void init(float x, float y, float z, float rhw, D3DCOLOR color, float u, float v);

	float x;
	float y;
	float z;
	float rhw;
	D3DCOLOR m_color;
	float u; // textured x

	float v; // textured y


};

class ASprite
{
private:
	char  m_name[SPRITE_NAME_LEN];

	IDirect3DDevice9* m_pDevice;
	
	LPDIRECT3DTEXTURE9 m_pTexture;
	LPDIRECT3DSURFACE9 m_thisSurface;
    long m_width;
    long m_height;

    ULONG *m_pData;     // Backup storage of data if we lose the surface.


	bool createTextureFromSurface(RECT* pSrcRect); // next create a texture from our loaded files clipping to the right-sized rectangle

	bool createSurfaceFromFile(char *fileName); // first load our .tga or .bmp files into a surface


public:
	ASprite(IDirect3DDevice9* pDevice); // Pointer to the device);


	SpriteVertex		m_SpriteVertices[NUM_SPRITE_VERTICES];
	IDirect3DSurface9*	m_pSurface;

	bool init(char *pFilename, bool isVertical = true);
	void bltSprite(POINT* pDest, bool useAlpha = true, COLOR_CODE color = COLOR_CYAN);
};
  
[edited by - The Frugal Gourmet on March 3, 2003 2:33:51 AM]

Share this post


Link to post
Share on other sites