Skip to main content
gamedev.net
🔒 Locked

SetFVF Question

Started by HackSaw220 Sep 22, 2006 at 6:03 PM 7 replies 850+ views
Original Post
HackSaw220
HackSaw220
I've searched enough tutorials that I've come to the conclusion that making a simple textured triangle with some vertex lighting is next to impossible in DX9. Here is what I have set up: #define VERTEX_TYPE ( D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX2 ) // Setup the texture for the face if( m_pTexture ) { pCD3DInterface->g_pDevice->SetTexture( 0, m_pTexture ); } // Render the face pCD3DInterface->g_pDevice->SetFVF( VERTEX_TYPE ); pCD3DInterface->g_pDevice->SetStreamSource( 0, pVB, 0, sizeof( CVertex ) ); pCD3DInterface->g_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 ); // Reset the texture if( m_pTexture ) { pCD3DInterface->g_pDevice->SetTexture( 0, NULL ); } This is the class definition for the Vertex: #include "standard.h" #ifndef CVertex_h #define CVertex_h class CVertex { public: D3DXVECTOR3 m_Position; D3DXVECTOR3 m_Normal; D3DCOLOR m_DiffuseColor; D3DCOLOR m_SpecularColor; float m_tu, m_tv; }; #endif I had this set up once before in DX8 and the triangle list that made up a wall textured and shaded nicely as I wanted. My two textured triangles just appear as the texture does when viewing it as a jpg in MS Paint. The vertices make a floor and the normals for each vertex is (0,1,0). If anyone has any suggestions as to what I need to change please reply.
Mastaba
Mastaba
D3DFVF_TEX2 means you have 2 sets of texture coordinates.
Mastaba
Mastaba
You haven't shown how you have set up the lights and material states, so I'm at a loss. So I went off and whipped up a quick demo that draws a textured and lit mesh using the fixed function pipeline.

// TexturedLitTriangles_DX9.cpp : Defines the entry point for the application.//#include "stdafx.h"#include "TexturedLitTriangles_DX9.h"#define D3D_DEBUG_INFO#include <d3d9.h>#include <d3dx9.h>#define MAX_LOADSTRING 100// Global Variables:HINSTANCE hInst;								// current instanceTCHAR szTitle[MAX_LOADSTRING];					// The title bar textTCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name// Forward declarations of functions included in this code module:ATOM				MyRegisterClass(HINSTANCE hInstance);HWND				InitInstance(HINSTANCE, int);LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);const DWORD gVertex_FVF=D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_SPECULAR | D3DFVF_TEX1;struct Vertex{	D3DXVECTOR3	pos;	D3DXVECTOR3 normal;	D3DCOLOR	diffuse;	D3DCOLOR	specular;	D3DXVECTOR2 tex;};D3DFORMAT GetRenderTargetFormat(IDirect3D9* pd3d){	D3DDISPLAYMODE mode;	HRESULT res=pd3d->GetAdapterDisplayMode(0,&mode);	if(res!=D3D_OK)		return D3DFMT_UNKNOWN;	return mode.Format;}BOOL TestDepthStencil(IDirect3D9* pd3d, const D3DFORMAT depthstencil_format, const D3DFORMAT rendertarget_format){	HRESULT res=pd3d->CheckDepthStencilMatch(0,D3DDEVTYPE_HAL,rendertarget_format,rendertarget_format,depthstencil_format);	return (res==D3D_OK);}D3DFORMAT GetDepthStencilFormat(IDirect3D9* pd3d, const D3DFORMAT rendertarget_format){	D3DFORMAT formats[]={D3DFMT_D24S8,D3DFMT_D24X8,D3DFMT_D16,D3DFMT_UNKNOWN};	DWORD i=0;	while(formats!=D3DFMT_UNKNOWN)	{		if(TestDepthStencil(pd3d,formats,rendertarget_format))			return formats;                ++i;	}	return D3DFMT_UNKNOWN;}HRESULT CreateTexture(IDirect3DDevice9* pdev, IDirect3DTexture9** pptex){	HRESULT res=pdev->CreateTexture(128,128,1,0,D3DFMT_A8R8G8B8,D3DPOOL_MANAGED,pptex,NULL);	if(res!=D3D_OK)	{		*pptex=NULL;		return res;	}	D3DLOCKED_RECT rect;	res=(*pptex)->LockRect(0,▭,NULL,0);	if(res!=D3D_OK)	{		(*pptex)->Release();		*pptex=NULL;		return res;	}	D3DCOLOR* pbits=reinterpret_cast<D3DCOLOR*>(rect.pBits);	INT stride=rect.Pitch/sizeof(D3DCOLOR);	for(DWORD v=0;v<64;++v)	{		D3DCOLOR* p=pbits;		for(DWORD u=0;u<64;++u)			*p++=0xFFFF0000;		for(DWORD u=0;u<64;++u)			*p++=0xFFFFFFFF;		pbits+=stride;	}	for(DWORD v=0;v<64;++v)	{		D3DCOLOR* p=pbits;		for(DWORD u=0;u<64;++u)			*p++=0xFFFFFFFF;		for(DWORD u=0;u<64;++u)			*p++=0xFFFF0000;		pbits+=stride;	}	(*pptex)->UnlockRect(0);	return D3D_OK;}HRESULT CreateMesh(IDirect3DDevice9* pdev, IDirect3DVertexBuffer9** ppvbuff){	HRESULT res=pdev->CreateVertexBuffer(600*sizeof(Vertex),0,gVertex_FVF,D3DPOOL_MANAGED,ppvbuff,NULL);	if(res!=D3D_OK)	{		*ppvbuff=NULL;		return res;	}	Vertex* pbuff;	res=(*ppvbuff)->Lock(0,0,reinterpret_cast<void**>(&pbuff),0);	for(DWORD u=0;u<10;++u)	{		float x1=(static_cast<float>(u))-5.0f;		float x2=(static_cast<float>(u+1))-5.0f;		for(DWORD v=0;v<10;++v)		{			float y1=(static_cast<float>(v))-5.0f;			float y2=(static_cast<float>(v+1))-5.0f;			pbuff->pos=D3DXVECTOR3(x1,y1,0);			pbuff->normal=D3DXVECTOR3(0,0,-1);			pbuff->diffuse=0xFFFFFFFF;			pbuff->specular=0xFFFFFFFF;			pbuff->tex=D3DXVECTOR2(x1/10.0f,y1/10.0f);			pbuff++;			pbuff->pos=D3DXVECTOR3(x2,y1,0);			pbuff->normal=D3DXVECTOR3(0,0,-1);			pbuff->diffuse=0xFFFFFFFF;			pbuff->specular=0xFFFFFFFF;			pbuff->tex=D3DXVECTOR2(x2/10.0f,y1/10.0f);			pbuff++;			pbuff->pos=D3DXVECTOR3(x1,y2,0);			pbuff->normal=D3DXVECTOR3(0,0,-1);			pbuff->diffuse=0xFFFFFFFF;			pbuff->specular=0xFFFFFFFF;			pbuff->tex=D3DXVECTOR2(x1/10.0f,y2/10.0f);			pbuff++;			pbuff->pos=D3DXVECTOR3(x1,y2,0);			pbuff->normal=D3DXVECTOR3(0,0,-1);			pbuff->diffuse=0xFFFFFFFF;			pbuff->specular=0xFFFFFFFF;			pbuff->tex=D3DXVECTOR2(x1/10.0f,y2/10.0f);			pbuff++;			pbuff->pos=D3DXVECTOR3(x2,y1,0);			pbuff->normal=D3DXVECTOR3(0,0,-1);			pbuff->diffuse=0xFFFFFFFF;			pbuff->specular=0xFFFFFFFF;			pbuff->tex=D3DXVECTOR2(x2/10.0f,y1/10.0f);			pbuff++;			pbuff->pos=D3DXVECTOR3(x2,y2,0);			pbuff->normal=D3DXVECTOR3(0,0,-1);			pbuff->diffuse=0xFFFFFFFF;			pbuff->specular=0xFFFFFFFF;			pbuff->tex=D3DXVECTOR2(x2/10.0f,y2/10.0f);			pbuff++;		}	}	res=(*ppvbuff)->Unlock();	if(res!=D3D_OK)	{		(*ppvbuff)->Release();		*ppvbuff=NULL;	}	return res;}int APIENTRY _tWinMain(HINSTANCE hInstance,                     HINSTANCE hPrevInstance,                     LPTSTR    lpCmdLine,                     int       nCmdShow){	UNREFERENCED_PARAMETER(hPrevInstance);	UNREFERENCED_PARAMETER(lpCmdLine);	MSG msg={0};	HACCEL hAccelTable;	// Initialize global strings	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);	LoadString(hInstance, IDC_TEXTUREDLITTRIANGLE_DX9, szWindowClass, MAX_LOADSTRING);	MyRegisterClass(hInstance);	// Perform application initialization:	HWND hWnd=InitInstance (hInstance, nCmdShow);	if (!hWnd)		return FALSE;	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TEXTUREDLITTRIANGLE_DX9));	// setup d3d9	IDirect3D9* pd3d=Direct3DCreate9(D3D_SDK_VERSION);	if(!pd3d)		return FALSE;	IDirect3DDevice9* pdev=NULL;	D3DXMATRIX world;	D3DXMATRIX projection;	D3DXMATRIX view;	D3DPRESENT_PARAMETERS params;	D3DFORMAT depthstencil_format;	D3DFORMAT rendertarget_format;	IDirect3DTexture9* ptex=NULL;	IDirect3DVertexBuffer9* pvbuff=NULL;	D3DXVECTOR3 eye=D3DXVECTOR3(0.5f,0,-3);	D3DXVECTOR3 at=D3DXVECTOR3(0,0,0);	D3DXVECTOR3 temp=D3DXVECTOR3(-1,0,-1);	D3DXVECTOR3 up;	D3DXMatrixIdentity(&world);	D3DXMatrixPerspectiveRH(&projection,10,10*3/4,1,1000);	D3DXVec3Normalize(&up,&temp);	D3DXMatrixLookAtRH(&view,&eye,&at,&up);	D3DXVECTOR3 lightPos=D3DXVECTOR3(0,0,-1.5f);	D3DLIGHT9 light;	D3DCOLORVALUE white={1,1,1,1};	D3DCOLORVALUE gray={0.2f,0.2f,0.2f,1};	D3DCOLORVALUE black={0,0,0,1};	D3DMATERIAL9 material;	material.Ambient=white;	material.Diffuse=white;	material.Emissive=black;	material.Power=2;	material.Specular=white;	rendertarget_format=GetRenderTargetFormat(pd3d);	if(rendertarget_format==D3DFMT_UNKNOWN)		goto quit;	depthstencil_format=GetDepthStencilFormat(pd3d, rendertarget_format);	if(rendertarget_format==D3DFMT_UNKNOWN)		goto quit;	ZeroMemory(¶ms, sizeof(params));	params.Windowed=TRUE;	params.AutoDepthStencilFormat=depthstencil_format;	params.BackBufferCount=1;	params.BackBufferFormat=rendertarget_format;	params.BackBufferWidth=512;	params.BackBufferHeight=384;	params.EnableAutoDepthStencil=TRUE;	params.hDeviceWindow=hWnd;	params.MultiSampleType=D3DMULTISAMPLE_NONE;	params.PresentationInterval=D3DPRESENT_INTERVAL_DEFAULT;	params.FullScreen_RefreshRateInHz=0;	params.SwapEffect=D3DSWAPEFFECT_DISCARD;	HRESULT res=pd3d->CreateDevice(0,D3DDEVTYPE_HAL,hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&params,&pdev);	if(res!=D3D_OK)		goto quit;	res=CreateTexture(pdev, &ptex);	if(res!=D3D_OK)		goto quit;	res=CreateMesh(pdev,&pvbuff);	if(res!=D3D_OK)		goto quit;		// set fixed function matricies	pdev->SetTransform(D3DTS_WORLD,&world);	pdev->SetTransform(D3DTS_VIEW,&view);	pdev->SetTransform(D3DTS_PROJECTION,&projection);	// set the FVF to use	pdev->SetFVF(gVertex_FVF);	// set the static vertex buffer to draw	pdev->SetStreamSource(0,pvbuff,0,sizeof(Vertex));	// set material state and texture for the mesh	pdev->SetMaterial(&material);	pdev->SetTexture(0,ptex);	// turn on a light	pdev->LightEnable(0,TRUE);	// set the static properties of the light	light.Type=D3DLIGHT_POINT;	light.Diffuse=white;	light.Ambient=gray;	light.Specular=white;	light.Attenuation0=0;	light.Attenuation1=0.25;	light.Attenuation2=0;	light.Direction=D3DXVECTOR3(0,0,0);	light.Falloff=1;	light.Range=20;	// light animation parameter	float t=0;	DWORD start_tick=GetTickCount();	// Main message loop:	while(1)	{		if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))		{			if(GetMessage(&msg, NULL, 0, 0))			{				if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))				{					TranslateMessage(&msg);					DispatchMessage(&msg);				}			}			else				break;		}		else		{			DWORD end_tick=GetTickCount();			DWORD delta=end_tick-start_tick;			if(delta==0)				delta=1;			start_tick=end_tick;			t+=0.001f*static_cast<float>(delta);			lightPos.x=5*sinf(4*t);			lightPos.y=5*cosf(3*t);			light.Position=lightPos;						pdev->SetLight(0,&light);			pdev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,0xFF202040,1,0);			pdev->BeginScene();			pdev->DrawPrimitive(D3DPT_TRIANGLELIST,0,200);			pdev->EndScene();			pdev->Present(NULL,NULL,NULL,NULL);		}	}quit:	if(pvbuff)		pvbuff->Release();	if(ptex)		ptex->Release();	if(pdev)		pdev->Release();	if(pd3d)		pd3d->Release();	return (int) msg.wParam;}////  FUNCTION: MyRegisterClass()////  PURPOSE: Registers the window class.////  COMMENTS:////    This function and its usage are only necessary if you want this code//    to be compatible with Win32 systems prior to the 'RegisterClassEx'//    function that was added to Windows 95. It is important to call this function//    so that the application will get 'well formed' small icons associated//    with it.//ATOM MyRegisterClass(HINSTANCE hInstance){	WNDCLASSEX wcex;	wcex.cbSize = sizeof(WNDCLASSEX);	wcex.style			= CS_HREDRAW | CS_VREDRAW;	wcex.lpfnWndProc	= WndProc;	wcex.cbClsExtra		= 0;	wcex.cbWndExtra		= 0;	wcex.hInstance		= hInstance;	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TEXTUREDLITTRIANGLE_DX9));	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);	wcex.hbrBackground	= NULL;	wcex.lpszMenuName	= NULL;	wcex.lpszClassName	= szWindowClass;	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));	return RegisterClassEx(&wcex);}////   FUNCTION: InitInstance(HINSTANCE, int)////   PURPOSE: Saves instance handle and creates main window////   COMMENTS:////        In this function, we save the instance handle in a global variable and//        create and display the main program window.//HWND InitInstance(HINSTANCE hInstance, int nCmdShow){	HWND hWnd;	hInst = hInstance; // Store instance handle in our global variable	RECT r={0,0,512,384};	const DWORD style=WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_BORDER;	AdjustWindowRect(&r,style,FALSE);	LONG width=r.right-r.left;	LONG height=r.bottom-r.top;		hWnd = CreateWindow(szWindowClass, szTitle, style,		  CW_USEDEFAULT, 0, width, height, NULL, NULL, hInstance, NULL);   if (!hWnd)   {      return NULL;   }   ShowWindow(hWnd, nCmdShow);   UpdateWindow(hWnd);   return hWnd;}////  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)////  PURPOSE:  Processes messages for the main window.////  WM_COMMAND	- process the application menu//  WM_PAINT	- Paint the main window//  WM_DESTROY	- post a quit message and return////LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){	int wmId, wmEvent;	PAINTSTRUCT ps;	HDC hdc;	switch (message)	{	case WM_COMMAND:		wmId    = LOWORD(wParam);		wmEvent = HIWORD(wParam);		// Parse the menu selections:		switch (wmId)		{		case IDM_EXIT:			DestroyWindow(hWnd);			break;		default:			return DefWindowProc(hWnd, message, wParam, lParam);		}		break;	case WM_PAINT:		hdc = BeginPaint(hWnd, &ps);		EndPaint(hWnd, &ps);		break;	case WM_DESTROY:		PostQuitMessage(0);		break;	default:		return DefWindowProc(hWnd, message, wParam, lParam);	}	return 0;}


[Edited by - Mastaba on September 23, 2006 1:21:49 AM]
Mastaba
Mastaba
That mesh I draw is a triangle list.
HackSaw220
HackSaw220
Yah saw that after looking through your code a bit more. I see what's going on now. Thanks for your help so far. :-)

// Note to self when redering a mesh
// You can't mix textured and non-textured material type
// meshes at the same time
void CObject::RenderMesh()
{

for( int i = 0 ; i < (int)m_NumMats ; i++ )
{

// value of 1 usues textures
// value of 0 uses materials

pCD3DInterface->g_pDevice->SetMaterial(&m_pMaterials );
pCD3DInterface->g_pDevice->SetTexture( 0, m_pTextures );

// pCD3DInterface->g_pDevice->SetTexture( 1, m_pTextures);

m_pMesh->DrawSubset(i);

}
}

For some reason I can't put my texture on my walls and have it light properly. I either use solid colored walls (blue for some reason) or an unlightable texture. I'm stumped. Do I need to do all that alpha blending of textures and materials to get a correctly lighted and textured on a "wall" or "floor"?

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.