mirror of
https://github.com/love2d/love.git
synced 2026-08-17 11:00:31 +02:00
Meshes expose GraphicsBuffers, part 2
This commit is contained in:
@@ -35,21 +35,34 @@ namespace graphics
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
Buffer::Buffer(size_t size, const void *data, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags)
|
||||
: love::graphics::Buffer(size, typeflags, usage, mapflags)
|
||||
, vbo(0)
|
||||
, memoryMap(nullptr)
|
||||
, modifiedOffset(0)
|
||||
, modifiedSize(0)
|
||||
Buffer::Buffer(const Settings &settings, const void *data, size_t size)
|
||||
: love::graphics::Buffer(settings, data, size)
|
||||
{
|
||||
if (typeflags & BUFFERFLAG_VERTEX)
|
||||
mapType = BUFFER_VERTEX;
|
||||
else if (typeflags & BUFFERFLAG_INDEX)
|
||||
mapType = BUFFER_INDEX;
|
||||
else if (mapflags & BUFFERFLAG_UNIFORM)
|
||||
mapType = BUFFER_UNIFORM;
|
||||
else if (mapflags & BUFFERFLAG_SHADER_STORAGE)
|
||||
mapType = BUFFER_SHADER_STORAGE;
|
||||
initialize(data);
|
||||
}
|
||||
|
||||
Buffer::Buffer(love::graphics::Graphics *gfx, const Settings &settings, const std::vector<DataDeclaration> &format, const void *data, size_t size, size_t arraylength)
|
||||
: love::graphics::Buffer(gfx, settings, format, data, size, arraylength)
|
||||
{
|
||||
initialize(data);
|
||||
}
|
||||
|
||||
Buffer::~Buffer()
|
||||
{
|
||||
unloadVolatile();
|
||||
delete[] memoryMap;
|
||||
}
|
||||
|
||||
void Buffer::initialize(const void *data)
|
||||
{
|
||||
if (typeFlags & TYPEFLAG_VERTEX)
|
||||
mapType = BUFFERTYPE_VERTEX;
|
||||
else if (typeFlags & TYPEFLAG_INDEX)
|
||||
mapType = BUFFERTYPE_INDEX;
|
||||
else if (typeFlags & TYPEFLAG_UNIFORM)
|
||||
mapType = BUFFERTYPE_UNIFORM;
|
||||
else if (typeFlags & TYPEFLAG_SHADER_STORAGE)
|
||||
mapType = BUFFERTYPE_SHADER_STORAGE;
|
||||
|
||||
target = OpenGL::getGLBufferType(mapType);
|
||||
|
||||
@@ -72,12 +85,34 @@ Buffer::Buffer(size_t size, const void *data, BufferTypeFlags typeflags, BufferU
|
||||
}
|
||||
}
|
||||
|
||||
Buffer::~Buffer()
|
||||
bool Buffer::loadVolatile()
|
||||
{
|
||||
if (vbo != 0)
|
||||
unload();
|
||||
return load(true);
|
||||
}
|
||||
|
||||
delete[] memoryMap;
|
||||
void Buffer::unloadVolatile()
|
||||
{
|
||||
mapped = false;
|
||||
if (vbo != 0)
|
||||
gl.deleteBuffer(vbo);
|
||||
vbo = 0;
|
||||
}
|
||||
|
||||
bool Buffer::load(bool restore)
|
||||
{
|
||||
glGenBuffers(1, &vbo);
|
||||
gl.bindBuffer(mapType, vbo);
|
||||
|
||||
while (glGetError() != GL_NO_ERROR)
|
||||
/* Clear the error buffer. */;
|
||||
|
||||
// Copy the old buffer only if 'restore' was requested.
|
||||
const GLvoid *src = restore ? memoryMap : nullptr;
|
||||
|
||||
// Note that if 'src' is '0', no data will be copied.
|
||||
glBufferData(target, (GLsizeiptr) getSize(), src, OpenGL::getGLBufferUsage(getUsage()));
|
||||
|
||||
return (glGetError() == GL_NO_ERROR);
|
||||
}
|
||||
|
||||
void *Buffer::map()
|
||||
@@ -204,40 +239,6 @@ void Buffer::copyTo(size_t offset, size_t size, love::graphics::Buffer *other, s
|
||||
other->fill(otheroffset, size, memoryMap + offset);
|
||||
}
|
||||
|
||||
bool Buffer::loadVolatile()
|
||||
{
|
||||
return load(true);
|
||||
}
|
||||
|
||||
void Buffer::unloadVolatile()
|
||||
{
|
||||
unload();
|
||||
}
|
||||
|
||||
bool Buffer::load(bool restore)
|
||||
{
|
||||
glGenBuffers(1, &vbo);
|
||||
gl.bindBuffer(mapType, vbo);
|
||||
|
||||
while (glGetError() != GL_NO_ERROR)
|
||||
/* Clear the error buffer. */;
|
||||
|
||||
// Copy the old buffer only if 'restore' was requested.
|
||||
const GLvoid *src = restore ? memoryMap : nullptr;
|
||||
|
||||
// Note that if 'src' is '0', no data will be copied.
|
||||
glBufferData(target, (GLsizeiptr) getSize(), src, OpenGL::getGLBufferUsage(getUsage()));
|
||||
|
||||
return (glGetError() == GL_NO_ERROR);
|
||||
}
|
||||
|
||||
void Buffer::unload()
|
||||
{
|
||||
mapped = false;
|
||||
gl.deleteBuffer(vbo);
|
||||
vbo = 0;
|
||||
}
|
||||
|
||||
} // opengl
|
||||
} // graphics
|
||||
} // love
|
||||
|
||||
@@ -32,6 +32,9 @@ namespace love
|
||||
{
|
||||
namespace graphics
|
||||
{
|
||||
|
||||
class Graphics;
|
||||
|
||||
namespace opengl
|
||||
{
|
||||
|
||||
@@ -39,9 +42,14 @@ class Buffer final : public love::graphics::Buffer, public Volatile
|
||||
{
|
||||
public:
|
||||
|
||||
Buffer(size_t size, const void *data, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags);
|
||||
Buffer(const Settings &settings, const void *data, size_t size);
|
||||
Buffer(love::graphics::Graphics *gfx, const Settings &settings, const std::vector<DataDeclaration> &format, const void *data, size_t size, size_t arraylength);
|
||||
virtual ~Buffer();
|
||||
|
||||
// Implements Volatile.
|
||||
bool loadVolatile() override;
|
||||
void unloadVolatile() override;
|
||||
|
||||
void *map() override;
|
||||
void unmap() override;
|
||||
void setMappedRangeModified(size_t offset, size_t size) override;
|
||||
@@ -50,29 +58,26 @@ public:
|
||||
|
||||
void copyTo(size_t offset, size_t size, love::graphics::Buffer *other, size_t otheroffset) override;
|
||||
|
||||
// Implements Volatile.
|
||||
bool loadVolatile() override;
|
||||
void unloadVolatile() override;
|
||||
|
||||
private:
|
||||
|
||||
void initialize(const void *data);
|
||||
|
||||
bool load(bool restore);
|
||||
void unload();
|
||||
|
||||
void unmapStatic(size_t offset, size_t size);
|
||||
void unmapStream();
|
||||
|
||||
BufferType mapType;
|
||||
GLenum target;
|
||||
BufferType mapType = BUFFERTYPE_VERTEX;
|
||||
GLenum target = 0;
|
||||
|
||||
// The VBO identifier. Assigned by OpenGL.
|
||||
GLuint vbo;
|
||||
GLuint vbo = 0;
|
||||
|
||||
// A pointer to mapped memory.
|
||||
char *memoryMap;
|
||||
char *memoryMap = nullptr;
|
||||
|
||||
size_t modifiedOffset;
|
||||
size_t modifiedSize;
|
||||
size_t modifiedOffset = 0;
|
||||
size_t modifiedSize = 0;
|
||||
|
||||
}; // Buffer
|
||||
|
||||
|
||||
@@ -155,15 +155,14 @@ love::graphics::Shader *Graphics::newShaderInternal(love::graphics::ShaderStage
|
||||
return new Shader(vertex, pixel);
|
||||
}
|
||||
|
||||
love::graphics::Buffer *Graphics::newBuffer(size_t size, const void *data, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags)
|
||||
love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const void *data, size_t size)
|
||||
{
|
||||
return new Buffer(size, data, typeflags, usage, mapflags);
|
||||
return new Buffer(settings, data, size);
|
||||
}
|
||||
|
||||
love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataMember> &format, size_t arraylength)
|
||||
love::graphics::Buffer *Graphics::newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength)
|
||||
{
|
||||
// TODO
|
||||
return nullptr;
|
||||
return new Buffer(this, settings, format, data, size, arraylength);
|
||||
}
|
||||
|
||||
void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight)
|
||||
@@ -254,9 +253,9 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b
|
||||
{
|
||||
// Initial sizes that should be good enough for most cases. It will
|
||||
// resize to fit if needed, later.
|
||||
streamBufferState.vb[0] = CreateStreamBuffer(BUFFER_VERTEX, 1024 * 1024 * 1);
|
||||
streamBufferState.vb[1] = CreateStreamBuffer(BUFFER_VERTEX, 256 * 1024 * 1);
|
||||
streamBufferState.indexBuffer = CreateStreamBuffer(BUFFER_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
|
||||
streamBufferState.vb[0] = CreateStreamBuffer(BUFFERTYPE_VERTEX, 1024 * 1024 * 1);
|
||||
streamBufferState.vb[1] = CreateStreamBuffer(BUFFERTYPE_VERTEX, 256 * 1024 * 1);
|
||||
streamBufferState.indexBuffer = CreateStreamBuffer(BUFFERTYPE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX);
|
||||
}
|
||||
|
||||
// Reload all volatile objects.
|
||||
@@ -375,7 +374,7 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
|
||||
GLenum glprimitivetype = OpenGL::getGLPrimitiveType(cmd.primitiveType);
|
||||
GLenum gldatatype = OpenGL::getGLIndexDataType(cmd.indexType);
|
||||
|
||||
gl.bindBuffer(BUFFER_INDEX, cmd.indexBuffer->getHandle());
|
||||
gl.bindBuffer(BUFFERTYPE_INDEX, cmd.indexBuffer->getHandle());
|
||||
|
||||
if (cmd.instanceCount > 1)
|
||||
glDrawElementsInstanced(glprimitivetype, cmd.indexCount, gldatatype, gloffset, cmd.instanceCount);
|
||||
@@ -417,7 +416,7 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes &attribute
|
||||
gl.bindTextureToUnit(texture, 0, false);
|
||||
gl.setCullMode(CULL_NONE);
|
||||
|
||||
gl.bindBuffer(BUFFER_INDEX, quadIndexBuffer->getHandle());
|
||||
gl.bindBuffer(BUFFERTYPE_INDEX, quadIndexBuffer->getHandle());
|
||||
|
||||
if (gl.isBaseVertexSupported())
|
||||
{
|
||||
|
||||
@@ -63,8 +63,8 @@ public:
|
||||
love::graphics::Image *newImage(const Image::Slices &data, const Image::Settings &settings) override;
|
||||
love::graphics::Image *newImage(TextureType textype, PixelFormat format, int width, int height, int slices, const Image::Settings &settings) override;
|
||||
love::graphics::Canvas *newCanvas(const Canvas::Settings &settings) override;
|
||||
love::graphics::Buffer *newBuffer(size_t size, const void *data, BufferTypeFlags typeflags, BufferUsage usage, uint32 mapflags) override;
|
||||
love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataMember> &format, size_t arraylength) override;
|
||||
love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const void *data, size_t size) override;
|
||||
love::graphics::Buffer *newBuffer(const Buffer::Settings &settings, const std::vector<Buffer::DataDeclaration> &format, const void *data, size_t size, size_t arraylength) override;
|
||||
|
||||
void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override;
|
||||
bool setMode(int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil) override;
|
||||
|
||||
@@ -223,7 +223,7 @@ void OpenGL::setupContext()
|
||||
glGetIntegerv(GL_CULL_FACE_MODE, &faceCull);
|
||||
state.faceCullMode = faceCull;
|
||||
|
||||
for (int i = 0; i < (int) BUFFER_MAX_ENUM; i++)
|
||||
for (int i = 0; i < (int) BUFFERTYPE_MAX_ENUM; i++)
|
||||
{
|
||||
state.boundBuffers[i] = 0;
|
||||
glBindBuffer(getGLBufferType((BufferType) i), 0);
|
||||
@@ -584,15 +584,15 @@ GLenum OpenGL::getGLBufferType(BufferType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case BUFFER_VERTEX:
|
||||
case BUFFERTYPE_VERTEX:
|
||||
return GL_ARRAY_BUFFER;
|
||||
case BUFFER_INDEX:
|
||||
case BUFFERTYPE_INDEX:
|
||||
return GL_ELEMENT_ARRAY_BUFFER;
|
||||
case BUFFER_UNIFORM:
|
||||
case BUFFERTYPE_UNIFORM:
|
||||
return GL_UNIFORM_BUFFER;
|
||||
case BUFFER_SHADER_STORAGE:
|
||||
case BUFFERTYPE_SHADER_STORAGE:
|
||||
return GL_SHADER_STORAGE_BUFFER;
|
||||
case BUFFER_MAX_ENUM:
|
||||
case BUFFERTYPE_MAX_ENUM:
|
||||
return GL_ZERO;
|
||||
}
|
||||
|
||||
@@ -717,10 +717,6 @@ GLenum OpenGL::getGLVertexDataType(DataFormat format, int &components, GLboolean
|
||||
intformat = true;
|
||||
return GL_UNSIGNED_BYTE;
|
||||
|
||||
case DATAFORMAT_SNORM16:
|
||||
components = 1;
|
||||
normalized = GL_TRUE;
|
||||
return GL_SHORT;
|
||||
case DATAFORMAT_SNORM16_VEC2:
|
||||
components = 2;
|
||||
normalized = GL_TRUE;
|
||||
@@ -730,10 +726,6 @@ GLenum OpenGL::getGLVertexDataType(DataFormat format, int &components, GLboolean
|
||||
normalized = GL_TRUE;
|
||||
return GL_BYTE;
|
||||
|
||||
case DATAFORMAT_UNORM16:
|
||||
components = 1;
|
||||
normalized = GL_TRUE;
|
||||
return GL_UNSIGNED_SHORT;
|
||||
case DATAFORMAT_UNORM16_VEC2:
|
||||
components = 2;
|
||||
normalized = GL_TRUE;
|
||||
@@ -743,10 +735,6 @@ GLenum OpenGL::getGLVertexDataType(DataFormat format, int &components, GLboolean
|
||||
normalized = GL_TRUE;
|
||||
return GL_UNSIGNED_SHORT;
|
||||
|
||||
case DATAFORMAT_INT16:
|
||||
components = 1;
|
||||
intformat = true;
|
||||
return GL_SHORT;
|
||||
case DATAFORMAT_INT16_VEC2:
|
||||
components = 2;
|
||||
intformat = true;
|
||||
@@ -810,7 +798,7 @@ void OpenGL::deleteBuffer(GLuint buffer)
|
||||
{
|
||||
glDeleteBuffers(1, &buffer);
|
||||
|
||||
for (int i = 0; i < (int) BUFFER_MAX_ENUM; i++)
|
||||
for (int i = 0; i < (int) BUFFERTYPE_MAX_ENUM; i++)
|
||||
{
|
||||
if (state.boundBuffers[i] == buffer)
|
||||
state.boundBuffers[i] = 0;
|
||||
@@ -857,7 +845,7 @@ void OpenGL::setVertexAttributes(const VertexAttributes &attributes, const Buffe
|
||||
|
||||
const void *offsetpointer = reinterpret_cast<void*>(bufferinfo.offset + attrib.offsetFromVertex);
|
||||
|
||||
bindBuffer(BUFFER_VERTEX, (GLuint) bufferinfo.buffer->getHandle());
|
||||
bindBuffer(BUFFERTYPE_VERTEX, (GLuint) bufferinfo.buffer->getHandle());
|
||||
|
||||
if (intformat)
|
||||
glVertexAttribIPointer(i, components, gltype, layout.stride, offsetpointer);
|
||||
|
||||
@@ -453,7 +453,7 @@ private:
|
||||
// Tracked OpenGL state.
|
||||
struct
|
||||
{
|
||||
GLuint boundBuffers[BUFFER_MAX_ENUM];
|
||||
GLuint boundBuffers[BUFFERTYPE_MAX_ENUM];
|
||||
|
||||
// Texture unit state (currently bound texture for each texture unit.)
|
||||
std::vector<GLuint> boundTextures[TEXTURE_MAX_ENUM];
|
||||
|
||||
Reference in New Issue
Block a user