Sign in to follow this  

Need help with texturing quads

This topic is 4101 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

I'm using Visual C++ 2003 and the DirectX 9 SDK to create a simple windows program that renders a quad in 2D. So far I've completed Tutorials 1 and 2 on MSDN for DirectX 9. Here is the code I have come up with so far: Edit: Sorry, new to the forums, didn't know about the "source" tag.
//theJ89's Direct X Test and window creation program
#include <windows.h>	//Includes windows,
#include <d3d9.h>		//D3D,
#include <dxerr9.h>		//and the D3D error handler?

//Removes rarely used things in windows.
#define WIN32_LEAN_AND_MEAN
//Describes the format of the vertex...
//Even though I make my own custom vertex structure I think it has to conform to these specifications.
#define POINT_FLAGS (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

//Width and height of the menu along with the name of my program.
#define APP_NAME "theJ89's DirectX Test Program"
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768

//Window and instance pointers
HWND window;
HINSTANCE hInst;

//Program stops running when bRun is set to false
bool bRun=true;

//Alert displays a message box with the name of the application, an "OK" button, an exclamation mark and the intended message.
void Alert(LPCTSTR lpMessage)
{
	if(window!=NULL){
		MessageBox(window,lpMessage,APP_NAME,MB_OK | MB_ICONEXCLAMATION);
	} else {
		MessageBox(NULL,lpMessage,APP_NAME,MB_OK | MB_ICONEXCLAMATION);
	}
}

//Confirm is like alert, but instead it has a question icon, yes/no buttons, and it returns the user's choice - true for yes and false for no.
bool Confirm(LPCTSTR lpMessage)
{
	int returnedValue=0;
	if(window!=NULL){
		returnedValue=MessageBox(window,lpMessage,APP_NAME,MB_YESNO | MB_ICONQUESTION);
	} else {
		returnedValue=MessageBox(NULL,lpMessage,APP_NAME,MB_YESNO | MB_ICONQUESTION);
	}
	if(returnedValue==IDYES){
		return true;
	} else {
		return false;
	}
}

//This is my vertex format, according to the second DX3D tutorial. It's got X, Y, and Z along with a reciprocol homogeneous w component and the color.
struct Vertex2D
{
	float x,y,z,rhw;
	D3DCOLOR color;
};

//This is my array of vertices, arranged like so:
/*
1----2
|  / |
| /  |
0----3
*/
Vertex2D vertices[] =
{
	{0.0f,		100.0f,	1.0f,	1.0f,	0xffffffff},
	{0.0f,		0.0f,	1.0f,	1.0f,	0xffffffff},
	{100.0f,	0.0f,	1.0f,	1.0f,	0xffffffff},
	{100.0f,	100.0f,	1.0f,	1.0f,	0xffffffff}
};

//DXGraphics is my singleton class to handle the Direct 3D interface, the device, the vertex buffer, rendering, and manage creation and cleanup.
//Currently I have the Render function set to draw a triangle fan that forms a rect as you can tell by the vertices.
class DXGraphics
{
public:
	//Constructor, makes sure all pointers are initilized to NULL
	DXGraphics()
	{
		d3d=NULL;
		d3dDevice=NULL;
		d3dVertexBuffer=NULL;
	}
	//Destructor, releases the vertex buffers, device, and d3d interface
	~DXGraphics()
	{
		if(d3dVertexBuffer!=NULL)
			d3dVertexBuffer->Release();
		if(d3dDevice!=NULL)
			d3dDevice->Release();
		if(d3d!=NULL)
			d3d->Release();
	}
	//Initilizes the interface and allows me to create the device...
	HRESULT createD3D()
	{
		if(NULL==(d3d=Direct3DCreate9(D3D_SDK_VERSION)))
		{
			Alert("Could not create Direct3D object.");
			return E_FAIL;
		}
		Alert("Successfully created Direct3D object!");
		return S_OK;
	}
	//Creates the device used to handle... um, pretty much everything.
	HRESULT createDevice()
	{
		D3DPRESENT_PARAMETERS d3dPresent;
		ZeroMemory(&d3dPresent,sizeof(d3dPresent));
		d3dPresent.Windowed=TRUE;
		d3dPresent.SwapEffect=D3DSWAPEFFECT_DISCARD;
		d3dPresent.BackBufferFormat=D3DFMT_UNKNOWN;
		
		if( FAILED( d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dPresent, &d3dDevice)))
		{
			Alert("Could not create device!");
			return S_OK;
		}
		Alert("Created device successfully!");
		return E_FAIL;
	}
	//Creates a vertex buffer for my polygons.
	HRESULT createVertexBuffer()
	{
		if( FAILED( d3dDevice->CreateVertexBuffer(4*sizeof(Vertex2D),0, POINT_FLAGS, D3DPOOL_DEFAULT, &d3dVertexBuffer, NULL ) ) )
		{
			Alert("Could not create vertex buffer!");
			return E_FAIL;
		}
		Alert("Created vertex buffer!");
		return S_OK;
	}
	//Copies the vertexes from the array in physical memory to the buffer on video memory, if I understood that correctly.
	HRESULT fillVertexBuffer()
	{
		VOID* pVertices;
		if(FAILED(d3dVertexBuffer->Lock(0,sizeof(vertices),(void**)&pVertices,0)))
		{
			Alert("Attempting to fill the vertex buffer has failed!");
			return E_FAIL;
		}
		memcpy(pVertices,vertices,sizeof(vertices));
		d3dVertexBuffer->Unlock();
		//Alert("The vertex buffer has been filled!");
		return S_OK;
	}
	//Clears the back buffer to black, starts drawing the scene, sets the stream to the buffer, sets the vertex format (I don't think it should be here but whatever works), and lastly draws the primative - a triangle fan comprised of the four vertices. From there it just ends the scene and displays it.
	void Render()
	{
		if(d3dDevice!=NULL)
		{
			d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
			if(SUCCEEDED(d3dDevice->BeginScene()))
			{
				d3dDevice->SetStreamSource(0,d3dVertexBuffer,0,sizeof(Vertex2D));
				d3dDevice->SetFVF(POINT_FLAGS);
				d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
				d3dDevice->EndScene();
			}
			d3dDevice->Present(NULL,NULL,NULL,NULL);
		}
	}
private:
	IDirect3D9* d3d;
	IDirect3DDevice9* d3dDevice;
	IDirect3DVertexBuffer9* d3dVertexBuffer;
};

//Creates the singleton object that handles Direct3D
DXGraphics dx3d;

//Message Handler for windows
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
	switch(uMessage)
	{
	case WM_DESTROY:
		bRun=false;
		break;
	case WM_LBUTTONDOWN:
		Alert("Left mouse button pressed. Goodbye!");
		bRun=false;
		break;
	/*
	case WM_PAINT:
		dx3d.Render();
		ValidateRect( hWnd, NULL );
		break;
	*/
	default:
		break;
	}
	return DefWindowProc(hWnd,uMessage,wParam,lParam);
}
//I made a function to create a window because I like having everything for this in one function.
int MakeWindow(HINSTANCE hInstance)
{
	WNDCLASSEX wc;
	wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProcedure;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = NULL;
    wc.hCursor = NULL;
    wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "DXTest";
    wc.hIconSm = NULL;

	if(!RegisterClassEx(&wc))
        return false;
	window=CreateWindowEx(NULL,"DXTest",APP_NAME,WS_CAPTION | WS_VISIBLE,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,NULL,NULL,hInstance,NULL);

	if(!window)
		return false;

	return true;
}
//Main windows function. Message loop, initilizes Direct X and renders the scene.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCommandLine, int nCommandShow)
{
	MSG msg;
	hInst=hInstance;
	MakeWindow(hInst);

	dx3d.createD3D();
	dx3d.createDevice();
	dx3d.createVertexBuffer();

	while (bRun)
    {
        //Exactly what is the difference between PeekMessage and GetMessage?
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
		//The vertex buffer is filled each frame because I used to have something that moved the vertexes one pixel each frame, and needed to refresh the buffer.
		dx3d.fillVertexBuffer();
		//Last step, render the scene with the singleton's functions.
		dx3d.Render();
	}
	return 0;
}

Now what I want to do is texture these quads. I have a 32x32 .tga that I want to use as a texture for the quad. However so far I can't find a tutorial for texturing quads using the XYZRHW vertex format... so, can somebody help me out here? [Edited by - theJ89 on September 16, 2006 9:32:24 PM]

Share this post


Link to post
Share on other sites
eeek. Can you please put large amount of code inside source tags? I am nice, so I will do it for you.




//theJ89's Direct X Test and window creation program
#include <windows.h> //Includes windows,
#include <d3d9.h> //D3D,
#include <dxerr9.h> //and the D3D error handler?

//Removes rarely used things in windows.
#define WIN32_LEAN_AND_MEAN
//Describes the format of the vertex...
//Even though I make my own custom vertex structure I think it has to conform to these specifications.
#define POINT_FLAGS (D3DFVF_XYZRHW | D3DFVF_DIFFUSE)

//Width and height of the menu along with the name of my program.
#define APP_NAME "theJ89's DirectX Test Program"
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768

//Window and instance pointers
HWND window;
HINSTANCE hInst;

//Program stops running when bRun is set to false
bool bRun=true;

//Alert displays a message box with the name of the application, an "OK" button, an exclamation mark and the intended message.
void Alert(LPCTSTR lpMessage)
{
if(window!=NULL){
MessageBox(window,lpMessage,APP_NAME,MB_OK | MB_ICONEXCLAMATION);
} else {
MessageBox(NULL,lpMessage,APP_NAME,MB_OK | MB_ICONEXCLAMATION);
}
}

//Confirm is like alert, but instead it has a question icon, yes/no buttons, and it returns the user's choice - true for yes and false for no.
bool Confirm(LPCTSTR lpMessage)
{
int returnedValue=0;
if(window!=NULL){
returnedValue=MessageBox(window,lpMessage,APP_NAME,MB_YESNO | MB_ICONQUESTION);
} else {
returnedValue=MessageBox(NULL,lpMessage,APP_NAME,MB_YESNO | MB_ICONQUESTION);
}
if(returnedValue==IDYES){
return true;
} else {
return false;
}
}

//This is my vertex format, according to the second DX3D tutorial. It's got X, Y, and Z along with a reciprocol homogeneous w component and the color.
struct Vertex2D
{
float x,y,z,rhw;
D3DCOLOR color;
};

//This is my array of vertices, arranged like so:
/*
1----2
| / |
| / |
0----3
*/

Vertex2D vertices[] =
{
{0.0f, 100.0f, 1.0f, 1.0f, 0xffffffff},
{0.0f, 0.0f, 1.0f, 1.0f, 0xffffffff},
{100.0f, 0.0f, 1.0f, 1.0f, 0xffffffff},
{100.0f, 100.0f, 1.0f, 1.0f, 0xffffffff}
};

//DXGraphics is my singleton class to handle the Direct 3D interface, the device, the vertex buffer, rendering, and manage creation and cleanup.
//Currently I have the Render function set to draw a triangle fan that forms a rect as you can tell by the vertices.
class DXGraphics
{
public:
//Constructor, makes sure all pointers are initilized to NULL
DXGraphics()
{
d3d=NULL;
d3dDevice=NULL;
d3dVertexBuffer=NULL;
}
//Destructor, releases the vertex buffers, device, and d3d interface
~DXGraphics()
{
if(d3dVertexBuffer!=NULL)
d3dVertexBuffer->Release();
if(d3dDevice!=NULL)
d3dDevice->Release();
if(d3d!=NULL)
d3d->Release();
}
//Initilizes the interface and allows me to create the device...
HRESULT createD3D()
{
if(NULL==(d3d=Direct3DCreate9(D3D_SDK_VERSION)))
{
Alert("Could not create Direct3D object.");
return E_FAIL;
}
Alert("Successfully created Direct3D object!");
return S_OK;
}
//Creates the device used to handle... um, pretty much everything.
HRESULT createDevice()
{
D3DPRESENT_PARAMETERS d3dPresent;
ZeroMemory(&d3dPresent,sizeof(d3dPresent));
d3dPresent.Windowed=TRUE;
d3dPresent.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dPresent.BackBufferFormat=D3DFMT_UNKNOWN;

if( FAILED( d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dPresent, &d3dDevice)))
{
Alert("Could not create device!");
return S_OK;
}
Alert("Created device successfully!");
return E_FAIL;
}
//Creates a vertex buffer for my polygons.
HRESULT createVertexBuffer()
{
if( FAILED( d3dDevice->CreateVertexBuffer(4*sizeof(Vertex2D),0, POINT_FLAGS, D3DPOOL_DEFAULT, &d3dVertexBuffer, NULL ) ) )
{
Alert("Could not create vertex buffer!");
return E_FAIL;
}
Alert("Created vertex buffer!");
return S_OK;
}
//Copies the vertexes from the array in physical memory to the buffer on video memory, if I understood that correctly.
HRESULT fillVertexBuffer()
{
VOID* pVertices;
if(FAILED(d3dVertexBuffer->Lock(0,sizeof(vertices),(void**)&pVertices,0)))
{
Alert("Attempting to fill the vertex buffer has failed!");
return E_FAIL;
}
memcpy(pVertices,vertices,sizeof(vertices));
d3dVertexBuffer->Unlock();
//Alert("The vertex buffer has been filled!");
return S_OK;
}
//Clears the back buffer to black, starts drawing the scene, sets the stream to the buffer, sets the vertex format (I don't think it should be here but whatever works), and lastly draws the primative - a triangle fan comprised of the four vertices. From there it just ends the scene and displays it.
void Render()
{
if(d3dDevice!=NULL)
{
d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
if(SUCCEEDED(d3dDevice->BeginScene()))
{
d3dDevice->SetStreamSource(0,d3dVertexBuffer,0,sizeof(Vertex2D));
d3dDevice->SetFVF(POINT_FLAGS);
d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
d3dDevice->EndScene();
}
d3dDevice->Present(NULL,NULL,NULL,NULL);
}
}
private:
IDirect3D9* d3d;
IDirect3DDevice9* d3dDevice;
IDirect3DVertexBuffer9* d3dVertexBuffer;
};

//Creates the singleton object that handles Direct3D
DXGraphics dx3d;

//Message Handler for windows
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
switch(uMessage)
{
case WM_DESTROY:
bRun=false;
break;
case WM_LBUTTONDOWN:
Alert("Left mouse button pressed. Goodbye!");
bRun=false;
break;
/*
case WM_PAINT:
dx3d.Render();
ValidateRect( hWnd, NULL );
break;
*/

default:
break;
}
return DefWindowProc(hWnd,uMessage,wParam,lParam);
}
//I made a function to create a window because I like having everything for this in one function.
int MakeWindow(HINSTANCE hInstance)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProcedure;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "DXTest";
wc.hIconSm = NULL;

if(!RegisterClassEx(&wc))
return false;
window=CreateWindowEx(NULL,"DXTest",APP_NAME,WS_CAPTION | WS_VISIBLE,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,NULL,NULL,hInstance,NULL);

if(!window)
return false;

return true;
}
//Main windows function. Message loop, initilizes Direct X and renders the scene.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCommandLine, int nCommandShow)
{
MSG msg;
hInst=hInstance;
MakeWindow(hInst);

dx3d.createD3D();
dx3d.createDevice();
dx3d.createVertexBuffer();

while (bRun)
{
//Exactly what is the difference between PeekMessage and GetMessage?
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//The vertex buffer is filled each frame because I used to have something that moved the vertexes one pixel each frame, and needed to refresh the buffer.
dx3d.fillVertexBuffer();
//Last step, render the scene with the singleton's functions.
dx3d.Render();
}
return 0;
}




EDIT: I also found this for you:
Texture Mapping Tutorial. I hope that works


To see how I did that, then just press the edit post button.

Share this post


Link to post
Share on other sites
Is there any way to do it using RHW? That just uses matrixes to orient the camera into a 2D view which isn't really what I was looking for.

[Edited by - theJ89 on September 16, 2006 11:21:59 PM]

Share this post


Link to post
Share on other sites
Not sure what you mean about doing it with RHW. Create your vertex format like this:


const DWORD D3DFVF_CVERTEX=(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1);

struct CVertex
{
FLOAT x,y,z,rhw;
DWORD color;
FLOAT u,v;
};


Then just assign u and v the correct texture co-ordinates when you set up the verticies for the quad.

Assuming a texture has been selected into the device before you call draw primitive, and that your rhw values are set to 1.0f, texturing will work fine.

D3DXLoadTextureFromFileEx will let you load a TGA file I believe.

This is a snippet from my 2D D3D set up code that covers the matrixy bit. Dev is the D3DDevice and W and H are the screen width and height.


void PartOfTheSetUp()
{
Dev->SetFVF(D3DFVF_CVERTEX);
Dev->SetRenderState(D3DRS_LIGHTING,FALSE);

D3DXMATRIX Ortho2D;
D3DXMATRIX Identity;

D3DXMatrixOrthoLH(&Ortho2D,FLOAT(W),FLOAT(H),0.0f,1.0f);
D3DXMatrixIdentity(&Identity);

Dev->SetTransform(D3DTS_PROJECTION,&Ortho2D);
Dev->SetTransform(D3DTS_WORLD,&Identity);
Dev->SetTransform(D3DTS_VIEW,&Identity);
}



Share this post


Link to post
Share on other sites
Quote:
Original post by EasilyConfused
Not sure what you mean about doing it with RHW. Create your vertex format like this:


const DWORD D3DFVF_CVERTEX=(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1);

struct CVertex
{
FLOAT x,y,z,rhw;
DWORD color;
FLOAT u,v;
};


Then just assign u and v the correct texture co-ordinates when you set up the verticies for the quad.

Assuming a texture has been selected into the device before you call draw primitive, and that your rhw values are set to 1.0f, texturing will work fine.

D3DXLoadTextureFromFileEx will let you load a TGA file I believe.

This is a snippet from my 2D D3D set up code that covers the matrixy bit. Dev is the D3DDevice and W and H are the screen width and height.

*** Source Snippet Removed ***


Thank you for the example, but I have finally figured out the texturing bit.

I had to disable D3DFVF_DIFFUSE because if I didn't for some reason the quads would render with dark red and black stripes.

So my next question is a two part question. The texture I am using has an alpha layer (it's a 32x32 .tga) that I want to use to hide parts of the texture (the background specifically).

So, the first question would have to be how do I set up Direct 3D to use an Alpha Operation that uses the current texture's alpha?

My second question is relatively simple. I want to use vertex color diffusion with my vertexes to change the colors of the textured quads, however when I use them strange red and black bar patterns appear on the quad instead of the given texture. How do I set up Direct 3D to render with vertex color diffusion?

Here is my current source code:

//theJ89's Direct X Test and window creation program
#include <windows.h> //Includes windows,
#include <d3d9.h> //D3D,
#include <d3dx9.h> //D3D,
#include <dxerr9.h> //and the D3D error handler?

//Removes rarely used things in windows.
#define WIN32_LEAN_AND_MEAN
//Describes the format of the vertex...
//Even though I make my own custom vertex structure I think it has to conform to these specifications.
#define POINT_FLAGS (D3DFVF_XYZRHW | D3DFVF_TEX1)

//Width and height of the menu along with the name of my program.
#define APP_NAME "theJ89's DirectX Test Program"
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768

//Window and instance pointers
HWND window;
HINSTANCE hInst;

//Program stops running when bRun is set to false
bool bRun=true;

//Alert displays a message box with the name of the application, an "OK" button, an exclamation mark and the intended message.
void Alert(LPCTSTR lpMessage)
{
if(window!=NULL){
MessageBox(window,lpMessage,APP_NAME,MB_OK | MB_ICONEXCLAMATION);
} else {
MessageBox(NULL,lpMessage,APP_NAME,MB_OK | MB_ICONEXCLAMATION);
}
}

//Confirm is like alert, but instead it has a question icon, yes/no buttons, and it returns the user's choice - true for yes and false for no.
bool Confirm(LPCTSTR lpMessage)
{
int returnedValue=0;
if(window!=NULL){
returnedValue=MessageBox(window,lpMessage,APP_NAME,MB_YESNO | MB_ICONQUESTION);
} else {
returnedValue=MessageBox(NULL,lpMessage,APP_NAME,MB_YESNO | MB_ICONQUESTION);
}
if(returnedValue==IDYES){
return true;
} else {
return false;
}
}

//This is my vertex format, according to the second DX3D tutorial. It's got X, Y, and Z along with a reciprocol homogeneous w component and the color.
struct Vertex2D
{
float x,y,z,rhw,u,v;
D3DCOLOR color;
};

//This is my array of vertices, arranged like so:
/*
1----2
| / |
| / |
0----3
*/

Vertex2D vertices[] =
{
{0.0f, 32.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0xffffffff},
{0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0xffffffff},
{32.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0xffffffff},
{32.0f, 32.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0xffffffff},
{32.0f, 32.0f, 1.0f, 1.0f, 0.0f, 1.0f, 0xff0000ff},
{32.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0xff0000ff},
{64.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0xff0000ff},
{64.0f, 32.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0xff0000ff}
};

//DXGraphics is my singleton class to handle the Direct 3D interface, the device, the vertex buffer, rendering, and manage creation and cleanup.
//Currently I have the Render function set to draw a triangle fan that forms a rect as you can tell by the vertices.
class DXGraphics
{
public:
//Constructor, makes sure all pointers are initilized to NULL
DXGraphics()
{
d3d=NULL;
d3dDevice=NULL;
d3dVertexBuffer=NULL;
}
//Destructor, releases the vertex buffers, device, and d3d interface
~DXGraphics()
{
if(d3dVertexBuffer!=NULL)
d3dVertexBuffer->Release();
if(d3dDevice!=NULL)
d3dDevice->Release();
if(d3d!=NULL)
d3d->Release();
}
//Initilizes the interface and allows me to create the device...
HRESULT createD3D()
{
if(NULL==(d3d=Direct3DCreate9(D3D_SDK_VERSION)))
{
Alert("Could not create Direct3D object.");
return E_FAIL;
}
Alert("Successfully created Direct3D object!");
return S_OK;
}
//Creates the device used to handle... um, pretty much everything.
HRESULT createDevice()
{
D3DPRESENT_PARAMETERS d3dPresent;
ZeroMemory(&d3dPresent,sizeof(d3dPresent));
d3dPresent.Windowed=TRUE;
d3dPresent.SwapEffect=D3DSWAPEFFECT_DISCARD;
d3dPresent.BackBufferFormat=D3DFMT_UNKNOWN;

if( FAILED( d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dPresent, &d3dDevice)))
{
Alert("Could not create device!");
return E_FAIL;
}
Alert("Created device successfully!");
return S_OK;
}
HRESULT loadTexture(const char* pszImgPath)
{
char* message=new char[255];
ZeroMemory(message,sizeof(message));
if(FAILED(D3DXCreateTextureFromFile(d3dDevice, pszImgPath, &d3dTexture))){
strcat(message, "Attempting to load texture ");
strcat(message, pszImgPath);
strcat(message, " has failed.");
Alert(message);
delete [] message;
return E_FAIL;
}
strcat(message, "Attempting to load texture ");
strcat(message, pszImgPath);
strcat(message, " has succeeded!");
Alert(message);
delete [] message;
return S_OK;
}
//Creates a vertex buffer for my polygons.
HRESULT createVertexBuffer()
{
if( FAILED( d3dDevice->CreateVertexBuffer(4*sizeof(Vertex2D),0, POINT_FLAGS, D3DPOOL_DEFAULT, &d3dVertexBuffer, NULL ) ) )
{
Alert("Could not create vertex buffer!");
return E_FAIL;
}
Alert("Created vertex buffer!");
return S_OK;
}
//Copies the vertexes from the array in physical memory to the buffer on video memory, if I understood that correctly.
HRESULT fillVertexBuffer()
{
VOID* pVertices;
if(FAILED(d3dVertexBuffer->Lock(0,sizeof(vertices),(void**)&pVertices,0)))
{
Alert("Attempting to fill the vertex buffer has failed!");
return E_FAIL;
}
memcpy(pVertices,vertices,sizeof(vertices));
d3dVertexBuffer->Unlock();
//Alert("The vertex buffer has been filled!");
return S_OK;
}
//Clears the back buffer to black, starts drawing the scene, sets the stream to the buffer, sets the vertex format (I don't think it should be here but whatever works), and lastly draws the primative - a triangle fan comprised of the four vertices. From there it just ends the scene and displays it.
void Render()
{
if(d3dDevice!=NULL)
{
d3dDevice->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
if(SUCCEEDED(d3dDevice->BeginScene()))
{
d3dDevice->SetTexture(0,d3dTexture);
d3dDevice->SetTextureStageState(0,D3DTSS_COLOROP,D3DTOP_SELECTARG1);
d3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1,D3DTA_TEXTURE);
d3dDevice->SetTextureStageState(0,D3DTSS_COLORARG2,D3DTA_DIFFUSE);
d3dDevice->SetTextureStageState(0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1);
d3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE);
d3dDevice->SetTextureStageState(0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE);
d3dDevice->SetStreamSource(0,d3dVertexBuffer,0,sizeof(Vertex2D));
d3dDevice->SetFVF(POINT_FLAGS);
d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,0,2);
d3dDevice->DrawPrimitive(D3DPT_TRIANGLEFAN,4,2);
d3dDevice->EndScene();
}
d3dDevice->Present(NULL,NULL,NULL,NULL);
}
}
private:
IDirect3D9* d3d;
IDirect3DDevice9* d3dDevice;
IDirect3DVertexBuffer9* d3dVertexBuffer;
IDirect3DTexture9* d3dTexture;
};

//Creates the singleton object that handles Direct3D
DXGraphics dx3d;

//Message Handler for windows
LRESULT CALLBACK WindowProcedure(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam)
{
switch(uMessage)
{
case WM_DESTROY:
bRun=false;
break;
case WM_LBUTTONDOWN:
Alert("Left mouse button pressed. Goodbye!");
bRun=false;
break;
/*
case WM_PAINT:
dx3d.Render();
ValidateRect( hWnd, NULL );
break;
*/

default:
break;
}
return DefWindowProc(hWnd,uMessage,wParam,lParam);
}
//I made a function to create a window because I like having everything for this in one function.
int MakeWindow(HINSTANCE hInstance)
{
WNDCLASSEX wc;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProcedure;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = NULL;
wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = "DXTest";
wc.hIconSm = NULL;

if(!RegisterClassEx(&wc))
return false;
window=CreateWindowEx(NULL,"DXTest",APP_NAME,WS_CAPTION | WS_VISIBLE,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,NULL,NULL,hInstance,NULL);

if(!window)
return false;

return true;
}
//Main windows function. Message loop, initilizes Direct X and renders the scene.
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCommandLine, int nCommandShow)
{
MSG msg;
hInst=hInstance;
MakeWindow(hInst);

if(FAILED(dx3d.createD3D()))
return 0;
if(FAILED(dx3d.createDevice()))
return 0;
if(FAILED(dx3d.createVertexBuffer()))
return 0;
if(FAILED(dx3d.loadTexture("tex.tga")))
return 0;

while (bRun)
{
//Exactly what is the difference between PeekMessage and GetMessage?
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
//The vertex buffer is filled each frame because I used to have something that moved the vertexes one pixel each frame, and needed to refresh the buffer.
dx3d.fillVertexBuffer();
//Last step, render the scene with the singleton's functions.
dx3d.Render();
}
return 0;
}

Share this post


Link to post
Share on other sites
Well, I've completed the alpha bit. I just had to set a few things in the device when it initilized.

But I am still having problems with D3DFVF_DIFFUSE. All but three lines of my code is exactly the same as above (only the createDevice function has changed).

How do I use vertex color with textures?

Share this post


Link to post
Share on other sites

This topic is 4101 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.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this