Files
UnrealEngine/Engine/Source/Developer/StandaloneRenderer/Private/OpenGL/SlateOpenGLVertexBuffer.cpp
2025-05-18 13:04:45 +08:00

135 lines
2.7 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "OpenGL/SlateOpenGLVertexBuffer.h"
#include "OpenGL/SlateOpenGLExtensions.h"
#include "OpenGL/SlateOpenGLRenderer.h"
FSlateOpenGLVertexBuffer::FSlateOpenGLVertexBuffer( uint32 InStride )
: BufferSize(0)
, Stride(InStride)
, BufferID(0)
{
check( InStride > 0 );
}
FSlateOpenGLVertexBuffer::~FSlateOpenGLVertexBuffer()
{
DestroyBuffer();
}
/**
* Initializes the vertex buffers resource if needed
*/
void FSlateOpenGLVertexBuffer::ConditionalCreateBuffer()
{
// Only generate the buffer if we don't have a valid one
if( !IsValid() )
{
glGenBuffers( 1, &BufferID );
}
CHECK_GL_ERRORS;
}
/**
* Releases the vertex buffers resource.
*/
void FSlateOpenGLVertexBuffer::DestroyBuffer()
{
if( IsValid() )
{
glDeleteBuffers( 1, &BufferID );
BufferID = 0;
}
}
/**
* Resizes the buffer to the passed in number of indices.
* Preserves internal data
*/
void FSlateOpenGLVertexBuffer::ResizeBuffer( uint32 NewSize )
{
ConditionalCreateBuffer();
// Only resize if the buffer cant provide the number of bytes requestd
if( NewSize > BufferSize )
{
uint8 *SavedVertices = NULL;
// If there are any indices at all save them off now
if( BufferSize > 0 )
{
void *Vertices = Lock( 0 );
SavedVertices = new uint8[BufferSize];
FMemory::Memcpy( SavedVertices, Vertices, BufferSize );
Unlock();
DestroyBuffer();
}
// Create the vertex buffer
ConditionalCreateBuffer();
// Bind the buffer so we can give it data
Bind();
// Set the vertex buffer's size
glBufferData( GL_ARRAY_BUFFER, NewSize, NULL, GL_DYNAMIC_DRAW );
// If there are any saved vertices, copy them back now.
if( SavedVertices )
{
void *Vertices = Lock( 0 );
FMemory::Memcpy( Vertices, SavedVertices, BufferSize );
Unlock();
delete[] SavedVertices;
}
BufferSize = NewSize;
}
}
/**
* Locks the vertex buffer, returning a pointer to its vertices
*/
void* FSlateOpenGLVertexBuffer::Lock( uint32 Offset )
{
// Bind the vertex buffer so we can access its data
Bind();
// Map the buffer data
// Calling glBufferData here is the same as a discard. We avoid a pipeline flush
glBufferData( GL_ARRAY_BUFFER, BufferSize, NULL, GL_DYNAMIC_DRAW );
void* Data = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );
CHECK_GL_ERRORS;
check(Data);
return (void*)((uint8*)Data + Offset);
}
/**
* Unlocks the buffer. Pointers to buffer data will no longer be valid after this call
*/
void FSlateOpenGLVertexBuffer::Unlock()
{
Bind();
glUnmapBuffer(GL_ARRAY_BUFFER);
CHECK_GL_ERRORS;
}
/**
* Binds the buffer so it can be accessed
*/
void FSlateOpenGLVertexBuffer::Bind()
{
glBindBuffer( GL_ARRAY_BUFFER, BufferID );
CHECK_GL_ERRORS;
}