This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Vertex Buffer Class Submitted by

This is a class that I use to quickly make, compile and use vertex buffers in Direct3D. It's fairly simplistic but that's what I like about it. Hopefully I weeded out everything specific to my code base, but if not ... I'm sure we'll cover it in the thread below. The first file (D3DVertex.h) is my class for holding Direct3D vertices. This is what I feed into the vertex buffer class. The second file (TVertexBuffer.h) is the vertex buffer class. It's templated, so if you want to use a different kind of vertex, you can (I do this when I create vertex buffers of 2D vertices for HUD graphics and text). The "D3DDevice" variable used in the "Create" should be a pointer to a valid Direct3D device. The vertex buffer class derives from STL vector because this seemed like a handy way to do it. I could feed vertices into this object and then tell it to make a vertex buffer out of it's contents. It's worked well so far. To use the class, you do something like this to create the vertex buffer:

    TVertexBuffer<FD3DVertex VB;

    VB.SetPrimType( D3DPT_TRIANGLELIST );

    VB.push_back( FD3DVertex( D3DXVECTOR3( 0.f, 0.f, 0.f ),
                              D3DXVECTOR3( 0.f, 0.f, 0.f ),
                              D3DCOLOR_XRGB(255,255,255), 1.f, 1.f ) );
    VB.push_back( FD3DVertex( D3DXVECTOR3( 0.f, 0.f, 0.f ),
                              D3DXVECTOR3( 0.f, 0.f, 0.f ),
                              D3DCOLOR_XRGB(255,255,255), 1.f, 1.f ) );
    .
    .
    .
    VB.push_back( FD3DVertex( D3DXVECTOR3( 0.f, 0.f, 0.f ),
                              D3DXVECTOR3( 0.f, 0.f, 0.f ),
                              D3DCOLOR_XRGB(255,255,255), 1.f, 1.f ) );

    VB.Create(0);
    VB.Upload();

... except of course, you'll be feeding vertices with real data in them. You can see what the parameters mean in the definition for FD3DVertex in D3DVertex.h. To draw the vertex buffer (assuming successful compilation), you do something like this:

    D3DDevice-SetStreamSource( 0, VB.VertexBuffer, VB.GetVertexSize() );
    D3DDevice-SetVertexShader( VB.GetFVF() );
    D3DDevice-DrawPrimitive( VB.PrimType, 0, VB.GetPrimCount() );

You should also set a texture, but that's something you can figure out on your own. You can render the vertex buffer as many times as you want, as long as the vertices don't change. If they do, you'll need to Release and Create/Upload the vertex buffer again. When the object destructs it will release the vertex buffer and clear it's vertex array. Be gentle. ;)

Currently browsing [vertbuffer.zip] (1,256 bytes) - [TVertexBuffer.h] - (1,758 bytes)

    #pragma once

    template<class T> class TVertexBuffer : public vector<T>
    {
    public:
    	TVertexBuffer()
    	{
    		VertexBuffer = NULL;
    	}
    	virtual ~TVertexBuffer()
    	{
    		clear();
    		Release();
    	}

    	// InSize is the maximum size the vertex buffer will ever grow to.  Leaving it at zero will create a vertex buffer at this arrays current size.
    	// Setting InSize to something larger than zero allows you to pad the vertex buffer.
    	virtual bool Create( int InSize )
    	{
    		if( !InSize )	InSize = size();
    		if( !InSize )	return 1;

    		HRESULT hr = D3DDevice->CreateVertexBuffer( InSize*GetVertexSize(), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, GetFVF(), D3DPOOL_DEFAULT, &VertexBuffer );
    		return (hr == D3D_OK);
    	}
    	virtual bool Upload()
    	{
    		if( !size() )	return 1;

    		VOID* Buffer;
    		 VertexBuffer->Lock( 0, size()*GetVertexSize(), (byte**)&Buffer, D3DLOCK_DISCARD );
    		::memcpy( (T*)Buffer, begin(), size()*GetVertexSize() );
    		VertexBuffer->Unlock();

    		return 1;
    	}
    	virtual void Release()
    	{
    		if( VertexBuffer )
    			VertexBuffer->Release();
    		VertexBuffer = NULL;
    	}

    	inline int GetVertexSize()
    	{
    		return sizeof(T);
    	}
    	inline DWORD GetFVF()
    	{
    		return T::FVF;
    	}
    	void SetPrimType( D3DPRIMITIVETYPE InPrimType )
    	{
    		PrimType = InPrimType;
    	}
    	virtual int GetPrimCount()
    	{
    		switch( PrimType )
    		{
    			case D3DPT_TRIANGLELIST:	return size()/3;
    			case D3DPT_TRIANGLEFAN:		return size()-2;
    			case D3DPT_TRIANGLESTRIP:	return size()-2;
    			case D3DPT_LINESTRIP:		return size()-1;
    			case D3DPT_LINELIST:		return size()/2;
    			case D3DPT_POINTLIST:		return size();
    		}

    		_ASSERT(0);	// Unknown primitive type
    		return 0;
    	}

    	LPDIRECT3DVERTEXBUFFER8 VertexBuffer;
    	D3DPRIMITIVETYPE PrimType;
    };

Currently browsing [vertbuffer.zip] (1,256 bytes) - [D3DVertex.h] - (503 bytes)

    class FD3DVertex
    {
    public:
    	enum {FVF=D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL | D3DFVF_TEX1};

    	FD3DVertex()
    	{}
    	FD3DVertex( D3DXVECTOR3 InVtx, D3DXVECTOR3 InNormal, DWORD InColor, float InS, float InT )
    		: X(InVtx.x), Y(InVtx.y), Z(InVtx.z), Nx(InNormal.x), Ny(InNormal.y), Nz(InNormal.z), Diffuse(InColor), S(InS), T(InT)
    	{
    	}

        float X, Y, Z;		// position
        float Nx, Ny, Nz;	// normal
        DWORD Diffuse;		// diffuse color
        float S, T;			// texture coordinates
    };

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.