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

132 lines
3.0 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "OpenGL/SlateOpenGLIndexBuffer.h"
#include "Rendering/RenderingCommon.h"
#include "OpenGL/SlateOpenGLExtensions.h"
FSlateOpenGLIndexBuffer::FSlateOpenGLIndexBuffer()
: MaxNumIndices(0)
, BufferID(0)
{
}
FSlateOpenGLIndexBuffer::~FSlateOpenGLIndexBuffer()
{
DestroyBuffer();
}
/**
* Initializes the index buffers resource if needed
*/
void FSlateOpenGLIndexBuffer::ConditionalCreateBuffer()
{
// Only generate the buffer if we don't have a valid one
if( !IsValid() )
{
glGenBuffers( 1, &BufferID );
}
}
/**
* Resizes the buffer to the passed in number of indices.
* Preserves internal data
*/
void FSlateOpenGLIndexBuffer::ResizeBuffer( uint32 NumIndices )
{
// Only resize if the index buffer cant provide the number of indices requested
if( NumIndices > MaxNumIndices )
{
// Determine the current buffer size so we can save off the current indices
uint32 CurrentBufferSize = MaxNumIndices*sizeof(SlateIndex);
uint8 *SavedIndices = NULL;
// If there are any indices at all save them off now
if( MaxNumIndices > 0 )
{
void *Indices = Lock( 0 );
SavedIndices = new uint8[CurrentBufferSize];
FMemory::Memcpy( SavedIndices, Indices, CurrentBufferSize );
Unlock();
// Destroy the current buffer. It needs to be recreated with a larger size
DestroyBuffer();
}
// Calculate the new buffer size
BufferSize = NumIndices*sizeof(SlateIndex);
// Create the index buffer
ConditionalCreateBuffer();
// Bind the buffer so we can give it data
Bind();
MaxNumIndices = NumIndices;
// Set the index buffer's size
glBufferData( GL_ELEMENT_ARRAY_BUFFER, BufferSize, NULL, GL_DYNAMIC_DRAW );
// If there are any saved indices, copy them back now.
if( SavedIndices )
{
void *Indices = Lock( 0 );
FMemory::Memcpy( Indices, SavedIndices, CurrentBufferSize );
Unlock();
delete[] SavedIndices;
}
}
}
/**
* Locks the index buffer, returning a pointer to the indices
*/
void* FSlateOpenGLIndexBuffer::Lock( uint32 FirstIndex )
{
// Bind the index 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_ELEMENT_ARRAY_BUFFER, BufferSize, NULL, GL_DYNAMIC_DRAW );
void* Data = glMapBuffer( GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY );
check(Data);
uint32 Offset = FirstIndex * sizeof(SlateIndex);
return (void*)((SlateIndex*)Data + FirstIndex);
}
/**
* Unlocks the buffer. Pointers to buffer data will no longer be valid after this call
*/
void FSlateOpenGLIndexBuffer::Unlock()
{
Bind();
glUnmapBuffer( GL_ELEMENT_ARRAY_BUFFER );
}
/**
* Binds the buffer so it can be accessed
*/
void FSlateOpenGLIndexBuffer::Bind()
{
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, BufferID );
}
/**
* Releases the index buffers resource.
*/
void FSlateOpenGLIndexBuffer::DestroyBuffer()
{
if( IsValid() )
{
glDeleteBuffers( 1, &BufferID );
BufferID = 0;
}
}