Jump to content

  • Log In with Google      Sign In   
  • Create Account


buggypixels

Member Since 16 Mar 2010
Offline Last Active Today, 05:11 AM
-----

Topics I've Started

DX9: Generic VertexBuffer using template

14 January 2011 - 01:01 AM

Hi everyone,

I am trying to build a generic vertexbuffer. Generic means that I could use any kind of Vertex along a VertexDeclaration. So far I have a working version which is posted below.
The problem is the way how I copy the data to the vertex buffer. First I get a warning from the compiler. Here is the snippet:


template<class T> 
void DynamicVertexBuffer<T>::update() {
	int total = m_Vertices.size();	
	if ( total > 0 ) {		
		T* pVertices;
		HR(vertexBuffer->Lock( 0, 0, ( void** )&pVertices, 0 ));	
		for ( size_t i = 0; i < total; ++i ) {		
			m_Vertices[i]->set(pVertices);
			pVertices++;
		}
		HR(vertexBuffer->Unlock());
	}
	m_numVertices = total;
}


Basically I want the vertex buffer to have a list/vector of vertices and the update method will copy the vertices to the buffer. The warning is about this line:
T* pVertices;

Also I do not like the way how I currently handle the building of the pointer:

m_Vertices[i]->set(pVertices);

But that was the only solution I could come up with that is working.
When you search around the internet you can find a huge list of examples but they all take a slightly different approach.
For example Chad Vernon uses a method like this in his generic vertex buffer:

BOOL SetData( UINT numVertices, void *pVertices, DWORD flags = D3DLOCK_DISCARD );

So in his code the vertex buffer is not storing the data (which I would prefer). Also he uses arrays and memcopy to build the actual vertex buffer.
I would still prefer the vector/list approach.

Now here are my questions:
  • I am on the wrong track
  • Can somebody give me a hint about the compiler warning
  • Does someone has a better idea
  • Should I drop my stuff and simply take the same approach as all the others

Any feedback would be great.


Here is the entire code:
#pragma once
#include "..\dxstdafx.h"
#include "IndexBuffer.h"
#include <vector>

namespace ds {

template <class T>
class DynamicVertexBuffer {

typedef std::vector<T*> Vertices;

public:
	DynamicVertexBuffer(D3DPRIMITIVETYPE primitiveType,IDirect3DVertexDeclaration9* vertexDeclaration,const int& vertexSize,const int& maxVertices);
	~DynamicVertexBuffer();
	void addVertex(T* v);
	void clear();
	void update();

	void preRendering();
	void render(int numPrimitives);
	void postRendering();
private:
	Vertices m_Vertices;
	int m_MaxVertices;
	IDirect3DVertexDeclaration9* m_VertexDeclaration;
	LPDIRECT3DVERTEXBUFFER9 vertexBuffer;
    IndexBuffer* indexBuffer;
    UINT m_numVertices;
    int m_vertexSize;
	D3DPRIMITIVETYPE m_primitiveType;
};

template<class T> 
DynamicVertexBuffer<T>::DynamicVertexBuffer(D3DPRIMITIVETYPE primitiveType,IDirect3DVertexDeclaration9* vertexDeclaration,const int& vertexSize,const int& maxVertices) 
	: m_VertexDeclaration(vertexDeclaration) , m_vertexSize(vertexSize) , m_primitiveType(primitiveType) , m_MaxVertices(maxVertices) {
		
	IDirect3DDevice9 * pDevice = gEngine->getDevice();
	D3DPOOL pool = D3DPOOL_DEFAULT; 
	DWORD usage = D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC; 		
	LOG(logINFO) << "creating new dynamic vertext buffer - size: " << m_MaxVertices;
	HR(pDevice->CreateVertexBuffer( m_MaxVertices * vertexSize,usage,0 ,pool, &vertexBuffer, NULL ));
	indexBuffer = 0;
}

template<class T> 
DynamicVertexBuffer<T>::~DynamicVertexBuffer() {
	if( vertexBuffer ) { 
		vertexBuffer->Release(); 
		vertexBuffer = NULL; 
	} 
}

template<class T> 
void DynamicVertexBuffer<T>::addVertex(T* v) {
	m_Vertices.push_back(v);
}

template<class T> 
void DynamicVertexBuffer<T>::clear() {
	for ( size_t i = 0 ; i < m_Vertices.size(); ++i ) {
		delete m_Vertices[i];
	}
	m_Vertices.clear();
}

template<class T> 
void DynamicVertexBuffer<T>::update() {
	int total = m_Vertices.size();	
	if ( total > 0 ) {		
		T* pVertices;
		HR(vertexBuffer->Lock( 0, 0, ( void** )&pVertices, 0 ));	
		for ( size_t i = 0; i < total; ++i ) {		
			m_Vertices[i]->set(pVertices);
			pVertices++;
		}
		HR(vertexBuffer->Unlock());
	}
	m_numVertices = total;
}

template<class T> 
void DynamicVertexBuffer<T>::preRendering() {
	if ( m_numVertices > 0 ) {
		IDirect3DDevice9 * pDevice = gEngine->getDevice();
		update();
		if ( indexBuffer != 0 ) {
			indexBuffer->init();
		}
		pDevice->SetStreamSource( 0, vertexBuffer, 0, m_vertexSize ); 
		pDevice->SetVertexDeclaration(m_VertexDeclaration);
	}
}

template<class T> 
void DynamicVertexBuffer<T>::render(int numPrimitives) {
	if ( m_numVertices > 0 ) {
		IDirect3DDevice9 * pDevice = gEngine->getDevice();
		if ( indexBuffer ) {
			HR(pDevice->SetIndices( indexBuffer->getIndexBuffer() )); 
			HR(pDevice->DrawIndexedPrimitive( m_primitiveType, 0, 0, m_numVertices, 0, numPrimitives ));
			gEngine->getDrawCounter()->addIndices(indexBuffer->getSize());
			gEngine->getDrawCounter()->addPrimitives(m_numVertices);
		} 
		else {
			HR(pDevice->DrawPrimitive(m_primitiveType,0,numPrimitives));
			gEngine->getDrawCounter()->addPrimitives(m_numVertices);
		}		
	}
}

template<class T> 
void DynamicVertexBuffer<T>::postRendering() {
}

};

[DX9 C++] Picking triangles

09 August 2010 - 11:49 PM

Hi there,

I have a probably slightly simple problem.
Basically I have about 400 cubes. These cubes are all in one vertex buffer along
with the indices in an index buffer. These 400 cubes are building one big cube. The user can actually rotate the big cube.
That is working smoothly.
But now I want to select any of these cubes with my mouse.
So far I have understood that I need to calcuate a ray tracing from the mouse
position in screenspace. Of course convert this ray into world space. This is not a problem.
But how do I check which of my cubes was selected? I know the position of the cube. So I can also calculate each index in the vertex and index buffer to get the 24 vertices and 36 indices I have for each cube.
Of course I could use the indices to get the vertices belonging to one triangle. But how to continue?

PARTNERS