mirror of
https://git.do.srb2.org/STJr/UltimateZoneBuilder.git
synced 2025-02-27 22:31:23 +00:00
Implement resource cleanup for all resource types
This commit is contained in:
parent
11aa31452b
commit
e1ff5fc0da
8 changed files with 220 additions and 66 deletions
|
@ -1,14 +1,15 @@
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
#include "IndexBuffer.h"
|
#include "IndexBuffer.h"
|
||||||
|
#include "RenderDevice.h"
|
||||||
IndexBuffer::IndexBuffer()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
IndexBuffer::~IndexBuffer()
|
IndexBuffer::~IndexBuffer()
|
||||||
{
|
{
|
||||||
// To do: move mBuffer to a delete list as this might be called by a finalizer in a different thread
|
if (Device && mBuffer != 0)
|
||||||
|
{
|
||||||
|
glDeleteBuffers(1, &mBuffer);
|
||||||
|
mBuffer = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint IndexBuffer::GetBuffer()
|
GLuint IndexBuffer::GetBuffer()
|
||||||
|
@ -30,7 +31,7 @@ IndexBuffer* IndexBuffer_New()
|
||||||
|
|
||||||
void IndexBuffer_Delete(IndexBuffer* buffer)
|
void IndexBuffer_Delete(IndexBuffer* buffer)
|
||||||
{
|
{
|
||||||
//delete buffer;
|
RenderDevice::DeleteObject(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
class RenderDevice;
|
||||||
|
|
||||||
class IndexBuffer
|
class IndexBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
IndexBuffer();
|
|
||||||
~IndexBuffer();
|
~IndexBuffer();
|
||||||
|
|
||||||
GLuint GetBuffer();
|
GLuint GetBuffer();
|
||||||
|
|
||||||
|
RenderDevice* Device = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GLuint mBuffer = 0;
|
GLuint mBuffer = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -61,15 +61,23 @@ RenderDevice::~RenderDevice()
|
||||||
if (Context)
|
if (Context)
|
||||||
{
|
{
|
||||||
Context->MakeCurrent();
|
Context->MakeCurrent();
|
||||||
|
|
||||||
|
ProcessDeleteList();
|
||||||
|
|
||||||
glDeleteBuffers(1, &mStreamVertexBuffer);
|
glDeleteBuffers(1, &mStreamVertexBuffer);
|
||||||
glDeleteVertexArrays(1, &mStreamVAO);
|
glDeleteVertexArrays(1, &mStreamVAO);
|
||||||
|
|
||||||
for (auto& sharedbuf : mSharedVertexBuffers)
|
for (auto& sharedbuf : mSharedVertexBuffers)
|
||||||
{
|
{
|
||||||
|
for (VertexBuffer* buf : sharedbuf->VertexBuffers)
|
||||||
|
buf->Device = nullptr;
|
||||||
|
|
||||||
GLuint handle = sharedbuf->GetBuffer();
|
GLuint handle = sharedbuf->GetBuffer();
|
||||||
glDeleteBuffers(1, &handle);
|
glDeleteBuffers(1, &handle);
|
||||||
handle = sharedbuf->GetVAO();
|
handle = sharedbuf->GetVAO();
|
||||||
glDeleteVertexArrays(1, &handle);
|
glDeleteVertexArrays(1, &handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& it : mSamplers)
|
for (auto& it : mSamplers)
|
||||||
{
|
{
|
||||||
for (GLuint handle : it.second.WrapModes)
|
for (GLuint handle : it.second.WrapModes)
|
||||||
|
@ -78,6 +86,7 @@ RenderDevice::~RenderDevice()
|
||||||
glDeleteSamplers(1, &handle);
|
glDeleteSamplers(1, &handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mShaderManager->ReleaseResources();
|
mShaderManager->ReleaseResources();
|
||||||
Context->ClearCurrent();
|
Context->ClearCurrent();
|
||||||
}
|
}
|
||||||
|
@ -330,7 +339,7 @@ bool RenderDevice::StartRendering(bool clear, int backcolor, Texture* target, bo
|
||||||
GLuint framebuffer = 0;
|
GLuint framebuffer = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
framebuffer = target->GetFramebuffer(usedepthbuffer);
|
framebuffer = target->GetFramebuffer(this, usedepthbuffer);
|
||||||
}
|
}
|
||||||
catch (std::runtime_error& e)
|
catch (std::runtime_error& e)
|
||||||
{
|
{
|
||||||
|
@ -385,7 +394,9 @@ bool RenderDevice::FinishRendering()
|
||||||
|
|
||||||
bool RenderDevice::Present()
|
bool RenderDevice::Present()
|
||||||
{
|
{
|
||||||
|
Context->MakeCurrent();
|
||||||
Context->SwapBuffers();
|
Context->SwapBuffers();
|
||||||
|
ProcessDeleteList();
|
||||||
return CheckGLError();
|
return CheckGLError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,7 +421,7 @@ bool RenderDevice::CopyTexture(Texture* dst, CubeMapFace face)
|
||||||
GLint oldTexture = 0;
|
GLint oldTexture = 0;
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
|
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &oldTexture);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, dst->GetTexture());
|
glBindTexture(GL_TEXTURE_CUBE_MAP, dst->GetTexture(this));
|
||||||
glCopyTexSubImage2D(facegl[(int)face], 0, 0, 0, 0, 0, dst->GetWidth(), dst->GetHeight());
|
glCopyTexSubImage2D(facegl[(int)face], 0, 0, 0, 0, 0, dst->GetWidth(), dst->GetHeight());
|
||||||
if (face == CubeMapFace::NegativeZ)
|
if (face == CubeMapFace::NegativeZ)
|
||||||
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
|
||||||
|
@ -420,40 +431,94 @@ bool RenderDevice::CopyTexture(Texture* dst, CubeMapFace face)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderDevice::GarbageCollectBuffer(int size, VertexFormat format)
|
||||||
|
{
|
||||||
|
auto& sharedbuf = mSharedVertexBuffers[(int)format];
|
||||||
|
if (sharedbuf->NextPos + size <= sharedbuf->Size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GLint oldarray = 0, oldvao = 0;
|
||||||
|
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &oldarray);
|
||||||
|
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &oldvao);
|
||||||
|
|
||||||
|
int totalSize = size;
|
||||||
|
for (VertexBuffer* buf : sharedbuf->VertexBuffers)
|
||||||
|
totalSize += buf->Size;
|
||||||
|
|
||||||
|
// If buffer is only half full we only need to GC. Otherwise we also need to expand the buffer size.
|
||||||
|
int newSize = std::max(totalSize, sharedbuf->Size);
|
||||||
|
if (newSize < totalSize * 2) newSize *= 2;
|
||||||
|
|
||||||
|
std::unique_ptr<SharedVertexBuffer> old = std::move(sharedbuf);
|
||||||
|
sharedbuf.reset(new SharedVertexBuffer(format, newSize));
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, sharedbuf->GetBuffer());
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sharedbuf->Size, nullptr, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_COPY_READ_BUFFER, old->GetBuffer());
|
||||||
|
|
||||||
|
// Copy all ranges still in use to the new buffer
|
||||||
|
int stride = (format == VertexFormat::Flat ? SharedVertexBuffer::FlatStride : SharedVertexBuffer::WorldStride);
|
||||||
|
int readPos = 0;
|
||||||
|
int writePos = 0;
|
||||||
|
int copySize = 0;
|
||||||
|
for (VertexBuffer* buf : old->VertexBuffers)
|
||||||
|
{
|
||||||
|
if (buf->BufferOffset != readPos + copySize)
|
||||||
|
{
|
||||||
|
if (copySize != 0)
|
||||||
|
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_ARRAY_BUFFER, readPos, writePos, copySize);
|
||||||
|
readPos = buf->BufferOffset;
|
||||||
|
writePos += copySize;
|
||||||
|
copySize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->BufferOffset = sharedbuf->NextPos;
|
||||||
|
buf->BufferStartIndex = buf->BufferOffset / stride;
|
||||||
|
sharedbuf->NextPos += buf->Size;
|
||||||
|
copySize += buf->Size;
|
||||||
|
}
|
||||||
|
if (copySize != 0)
|
||||||
|
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_ARRAY_BUFFER, readPos, writePos, copySize);
|
||||||
|
sharedbuf->VertexBuffers.swap(old->VertexBuffers);
|
||||||
|
glBindBuffer(GL_COPY_READ_BUFFER, 0);
|
||||||
|
|
||||||
|
GLuint handle = old->GetVAO();
|
||||||
|
glDeleteVertexArrays(1, &handle);
|
||||||
|
if (handle == oldvao) oldvao = sharedbuf->GetVAO();
|
||||||
|
|
||||||
|
handle = old->GetBuffer();
|
||||||
|
glDeleteBuffers(1, &handle);
|
||||||
|
if (handle == oldarray) oldarray = sharedbuf->GetBuffer();
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, oldarray);
|
||||||
|
glBindVertexArray(oldvao);
|
||||||
|
|
||||||
|
mVertexBufferChanged = true;
|
||||||
|
mNeedApply = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool RenderDevice::SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size, VertexFormat format)
|
bool RenderDevice::SetVertexBufferData(VertexBuffer* buffer, void* data, int64_t size, VertexFormat format)
|
||||||
{
|
{
|
||||||
if (!mContextIsCurrent) Context->MakeCurrent();
|
if (!mContextIsCurrent) Context->MakeCurrent();
|
||||||
|
|
||||||
GLint oldbinding = 0;
|
if (buffer->Device)
|
||||||
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &oldbinding);
|
{
|
||||||
|
buffer->Device->mSharedVertexBuffers[(int)buffer->Format]->VertexBuffers.erase(buffer->ListIt);
|
||||||
|
buffer->Device = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
GarbageCollectBuffer(size, format);
|
||||||
|
|
||||||
auto& sharedbuf = mSharedVertexBuffers[(int)format];
|
auto& sharedbuf = mSharedVertexBuffers[(int)format];
|
||||||
if (sharedbuf->NextPos + size > sharedbuf->Size)
|
|
||||||
{
|
|
||||||
std::unique_ptr<SharedVertexBuffer> old = std::move(sharedbuf);
|
|
||||||
sharedbuf.reset(new SharedVertexBuffer(format, old->Size * 2));
|
|
||||||
sharedbuf->NextPos = old->NextPos;
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, sharedbuf->GetBuffer());
|
GLint oldbinding = 0;
|
||||||
glBufferData(GL_ARRAY_BUFFER, sharedbuf->Size, nullptr, GL_STATIC_DRAW);
|
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &oldbinding);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, sharedbuf->GetBuffer());
|
||||||
glBindBuffer(GL_COPY_READ_BUFFER, old->GetBuffer());
|
|
||||||
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_ARRAY_BUFFER, 0, 0, old->Size);
|
|
||||||
glBindBuffer(GL_COPY_READ_BUFFER, 0);
|
|
||||||
|
|
||||||
GLuint handle = old->GetBuffer();
|
|
||||||
glDeleteBuffers(1, &handle);
|
|
||||||
handle = old->GetVAO();
|
|
||||||
glDeleteVertexArrays(1, &handle);
|
|
||||||
|
|
||||||
mVertexBufferChanged = true;
|
|
||||||
mNeedApply = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, sharedbuf->GetBuffer());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
buffer->ListIt = sharedbuf->VertexBuffers.insert(sharedbuf->VertexBuffers.end(), buffer);
|
||||||
|
buffer->Device = this;
|
||||||
|
buffer->Size = size;
|
||||||
buffer->Format = format;
|
buffer->Format = format;
|
||||||
buffer->BufferOffset = sharedbuf->NextPos;
|
buffer->BufferOffset = sharedbuf->NextPos;
|
||||||
buffer->BufferStartIndex = buffer->BufferOffset / (format == VertexFormat::Flat ? SharedVertexBuffer::FlatStride : SharedVertexBuffer::WorldStride);
|
buffer->BufferStartIndex = buffer->BufferOffset / (format == VertexFormat::Flat ? SharedVertexBuffer::FlatStride : SharedVertexBuffer::WorldStride);
|
||||||
|
@ -504,7 +569,7 @@ bool RenderDevice::SetCubePixels(Texture* texture, CubeMapFace face, const void*
|
||||||
void* RenderDevice::MapPBO(Texture* texture)
|
void* RenderDevice::MapPBO(Texture* texture)
|
||||||
{
|
{
|
||||||
if (!mContextIsCurrent) Context->MakeCurrent();
|
if (!mContextIsCurrent) Context->MakeCurrent();
|
||||||
GLint pbo = texture->GetPBO();
|
GLint pbo = texture->GetPBO(this);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
|
||||||
void* buf = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
void* buf = glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
|
||||||
bool result = CheckGLError();
|
bool result = CheckGLError();
|
||||||
|
@ -519,10 +584,10 @@ void* RenderDevice::MapPBO(Texture* texture)
|
||||||
bool RenderDevice::UnmapPBO(Texture* texture)
|
bool RenderDevice::UnmapPBO(Texture* texture)
|
||||||
{
|
{
|
||||||
if (!mContextIsCurrent) Context->MakeCurrent();
|
if (!mContextIsCurrent) Context->MakeCurrent();
|
||||||
GLint pbo = texture->GetPBO();
|
GLint pbo = texture->GetPBO(this);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, pbo);
|
||||||
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture->GetTexture());
|
glBindTexture(GL_TEXTURE_2D, texture->GetTexture(this));
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->GetWidth(), texture->GetHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, texture->GetWidth(), texture->GetHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
bool result = CheckGLError();
|
bool result = CheckGLError();
|
||||||
mNeedApply = true;
|
mNeedApply = true;
|
||||||
|
@ -784,7 +849,7 @@ bool RenderDevice::ApplyTextures()
|
||||||
{
|
{
|
||||||
GLenum target = mTextureUnit.Tex->IsCubeTexture() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
GLenum target = mTextureUnit.Tex->IsCubeTexture() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
|
||||||
|
|
||||||
glBindTexture(target, mTextureUnit.Tex->GetTexture());
|
glBindTexture(target, mTextureUnit.Tex->GetTexture(this));
|
||||||
|
|
||||||
GLuint& samplerHandle = mSamplerFilter->WrapModes[(int)mTextureUnit.WrapMode];
|
GLuint& samplerHandle = mSamplerFilter->WrapModes[(int)mTextureUnit.WrapMode];
|
||||||
if (samplerHandle == 0)
|
if (samplerHandle == 0)
|
||||||
|
@ -815,6 +880,50 @@ bool RenderDevice::ApplyTextures()
|
||||||
return CheckGLError();
|
return CheckGLError();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::mutex& RenderDevice::GetMutex()
|
||||||
|
{
|
||||||
|
static std::mutex m;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderDevice::DeleteObject(VertexBuffer* buffer)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(RenderDevice::GetMutex());
|
||||||
|
if (buffer->Device)
|
||||||
|
buffer->Device->mDeleteList.VertexBuffers.push_back(buffer);
|
||||||
|
else
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderDevice::DeleteObject(IndexBuffer* buffer)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(RenderDevice::GetMutex());
|
||||||
|
if (buffer->Device)
|
||||||
|
buffer->Device->mDeleteList.IndexBuffers.push_back(buffer);
|
||||||
|
else
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderDevice::DeleteObject(Texture* texture)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(RenderDevice::GetMutex());
|
||||||
|
if (texture->Device)
|
||||||
|
texture->Device->mDeleteList.Textures.push_back(texture);
|
||||||
|
else
|
||||||
|
delete texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderDevice::ProcessDeleteList()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(RenderDevice::GetMutex());
|
||||||
|
for (auto buffer : mDeleteList.IndexBuffers) delete buffer;
|
||||||
|
for (auto buffer : mDeleteList.VertexBuffers) delete buffer;
|
||||||
|
for (auto texture : mDeleteList.Textures) delete texture;
|
||||||
|
mDeleteList.IndexBuffers.clear();
|
||||||
|
mDeleteList.VertexBuffers.clear();
|
||||||
|
mDeleteList.Textures.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "OpenGLContext.h"
|
#include "OpenGLContext.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
class SharedVertexBuffer;
|
class SharedVertexBuffer;
|
||||||
class VertexBuffer;
|
class VertexBuffer;
|
||||||
|
@ -78,6 +79,8 @@ public:
|
||||||
|
|
||||||
bool InvalidateTexture(Texture* texture);
|
bool InvalidateTexture(Texture* texture);
|
||||||
|
|
||||||
|
void GarbageCollectBuffer(int size, VertexFormat format);
|
||||||
|
|
||||||
bool ApplyViewport();
|
bool ApplyViewport();
|
||||||
bool ApplyChanges();
|
bool ApplyChanges();
|
||||||
bool ApplyVertexBuffer();
|
bool ApplyVertexBuffer();
|
||||||
|
@ -97,8 +100,22 @@ public:
|
||||||
|
|
||||||
GLint GetGLMinFilter(TextureFilter filter, TextureFilter mipfilter);
|
GLint GetGLMinFilter(TextureFilter filter, TextureFilter mipfilter);
|
||||||
|
|
||||||
|
static std::mutex& GetMutex();
|
||||||
|
static void DeleteObject(VertexBuffer* buffer);
|
||||||
|
static void DeleteObject(IndexBuffer* buffer);
|
||||||
|
static void DeleteObject(Texture* texture);
|
||||||
|
|
||||||
|
void ProcessDeleteList();
|
||||||
|
|
||||||
std::unique_ptr<IOpenGLContext> Context;
|
std::unique_ptr<IOpenGLContext> Context;
|
||||||
|
|
||||||
|
struct DeleteList
|
||||||
|
{
|
||||||
|
std::vector<VertexBuffer*> VertexBuffers;
|
||||||
|
std::vector<IndexBuffer*> IndexBuffers;
|
||||||
|
std::vector<Texture*> Textures;
|
||||||
|
} mDeleteList;
|
||||||
|
|
||||||
struct TextureUnit
|
struct TextureUnit
|
||||||
{
|
{
|
||||||
Texture* Tex = nullptr;
|
Texture* Tex = nullptr;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
|
#include "RenderDevice.h"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
Texture::Texture()
|
Texture::Texture()
|
||||||
|
@ -9,7 +10,8 @@ Texture::Texture()
|
||||||
|
|
||||||
Texture::~Texture()
|
Texture::~Texture()
|
||||||
{
|
{
|
||||||
// To do: move mTexture to a delete list as this might be called by a finalizer in a different thread
|
if (Device)
|
||||||
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture::Set2DImage(int width, int height)
|
void Texture::Set2DImage(int width, int height)
|
||||||
|
@ -48,12 +50,15 @@ void Texture::Invalidate()
|
||||||
mFramebuffer = 0;
|
mFramebuffer = 0;
|
||||||
mTexture = 0;
|
mTexture = 0;
|
||||||
mPBO = 0;
|
mPBO = 0;
|
||||||
|
Device = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint Texture::GetTexture()
|
GLuint Texture::GetTexture(RenderDevice* device)
|
||||||
{
|
{
|
||||||
if (mTexture == 0)
|
if (mTexture == 0)
|
||||||
{
|
{
|
||||||
|
Device = device;
|
||||||
|
|
||||||
GLint oldActiveTex = GL_TEXTURE0;
|
GLint oldActiveTex = GL_TEXTURE0;
|
||||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &oldActiveTex);
|
glGetIntegerv(GL_ACTIVE_TEXTURE, &oldActiveTex);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
@ -97,13 +102,13 @@ GLuint Texture::GetTexture()
|
||||||
return mTexture;
|
return mTexture;
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint Texture::GetFramebuffer(bool usedepthbuffer)
|
GLuint Texture::GetFramebuffer(RenderDevice* device, bool usedepthbuffer)
|
||||||
{
|
{
|
||||||
if (!usedepthbuffer)
|
if (!usedepthbuffer)
|
||||||
{
|
{
|
||||||
if (mFramebuffer == 0)
|
if (mFramebuffer == 0)
|
||||||
{
|
{
|
||||||
GLuint texture = GetTexture();
|
GLuint texture = GetTexture(Device);
|
||||||
glGenFramebuffers(1, &mFramebuffer);
|
glGenFramebuffers(1, &mFramebuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
||||||
|
@ -116,6 +121,8 @@ GLuint Texture::GetFramebuffer(bool usedepthbuffer)
|
||||||
{
|
{
|
||||||
if (mDepthRenderbuffer == 0)
|
if (mDepthRenderbuffer == 0)
|
||||||
{
|
{
|
||||||
|
Device = device;
|
||||||
|
|
||||||
glGenRenderbuffers(1, &mDepthRenderbuffer);
|
glGenRenderbuffers(1, &mDepthRenderbuffer);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer);
|
glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer);
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mWidth, mHeight);
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, mWidth, mHeight);
|
||||||
|
@ -124,7 +131,7 @@ GLuint Texture::GetFramebuffer(bool usedepthbuffer)
|
||||||
|
|
||||||
if (mFramebuffer == 0)
|
if (mFramebuffer == 0)
|
||||||
{
|
{
|
||||||
GLuint texture = GetTexture();
|
GLuint texture = GetTexture(Device);
|
||||||
glGenFramebuffers(1, &mFramebuffer);
|
glGenFramebuffers(1, &mFramebuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
|
||||||
|
@ -137,10 +144,12 @@ GLuint Texture::GetFramebuffer(bool usedepthbuffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint Texture::GetPBO()
|
GLuint Texture::GetPBO(RenderDevice* device)
|
||||||
{
|
{
|
||||||
if (mPBO == 0)
|
if (mPBO == 0)
|
||||||
{
|
{
|
||||||
|
Device = device;
|
||||||
|
|
||||||
glGenBuffers(1, &mPBO);
|
glGenBuffers(1, &mPBO);
|
||||||
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
|
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mPBO);
|
||||||
glBufferData(GL_PIXEL_UNPACK_BUFFER, mWidth*mHeight * 4, NULL, GL_STREAM_DRAW);
|
glBufferData(GL_PIXEL_UNPACK_BUFFER, mWidth*mHeight * 4, NULL, GL_STREAM_DRAW);
|
||||||
|
@ -161,7 +170,7 @@ Texture* Texture_New()
|
||||||
|
|
||||||
void Texture_Delete(Texture* tex)
|
void Texture_Delete(Texture* tex)
|
||||||
{
|
{
|
||||||
//delete tex;
|
RenderDevice::DeleteObject(tex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Texture_Set2DImage(Texture* handle, int width, int height)
|
void Texture_Set2DImage(Texture* handle, int width, int height)
|
||||||
|
|
|
@ -10,6 +10,8 @@ enum class CubeMapFace : int
|
||||||
NegativeZ
|
NegativeZ
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class RenderDevice;
|
||||||
|
|
||||||
class Texture
|
class Texture
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -29,9 +31,11 @@ public:
|
||||||
bool IsTextureCreated() const { return mTexture; }
|
bool IsTextureCreated() const { return mTexture; }
|
||||||
void Invalidate();
|
void Invalidate();
|
||||||
|
|
||||||
GLuint GetTexture();
|
GLuint GetTexture(RenderDevice* device);
|
||||||
GLuint GetFramebuffer(bool usedepthbuffer);
|
GLuint GetFramebuffer(RenderDevice* device, bool usedepthbuffer);
|
||||||
GLuint GetPBO();
|
GLuint GetPBO(RenderDevice* device);
|
||||||
|
|
||||||
|
RenderDevice* Device = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int mWidth = 0;
|
int mWidth = 0;
|
||||||
|
|
|
@ -2,19 +2,9 @@
|
||||||
#include "Precomp.h"
|
#include "Precomp.h"
|
||||||
#include "VertexBuffer.h"
|
#include "VertexBuffer.h"
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
|
#include "RenderDevice.h"
|
||||||
|
|
||||||
VertexBuffer::VertexBuffer()
|
SharedVertexBuffer::SharedVertexBuffer(VertexFormat format, int size) : Format(format), Size(size)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
VertexBuffer::~VertexBuffer()
|
|
||||||
{
|
|
||||||
// To do: release its slot in RenderDevice (note: this might be called by a finalizer in a different thread)
|
|
||||||
}
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
SharedVertexBuffer::SharedVertexBuffer(VertexFormat format, int64_t size) : Format(format), Size(size)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,6 +55,17 @@ void SharedVertexBuffer::SetupWorldVAO()
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
VertexBuffer::~VertexBuffer()
|
||||||
|
{
|
||||||
|
if (Device)
|
||||||
|
{
|
||||||
|
Device->mSharedVertexBuffers[(int)Format]->VertexBuffers.erase(ListIt);
|
||||||
|
Device = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ VertexBuffer* VertexBuffer_New()
|
||||||
|
|
||||||
void VertexBuffer_Delete(VertexBuffer* buffer)
|
void VertexBuffer_Delete(VertexBuffer* buffer)
|
||||||
{
|
{
|
||||||
//delete buffer;
|
RenderDevice::DeleteObject(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,26 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
enum class VertexFormat : int32_t { Flat, World };
|
enum class VertexFormat : int32_t { Flat, World };
|
||||||
|
|
||||||
|
class RenderDevice;
|
||||||
|
class VertexBuffer;
|
||||||
|
|
||||||
class SharedVertexBuffer
|
class SharedVertexBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SharedVertexBuffer(VertexFormat format, int64_t size);
|
SharedVertexBuffer(VertexFormat format, int size);
|
||||||
|
|
||||||
GLuint GetBuffer();
|
GLuint GetBuffer();
|
||||||
GLuint GetVAO();
|
GLuint GetVAO();
|
||||||
|
|
||||||
VertexFormat Format = VertexFormat::Flat;
|
VertexFormat Format = VertexFormat::Flat;
|
||||||
|
|
||||||
int64_t NextPos = 0;
|
int NextPos = 0;
|
||||||
int64_t Size = 0;
|
int Size = 0;
|
||||||
|
|
||||||
|
std::list<VertexBuffer*> VertexBuffers;
|
||||||
|
|
||||||
static const int FlatStride = 24;
|
static const int FlatStride = 24;
|
||||||
static const int WorldStride = 36;
|
static const int WorldStride = 36;
|
||||||
|
@ -29,11 +36,14 @@ private:
|
||||||
class VertexBuffer
|
class VertexBuffer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
VertexBuffer();
|
|
||||||
~VertexBuffer();
|
~VertexBuffer();
|
||||||
|
|
||||||
VertexFormat Format = VertexFormat::Flat;
|
VertexFormat Format = VertexFormat::Flat;
|
||||||
|
|
||||||
|
RenderDevice* Device = nullptr;
|
||||||
|
std::list<VertexBuffer*>::iterator ListIt;
|
||||||
|
|
||||||
int BufferOffset = 0;
|
int BufferOffset = 0;
|
||||||
int BufferStartIndex = 0;
|
int BufferStartIndex = 0;
|
||||||
|
int Size = 0;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue