00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "LampBasic.h"
00026 #include "Graphics2D/Renderer/SpriteGraphicsBuffer.h"
00027 #include "Graphics/System/LampGraphics.h"
00028 #include "Graphics/Renderer/RenderingDevice.h"
00029
00030 namespace Lamp{
00031
00032
00033
00034
00035
00036 SpriteGraphicsBuffer::SpriteGraphicsBuffer() :
00037 indexBuffer_(NULL), vertexBuffer_(NULL), vertexDeclaration_(NULL),
00038 topIndex_(0), bottomIndex_(0){
00039 LampGraphics::addDeviceObjectHolder(this);
00040 }
00041
00042
00043 SpriteGraphicsBuffer::~SpriteGraphicsBuffer(){
00044 LampGraphics::removeDeviceObjectHolder(this);
00045 SafeRelease(vertexDeclaration_);
00046 SafeRelease(vertexBuffer_);
00047 SafeRelease(indexBuffer_);
00048 }
00049
00050
00051
00052
00053 void SpriteGraphicsBuffer::request(
00054 const Point2f& minPosition, const Point2f& maxPosition,
00055 const TexCoord2& minUV, const TexCoord2& maxUV){
00056 Assert((vertexBuffer_ != NULL) && (indexBuffer_ != NULL) &&
00057 (vertexDeclaration_ != NULL));
00058 Assert(topIndex_ <= bottomIndex_);
00059
00060
00061 SpriteData* data = &dataBuffer_[bottomIndex_];
00062 data->position0.set(minPosition.x, minPosition.y, 0.f);
00063 data->uv0.set(minUV.u, minUV.v);
00064 data->position1.set(minPosition.x, maxPosition.y, 0.f);
00065 data->uv1.set(minUV.u, maxUV.v);
00066 data->position2.set(maxPosition.x, minPosition.y, 0.f);
00067 data->uv2.set(maxUV.u, minUV.v);
00068 data->position3.set(maxPosition.x, maxPosition.y, 0.f);
00069 data->uv3.set(maxUV.u, maxUV.v);
00070
00071
00072 bottomIndex_++;
00073 if(bottomIndex_ == maxSpriteCount_){ render(); }
00074 }
00075
00076
00077 void SpriteGraphicsBuffer::render(){
00078 Assert((vertexBuffer_ != NULL) && (indexBuffer_ != NULL) &&
00079 (vertexDeclaration_ != NULL));
00080 Assert(topIndex_ <= bottomIndex_);
00081
00082
00083 int spriteCount = bottomIndex_ - topIndex_;
00084 if(spriteCount == 0){ return; }
00085
00086
00087 RenderingDevice* device = RenderingDevice::getInstance();
00088 int offset = sizeof(SpriteData) * topIndex_;
00089 int size = sizeof(SpriteData) * spriteCount;
00090 u_char* address = device->lockDynamicVertexBuffer(
00091 vertexBuffer_, offset, size);
00092 std::memcpy(address, &dataBuffer_[topIndex_], size);
00093 device->unlockDynamicVertexBuffer(vertexBuffer_);
00094
00095
00096 device->drawIndexedTriangleList(0,
00097 topIndex_ * vertexPerSprite_,
00098 spriteCount * vertexPerSprite_,
00099 topIndex_ * indexPerSprite_,
00100 spriteCount * 2);
00101
00102
00103 if(bottomIndex_ == maxSpriteCount_){ topIndex_ = bottomIndex_ = 0; }
00104 else{ topIndex_ = bottomIndex_; }
00105 }
00106
00107
00108 void SpriteGraphicsBuffer::setup(){
00109 RenderingDevice* device = RenderingDevice::getInstance();
00110
00111 if(indexBuffer_ == NULL){ buildIndexBuffer(); }
00112
00113
00114 if(vertexBuffer_ == NULL){
00115 int bufferSize = vertexBufferSize_ * vertexSize_;
00116 vertexBuffer_ = device->createDynamicVertexBuffer(bufferSize);
00117 }
00118
00119
00120 if(vertexDeclaration_ == NULL){
00121 TexCoord::Type texType(TexCoord::type2);
00122 int size = device->createVertexDeclaration(
00123 &vertexDeclaration_, true, 0, 0, false, false, 1, &texType);
00124 Assert(size == vertexSize_);
00125 }
00126 Assert((vertexBuffer_ != NULL) && (indexBuffer_ != NULL) &&
00127 (vertexDeclaration_ != NULL));
00128
00129
00130 device->setIndexBuffer(indexBuffer_);
00131 device->setVertexBuffer(vertexBuffer_, vertexSize_);
00132 device->setVertexDeclaration(vertexDeclaration_);
00133 }
00134
00135
00136 void SpriteGraphicsBuffer::buildIndexBuffer(){
00137
00138 RenderingDevice* device = RenderingDevice::getInstance();
00139 int bufferSize = indexBufferSize_ * indexSize_;
00140 indexBuffer_ = device->createStaticIndexBuffer(bufferSize);
00141
00142
00143 u_short* address = (u_short*)device->lockStaticIndexBuffer(
00144 indexBuffer_, 0, bufferSize);
00145 u_short indexTable[indexPerSprite_] = { 0, 1, 2, 2, 1, 3};
00146 for(int i = 0; i < maxSpriteCount_; i++){
00147 int vertexOffset = i * vertexPerSprite_;
00148 for(int j = 0; j < indexPerSprite_; j++){
00149 (*address) = vertexOffset + indexTable[j];
00150 address++;
00151 }
00152 }
00153 device->unlockStaticIndexBuffer(indexBuffer_);
00154 }
00155
00156 }
00157