⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 quademitter.h

📁 一个纹理地形渲染器
💻 H
字号:
// DirectX Quad Emitter

#pragma once

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

#include "Mathematics/Float.h"
#include "Mathematics/Vector.h"


namespace DirectX
{
    using namespace Mathematics;

    /// A simple wrapper around a dynamic vertex buffer.
    /// Emulates glBegin/glQuad/glEnd style semantics.
    /// Please note that this emitter is designed only to work with D3DFVF_XYZ format vertex streams!

    class QuadEmitter
    {
        LPDIRECT3DDEVICE9 _device;                      ///< the d3d device
        LPDIRECT3DVERTEXBUFFER9 _vertexBuffer;          ///< the dynamic vertex buffer
        LPDIRECT3DINDEXBUFFER9 _indexBuffer;            ///< the static vertex buffer with a repeated quad -> two triangles mapping for each quad
            
        Vector *_vertices;                              ///< pointer to locked vertices
        unsigned int _verticesSize;                     ///< size of vertices array (number of vertices)

        unsigned int _quadCount;                        ///< maximum number of quads that will fit into vertex buffer
        
        unsigned int _currentVertex;                    ///< current vertex in vertex buffer
        unsigned int _currentQuad;                      ///< current quad in vertex buffer

    public:

        /// default constructor.
        /// clears everything to defaults.

        QuadEmitter()
        {
            _device = 0;
            _vertexBuffer = 0;
            _indexBuffer = 0;
            _quadCount = 0;
            _vertices = 0;
            _verticesSize = 0;
            _currentQuad = 0;
            _currentVertex = 0;
        }
        
        /// initialize quad emitter.
        /// creates vertex and index buffers and prepares for rendering.
        /// note: you must initialize the quad emitter before you call any other methods!

        void initialize(LPDIRECT3DDEVICE9 device, int quads)
        {
            _device = device;

            _quadCount = quads;

            _verticesSize = quads*4;

            _currentVertex = 0;
            _currentQuad = 0;

            _device->CreateVertexBuffer((UINT)(sizeof(Vector)*_verticesSize), D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC, D3DFVF_XYZ, D3DPOOL_DEFAULT, &_vertexBuffer, 0);

		    _device->CreateIndexBuffer(2 * _quadCount * 3 * sizeof(short), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_DEFAULT, &_indexBuffer, 0);

            // build index buffer

		    unsigned short *index = 0;

		    _indexBuffer->Lock(0, 0, (VOID**)&index, 0);

            int indices = quads*6;

            int vertex = 0;
            
            for (int i=0; i<indices; i+=6)
            {
                index[i] = (unsigned short) vertex;
                index[i+1] = (unsigned short) (vertex + 1);
                index[i+2] = (unsigned short) (vertex + 2);
                index[i+3] = (unsigned short) vertex;
                index[i+4] = (unsigned short) (vertex + 2);
                index[i+5] = (unsigned short) (vertex + 3);

                vertex += 4;
            }

            _indexBuffer->Unlock();
        }

        /// release quad emitter.
        /// releases vertex and index buffers.

	    void release()
	    {
            if (_vertexBuffer)
            {
                _vertexBuffer->Release();
                _vertexBuffer = 0;
            }

            if (_indexBuffer)
            {
                _indexBuffer->Release();
                _indexBuffer = 0;
            }
	    }

        /// destructor.
        /// automatically calls release.

        ~QuadEmitter()
        {
		    release();
        }

        /// begin a stream of quads.

        void begin()
        {
            // start buffered rendering

		    _device->SetIndices(_indexBuffer);

            _device->SetStreamSource(0, _vertexBuffer, 0, sizeof(Vector));

            _vertexBuffer->Lock(0, 0, (void**)&_vertices, D3DLOCK_DISCARD);
        }

        /// emit a quad.
        /// returns a pointer to the current quad vertex for the client to fill in.
        /// you should set the vertices to make up the quad. there are four indices
        /// in the returned pointer to vertices that are valid: [0]..[3].
             
        Vector* quad()
        {
            if (_currentQuad==_quadCount) flush();

            assert(_currentVertex<_verticesSize);
            assert(_currentVertex+1<_verticesSize);
            assert(_currentVertex+2<_verticesSize);
            assert(_currentVertex+3<_verticesSize);
                   
            Vector *pointer = _vertices + _currentVertex;

            _currentVertex += 4;
            _currentQuad ++;

            return pointer;
        }

        /// end quad stream.
        /// you must call this once you have finished emitting quads.

        void end()
        {
            flush(true);

            _device->SetIndices(0);
            _device->SetStreamSource(0,0,0,0);
        }

    protected:

        /// flush quads to the renderer.
        /// this method ensures that all buffered quads are rendered.

        void flush(bool end = false)
        {
            // unlock vertex buffer

            _vertexBuffer->Unlock();

            // safety check for empty buffer

            if (_currentQuad==0) return;

            // draw primitive
            
            _device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, _currentVertex, 0, _currentQuad*2);

            // start again ...
            
            _currentVertex = 0;
            _currentQuad = 0;

            if (!end)
            {
                // lock vert buffer (discard)

                _vertexBuffer->Lock(0, 0, (void**)&_vertices, D3DLOCK_DISCARD);
            }
        }
    };
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -