Jump to content

  • Log In with Google      Sign In   
  • Create Account


buggypixels

Member Since 16 Mar 2010
Offline Last Active Apr 16 2014 06:40 AM
-----

#4760866 DX9: Generic VertexBuffer using template

Posted by buggypixels on 18 January 2011 - 02:16 PM

I have posted the code along with some short explanations at my webset buggypixels.com
Hope you find it interesting.


#4758706 DX9: Generic VertexBuffer using template

Posted by buggypixels on 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() {
}

};



PARTNERS