123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- /**
- * Copyright (c) 2006-2017 LOVE Development Team
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event will the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Permission is granted to anyone to use this software for any purpose,
- * including commercial applications, and to alter it and redistribute it
- * freely, subject to the following restrictions:
- *
- * 1. The origin of this software must not be misrepresented; you must not
- * claim that you wrote the original software. If you use this software
- * in a product, an acknowledgment in the product documentation would be
- * appreciated but is not required.
- * 2. Altered source versions must be plainly marked as such, and must not be
- * misrepresented as being the original software.
- * 3. This notice may not be removed or altered from any source distribution.
- **/
- #include "Buffer.h"
- #include "Graphics.h"
- #include "common/Exception.h"
- namespace love
- {
- namespace graphics
- {
- Buffer::Buffer(size_t size, BufferType type, vertex::Usage usage, uint32 mapflags)
- : size(size)
- , type(type)
- , usage(usage)
- , map_flags(mapflags)
- , is_mapped(false)
- {
- }
- Buffer::~Buffer()
- {
- }
- // QuadIndices
- static const int MAX_VERTICES_PER_DRAW = LOVE_UINT16_MAX;
- static const int MAX_QUADS_PER_DRAW = MAX_VERTICES_PER_DRAW / 4;
- size_t QuadIndices::objectCount = 0;
- Buffer *QuadIndices::indexBuffer = nullptr;
- QuadIndices::QuadIndices(Graphics *gfx)
- {
- if (indexBuffer == nullptr)
- {
- size_t buffersize = sizeof(uint16) * MAX_QUADS_PER_DRAW * 6;
- indexBuffer = gfx->newBuffer(buffersize, nullptr, BUFFER_INDEX, vertex::USAGE_STATIC, 0);
- Buffer::Mapper map(*indexBuffer);
- vertex::fillIndices(vertex::TriangleIndexMode::QUADS, 0, MAX_VERTICES_PER_DRAW, (uint16 *) map.get());
- }
- objectCount++;
- }
- QuadIndices::QuadIndices(const QuadIndices &)
- {
- objectCount++;
- }
- QuadIndices &QuadIndices::operator = (const QuadIndices &)
- {
- return *this;
- }
- QuadIndices::~QuadIndices()
- {
- --objectCount;
- // Delete the buffer if we were the last living QuadIndices object.
- if (objectCount <= 0)
- {
- delete indexBuffer;
- indexBuffer = nullptr;
- }
- }
- static inline void advanceVertexOffsets(const vertex::Attributes &attributes, vertex::Buffers &buffers, int vertexcount)
- {
- // TODO: Figure out a better way to avoid touching the same buffer multiple
- // times, if multiple attributes share the buffer.
- uint32 touchedbuffers = 0;
- for (unsigned int i = 0; i < vertex::Attributes::MAX; i++)
- {
- if (!attributes.isEnabled(i))
- continue;
- auto &attrib = attributes.attribs[i];
- uint32 bufferbit = 1u << attrib.bufferindex;
- if ((touchedbuffers & bufferbit) == 0)
- {
- touchedbuffers |= bufferbit;
- buffers.info[attrib.bufferindex].offset += attrib.stride * vertexcount;
- }
- }
- }
- void QuadIndices::draw(Graphics *gfx, int quadstart, int quadcount, const vertex::Attributes &attributes, vertex::Buffers buffers, Texture *texture)
- {
- Graphics::DrawIndexedCommand cmd(&attributes, &buffers, indexBuffer);
- cmd.primitiveType = PRIMITIVE_TRIANGLES;
- cmd.indexBufferOffset = 0;
- cmd.indexType = INDEX_UINT16;
- cmd.texture = texture;
- // TODO: We can use glDrawElementsBaseVertex when supported, instead of
- // advancing the vertex offset.
- if (quadstart > 0)
- advanceVertexOffsets(attributes, buffers, quadstart * 4);
- for (int quadindex = 0; quadindex < quadcount; quadindex += MAX_QUADS_PER_DRAW)
- {
- int quaddrawcount = std::min(MAX_QUADS_PER_DRAW, quadcount - quadindex);
- if (quadindex > 0)
- advanceVertexOffsets(attributes, buffers, quaddrawcount * 4);
- cmd.indexCount = quaddrawcount * 6;
- gfx->draw(cmd);
- }
- }
- Buffer *QuadIndices::getBuffer() const
- {
- return indexBuffer;
- }
- } // graphics
- } // love
|