Jump to content
  • Advertisement
Sign in to follow this  
solrac_pr

OpenGL Rendering from Index Buffers

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

Hello everyone! I've been trying to figure out how to render from an index buffer in Direct3D for a while now. I've been able to render geometry from vertex buffers for a while but after switching to index buffers nothing seems to render on the screen. I understand how index buffers work and all of the concepts behind them, I just don't know if I'm doing something wrong in the three steps required to make them work (creation, locking and filling in the data, and rendering with DrawIndexedPrimitive). Here's my test application (ignore the fact that it is about as crude as it can be):
#ifndef _CRENDER_APP_H_
#define _CRENDER_APP_H_

#include <windows.h>

#include <string>

#include <d3d9.h>
#include <d3dx9.h>
#include <d3dx9mesh.h>

#define RELEASE(pInterface)		{									if (pInterface)					{									pInterface->Release();			pInterface = 0;				}							}

class CRenderApp
{
public:
	struct tVertex
	{
		D3DXVECTOR3		_vPosition;
		D3DXVECTOR3		_vNormal;

		float u, v;
	};

	CRenderApp();
	~CRenderApp();

	void Initialize(const HWND& hWnd);
	void Render();
	void Shutdown();

	static const unsigned int D3DFVF_CUSTOMVERTEX;

private:
	void SetMatrices();
	void HandleInput();

	void LoadModel(const std::string& strFileName);

	IDirect3D9*					m_pDirect3d;
	IDirect3DDevice9*			m_pDevice;

	IDirect3DVertexBuffer9*		m_pBuffer;
	IDirect3DIndexBuffer9*		m_pIndexBuffer;

	IDirect3DTexture9*			m_pTexture;
	ID3DXMesh*					m_pTorus;

	tVertex*					m_pVertices;
	unsigned int*				m_pIndices;

	int							m_nNumVertices, m_nNumNormals, m_nNumIndices;

	bool						m_bWireFrame;
	float						m_fRotation;

	float						m_fCameraZ;
};

#endif



#include "RenderApp.h"

#include <assert.h>
#include <fstream>

using namespace std;

const unsigned int CRenderApp::D3DFVF_CUSTOMVERTEX(D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1);

CRenderApp::CRenderApp()
{
	m_pDirect3d =		0;
	m_pDevice =			0;

	m_pBuffer =			0;
	m_pTorus =			0;

	m_bWireFrame =		false;
	m_fRotation =		0.0f;

	m_pVertices =		0;
	m_pIndices =		0;

	m_nNumVertices =	0;
	m_nNumNormals =		0;
	m_nNumIndices =		0;

	m_fCameraZ =		-5.0f;
}

CRenderApp::~CRenderApp()
{
}

void CRenderApp::Initialize(const HWND& hWnd)
{
	// Initialize Direct3D object.
	m_pDirect3d = Direct3DCreate9(D3D_SDK_VERSION);

	assert(m_pDirect3d);

	// Setting up the presentation parameters.
	D3DPRESENT_PARAMETERS d3dpp;
	memset(&d3dpp, 0, sizeof(D3DPRESENT_PARAMETERS));

	d3dpp.Windowed =				true;
	d3dpp.BackBufferFormat =		D3DFMT_UNKNOWN;
	d3dpp.SwapEffect =				D3DSWAPEFFECT_DISCARD;

	d3dpp.EnableAutoDepthStencil =	true;
	d3dpp.AutoDepthStencilFormat =	D3DFMT_D16;

	// Creating the Direct3D device used for rendering.
	m_pDirect3d->CreateDevice(	D3DADAPTER_DEFAULT,
								D3DDEVTYPE_HAL,
								hWnd,
								D3DCREATE_HARDWARE_VERTEXPROCESSING,
								&d3dpp, &m_pDevice	);

	assert(m_pDevice);

	// Turn off back face culling.
	m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

	// Enable lighting and set the ambient light color and intensity.
	m_pDevice->SetRenderState(D3DRS_LIGHTING, true);
	m_pDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_RGBA(0, 0, 0, 255));

	// Set the material properties.
	D3DMATERIAL9 Material;
	memset(&Material, 0, sizeof(D3DMATERIAL9));

	Material.Diffuse =		D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
	Material.Ambient =		D3DXCOLOR(0.1f, 0.1f, 0.1f, 1.0f);
	Material.Specular =		D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
	Material.Power =		1000.0f;

	m_pDevice->SetMaterial(&Material);

	// Create a light and set it.
	D3DLIGHT9 Light;
	memset(&Light, 0, sizeof(D3DLIGHT9));

	Light.Type =			D3DLIGHT_DIRECTIONAL;
	Light.Direction =		D3DXVECTOR3(0.0f, 0.0f, 1.0f);
	Light.Diffuse =			D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);
	Light.Specular =		D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
	Light.Position =		D3DXVECTOR3(0.0f, 0.0f, -10.0f);

	Light.Range =			1000.0f;
	Light.Falloff =			0.0f;

	Light.Attenuation0 =	1.0f;

	m_pDevice->SetLight(0, &Light);
	m_pDevice->LightEnable(0, true);

	//m_pDevice->SetRenderState(D3DRS_SPECULARENABLE, true);

	LoadModel("model.txt");

	D3DXCreateTextureFromFileEx(m_pDevice, "Circuit_Glow.jpg", 256, 256,
								D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, D3DPOOL_DEFAULT, D3DX_DEFAULT, D3DX_DEFAULT,
								0, 0, 0, &m_pTexture);

	//m_pDevice->SetTexture(0, m_pTexture);
	//m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE );
	//m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
	//m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
	//m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE );
}

void CRenderApp::SetMatrices()
{
	// Create our world and view matrices.
	D3DXMATRIXA16 mWorld;

	D3DXMatrixRotationY(&mWorld, m_fRotation);

	D3DXVECTOR3 vEyePt(0.0f, 0.0f, m_fCameraZ);
	D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);
	D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);

	D3DXMATRIXA16 mView;
	D3DXMatrixLookAtLH(&mView, &vEyePt, &vLookatPt, &vUpVec);

	// The camera matrix is the concatenation of the world and view matrices.
	D3DXMATRIXA16 mCamera;
	D3DXMatrixMultiply(&mCamera, &mWorld, &mView);

	D3DXMatrixIdentity(&mView);

	// Set the camera's matrix and the identity view matrix.
	m_pDevice->SetTransform(D3DTS_WORLD, &mCamera);
	m_pDevice->SetTransform(D3DTS_VIEW, &mView);
	
	// Set the projection matrix.
	D3DXMATRIXA16 mProj;
	D3DXMatrixPerspectiveFovLH(&mProj, D3DX_PI / 4.0f, 1.0f, 1.0f, 100.0f);
	
	m_pDevice->SetTransform(D3DTS_PROJECTION, &mProj);
}

void CRenderApp::LoadModel(const std::string& strFileName)
{
	ifstream sInput;

	sInput.open(strFileName.c_str());

	// Read in the vertices from the ghetto file format.
	sInput >> m_nNumVertices;

	m_pVertices = new tVertex[m_nNumVertices];

	for (int i = 0; i < m_nNumVertices; ++i)
	{
		sInput	>> m_pVertices._vPosition.x
				>> m_pVertices._vPosition.y
				>> m_pVertices._vPosition.z;

		//sInput >> m_pVertices.u >> m_pVertices.v;
	}

	sInput >> m_nNumNormals;

	for (int i = 0; i < m_nNumNormals; ++i)
	{
		sInput	>> m_pVertices._vNormal.x
				>> m_pVertices._vNormal.y
				>> m_pVertices._vNormal.z;
	}

	sInput >> m_nNumIndices;

	m_pIndices = new unsigned int[m_nNumIndices];

	for (int i = 0; i < m_nNumIndices; ++i)
	{
		sInput >> m_pIndices;
	}

	sInput.close();

	m_pDevice->CreateVertexBuffer(	m_nNumVertices * sizeof(tVertex),
									0,
									D3DFVF_CUSTOMVERTEX,
									D3DPOOL_DEFAULT,
									&m_pBuffer,
									0	);

	assert(m_pBuffer);

	m_pDevice->CreateIndexBuffer(	m_nNumIndices * sizeof(unsigned int),
									0,
									D3DFMT_INDEX32,
									D3DPOOL_DEFAULT,
									&m_pIndexBuffer,
									0	);

	assert(m_pIndexBuffer);

	void* pVerts;
	m_pBuffer->Lock(0, sizeof(tVertex) * m_nNumVertices, (void**) &pVerts, 0);
	{
		memcpy(pVerts, m_pVertices, sizeof(tVertex) * m_nNumVertices);
	}
	m_pBuffer->Unlock();

	void* pIndices;
	m_pIndexBuffer->Lock(0, sizeof(unsigned int) * m_nNumIndices, (void**) &pIndices, 0);
	{
		memcpy(pIndices, m_pIndices, sizeof(unsigned int) * m_nNumIndices);
	}
	m_pIndexBuffer->Unlock();
}

void CRenderApp::HandleInput()
{
	if (GetAsyncKeyState('W'))
		m_bWireFrame = (m_bWireFrame) ? false : true;

	if (GetAsyncKeyState(VK_RIGHT))
		m_fRotation += 0.2f;
	if (GetAsyncKeyState(VK_LEFT))
		m_fRotation -= 0.2f;

	if (GetAsyncKeyState(VK_UP))
		m_fCameraZ += 0.2f;
	if (GetAsyncKeyState(VK_DOWN))
		m_fCameraZ -= 0.2f;
}

void CRenderApp::Render()
{
	HandleInput();

	m_pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

	m_pDevice->BeginScene();
	{
		SetMatrices();

		if (m_bWireFrame)
			m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
		else
			m_pDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);

		m_pDevice->SetStreamSource(0, m_pBuffer, 0, sizeof(tVertex));

		//m_pDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
		//m_pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, m_nNumVertices / 3);

		m_pDevice->SetIndices(m_pIndexBuffer);
		m_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, m_nNumVertices, 0, m_nNumIndices / 3);
	}
	m_pDevice->EndScene();

	m_pDevice->Present(0, 0, 0, 0);
}

void CRenderApp::Shutdown()
{
	delete m_pVertices;
	delete m_pIndices;

	RELEASE(m_pTexture);

	RELEASE(m_pIndexBuffer);
	RELEASE(m_pBuffer);
	
	RELEASE(m_pDevice);
	RELEASE(m_pDirect3d);
}


Thanks in advance for any suggestions. I hope to be able to get this up and running soon. I've already got an OpenGL version of my renderer working correcltly, I just need the Direct3D version to be done.

Share this post


Link to post
Share on other sites
Advertisement
I notice in your code you use an unsigned int for your indices. With the D3DFMT_INDEX32 flags you really will need an unsigned long (aka DWORD). See if changing that helps you out a bit.

Share this post


Link to post
Share on other sites
unsigned int and unsigned long are the same in Window on Intel-32.

It's more likely that the card doesn't support INDEX32, only INDEX16 (unsigned short). GeForce3 & 4 are INDEX16 only. I don't know about GeForceFX, or any ATI cards for sure.

edit: Also, why comment out the SetFVF? You still have a vertex stream that needs describing.

Share this post


Link to post
Share on other sites
Thanks a lot guys. I got it to work by switching from D3DFMT_INDEX32 to D3DFMT_INDEX16 and it works fine. I was assuming my video card supported this feature but I guess I was wrong. I'm coding on a laptop so my video card is severely limited. I'll probably have to check D3DCAPS when initializing my renderer to make sure this and all the features I want to use are available. Anyway, thanks again.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!