- model vertex buffer converted.

This commit is contained in:
Christoph Oelckers 2018-10-27 16:59:13 +02:00
parent 5201501534
commit cd8c7a17eb
5 changed files with 50 additions and 95 deletions

View File

@ -95,26 +95,6 @@ public:
void BindVBO(); void BindVBO();
}; };
class FModelVertexBuffer : public FVertexBuffer, public IModelVertexBuffer
{
int mIndexFrame[2];
FModelVertex *vbo_ptr;
uint32_t ibo_id;
public:
FModelVertexBuffer(bool needindex, bool singleframe);
~FModelVertexBuffer();
FModelVertex *LockVertexBuffer(unsigned int size) override;
void UnlockVertexBuffer() override;
unsigned int *LockIndexBuffer(unsigned int size) override;
void UnlockIndexBuffer() override;
void SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) override;
void BindVBO() override;
};
#define VSO ((FSkyVertex*)NULL) #define VSO ((FSkyVertex*)NULL)

View File

@ -35,6 +35,7 @@
#include "d_player.h" #include "d_player.h"
#include "g_levellocals.h" #include "g_levellocals.h"
#include "i_time.h" #include "i_time.h"
#include "cmdlib.h"
#include "hwrenderer/textures/hw_material.h" #include "hwrenderer/textures/hw_material.h"
#include "gl_load/gl_interface.h" #include "gl_load/gl_interface.h"
@ -113,7 +114,7 @@ IModelVertexBuffer *FGLModelRenderer::CreateVertexBuffer(bool needindex, bool si
void FGLModelRenderer::SetVertexBuffer(IModelVertexBuffer *buffer) void FGLModelRenderer::SetVertexBuffer(IModelVertexBuffer *buffer)
{ {
gl_RenderState.SetVertexBuffer((FModelVertexBuffer*)buffer); static_cast<FModelVertexBuffer*>(buffer)->Bind(gl_RenderState);
} }
void FGLModelRenderer::ResetVertexBuffer() void FGLModelRenderer::ResetVertexBuffer()
@ -146,23 +147,22 @@ void FGLModelRenderer::DrawElements(int numIndices, size_t offset)
//=========================================================================== //===========================================================================
// //
// Uses a hardware buffer if either single frame (i.e. no interpolation needed)
// or shading is available (interpolation is done by the vertex shader)
// //
// If interpolation has to be done on the CPU side this will fall back
// to CPU-side arrays.
// //
//=========================================================================== //===========================================================================
FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe) FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe)
: FVertexBuffer(true)
{ {
vbo_ptr = nullptr; mVertexBuffer = screen->CreateVertexBuffer();
ibo_id = 0; mIndexBuffer = needindex ? screen->CreateIndexBuffer() : nullptr;
if (needindex)
{ static const FVertexBufferAttribute format[] = {
glGenBuffers(1, &ibo_id); // The index buffer can always be a real buffer. { 0, VATTR_VERTEX, VFmt_Float3, myoffsetof(FModelVertex, x) },
} { 0, VATTR_TEXCOORD, VFmt_Float2, myoffsetof(FModelVertex, u) },
{ 0, VATTR_NORMAL, VFmt_Packed_A2R10G10B10, myoffsetof(FModelVertex, packedNormal) },
{ 0, VATTR_VERTEX2, VFmt_Float3, myoffsetof(FModelVertex, x) }
};
mVertexBuffer->SetFormat(2, 4, sizeof(FModelVertex), format);
} }
//=========================================================================== //===========================================================================
@ -171,15 +171,10 @@ FModelVertexBuffer::FModelVertexBuffer(bool needindex, bool singleframe)
// //
//=========================================================================== //===========================================================================
void FModelVertexBuffer::BindVBO() void FModelVertexBuffer::Bind(FRenderState &state)
{ {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); state.SetVertexBuffer(mVertexBuffer, mIndexFrame[0], mIndexFrame[1]);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); if (mIndexBuffer) state.SetIndexBuffer(mIndexBuffer);
glEnableVertexAttribArray(VATTR_VERTEX);
glEnableVertexAttribArray(VATTR_TEXCOORD);
glEnableVertexAttribArray(VATTR_VERTEX2);
glEnableVertexAttribArray(VATTR_NORMAL);
glDisableVertexAttribArray(VATTR_COLOR);
} }
//=========================================================================== //===========================================================================
@ -190,14 +185,8 @@ void FModelVertexBuffer::BindVBO()
FModelVertexBuffer::~FModelVertexBuffer() FModelVertexBuffer::~FModelVertexBuffer()
{ {
if (ibo_id != 0) if (mIndexBuffer) delete mIndexBuffer;
{ delete mVertexBuffer;
glDeleteBuffers(1, &ibo_id);
}
if (vbo_ptr != nullptr)
{
delete[] vbo_ptr;
}
} }
//=========================================================================== //===========================================================================
@ -208,19 +197,7 @@ FModelVertexBuffer::~FModelVertexBuffer()
FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size) FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size)
{ {
if (vbo_id > 0) return static_cast<FModelVertex*>(mVertexBuffer->Lock(size * sizeof(FModelVertex)));
{
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glBufferData(GL_ARRAY_BUFFER, size * sizeof(FModelVertex), nullptr, GL_STATIC_DRAW);
return (FModelVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, size * sizeof(FModelVertex), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
else
{
if (vbo_ptr != nullptr) delete[] vbo_ptr;
vbo_ptr = new FModelVertex[size];
memset(vbo_ptr, 0, size * sizeof(FModelVertex));
return vbo_ptr;
}
} }
//=========================================================================== //===========================================================================
@ -231,11 +208,7 @@ FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size)
void FModelVertexBuffer::UnlockVertexBuffer() void FModelVertexBuffer::UnlockVertexBuffer()
{ {
if (vbo_id > 0) mVertexBuffer->Unlock();
{
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glUnmapBuffer(GL_ARRAY_BUFFER);
}
} }
//=========================================================================== //===========================================================================
@ -246,16 +219,8 @@ void FModelVertexBuffer::UnlockVertexBuffer()
unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size) unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size)
{ {
if (ibo_id != 0) if (mIndexBuffer) return static_cast<unsigned int*>(mIndexBuffer->Lock(size * sizeof(unsigned int)));
{ else return nullptr;
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(unsigned int), NULL, GL_STATIC_DRAW);
return (unsigned int*)glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, size * sizeof(unsigned int), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
}
else
{
return nullptr;
}
} }
//=========================================================================== //===========================================================================
@ -266,27 +231,18 @@ unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size)
void FModelVertexBuffer::UnlockIndexBuffer() void FModelVertexBuffer::UnlockIndexBuffer()
{ {
if (ibo_id > 0) if (mIndexBuffer) mIndexBuffer->Unlock();
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
}
} }
//=========================================================================== //===========================================================================
// //
// Sets up the buffer starts for frame interpolation //
// This must be called after gl_RenderState.Apply!
// //
//=========================================================================== //===========================================================================
static TArray<FModelVertex> iBuffer;
void FModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) void FModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size)
{ {
glBindBuffer(GL_ARRAY_BUFFER, vbo_id); mIndexFrame[0] = frame1;
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].x); mIndexFrame[1] = frame2;
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].u);
glVertexAttribPointer(VATTR_VERTEX2, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame2].x);
glVertexAttribPointer(VATTR_NORMAL, 4, GL_INT_2_10_10_10_REV, true, sizeof(FModelVertex), &VMO[frame2].packedNormal);
} }

View File

@ -30,6 +30,28 @@
class GLSprite; class GLSprite;
struct FDrawInfo; struct FDrawInfo;
class FRenderState;
class FModelVertexBuffer : public IModelVertexBuffer
{
int mIndexFrame[2];
IVertexBuffer *mVertexBuffer;
IIndexBuffer *mIndexBuffer;
public:
FModelVertexBuffer(bool needindex, bool singleframe);
~FModelVertexBuffer();
FModelVertex *LockVertexBuffer(unsigned int size) override;
void UnlockVertexBuffer() override;
unsigned int *LockIndexBuffer(unsigned int size) override;
void UnlockIndexBuffer() override;
void SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) override;
void Bind(FRenderState &state);
};
class FGLModelRenderer : public FModelRenderer class FGLModelRenderer : public FModelRenderer
{ {

View File

@ -276,7 +276,7 @@ void FGLRenderState::ApplyBuffers()
} }
if (mIndexBuffer != mCurrentIndexBuffer) if (mIndexBuffer != mCurrentIndexBuffer)
{ {
static_cast<GLIndexBuffer*>(mIndexBuffer)->Bind(); if (mIndexBuffer) static_cast<GLIndexBuffer*>(mIndexBuffer)->Bind();
mCurrentIndexBuffer = mIndexBuffer; mCurrentIndexBuffer = mIndexBuffer;
} }
} }

View File

@ -192,11 +192,8 @@ GLIndexBuffer::~GLIndexBuffer()
void GLIndexBuffer::SetData(size_t size, void *data, bool staticdata) void GLIndexBuffer::SetData(size_t size, void *data, bool staticdata)
{ {
if (data != nullptr) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
{ glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, staticdata? GL_STATIC_DRAW : GL_STREAM_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, staticdata? GL_STATIC_DRAW : GL_STREAM_DRAW);
}
buffersize = size; buffersize = size;
gl_RenderState.ResetVertexBuffer(); // This is needed because glBindBuffer overwrites the setting stored in the render state. gl_RenderState.ResetVertexBuffer(); // This is needed because glBindBuffer overwrites the setting stored in the render state.
} }