diff --git a/src/gl/data/gl_vertexbuffer.h b/src/gl/data/gl_vertexbuffer.h index 8d0c35637..3d6d16345 100644 --- a/src/gl/data/gl_vertexbuffer.h +++ b/src/gl/data/gl_vertexbuffer.h @@ -95,26 +95,6 @@ public: 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) diff --git a/src/gl/models/gl_models.cpp b/src/gl/models/gl_models.cpp index 48ad733da..723e50ce0 100644 --- a/src/gl/models/gl_models.cpp +++ b/src/gl/models/gl_models.cpp @@ -35,6 +35,7 @@ #include "d_player.h" #include "g_levellocals.h" #include "i_time.h" +#include "cmdlib.h" #include "hwrenderer/textures/hw_material.h" #include "gl_load/gl_interface.h" @@ -113,7 +114,7 @@ IModelVertexBuffer *FGLModelRenderer::CreateVertexBuffer(bool needindex, bool si void FGLModelRenderer::SetVertexBuffer(IModelVertexBuffer *buffer) { - gl_RenderState.SetVertexBuffer((FModelVertexBuffer*)buffer); + static_cast(buffer)->Bind(gl_RenderState); } 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) - : FVertexBuffer(true) { - vbo_ptr = nullptr; - ibo_id = 0; - if (needindex) - { - glGenBuffers(1, &ibo_id); // The index buffer can always be a real buffer. - } + mVertexBuffer = screen->CreateVertexBuffer(); + mIndexBuffer = needindex ? screen->CreateIndexBuffer() : nullptr; + + static const FVertexBufferAttribute format[] = { + { 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); - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glEnableVertexAttribArray(VATTR_VERTEX); - glEnableVertexAttribArray(VATTR_TEXCOORD); - glEnableVertexAttribArray(VATTR_VERTEX2); - glEnableVertexAttribArray(VATTR_NORMAL); - glDisableVertexAttribArray(VATTR_COLOR); + state.SetVertexBuffer(mVertexBuffer, mIndexFrame[0], mIndexFrame[1]); + if (mIndexBuffer) state.SetIndexBuffer(mIndexBuffer); } //=========================================================================== @@ -190,14 +185,8 @@ void FModelVertexBuffer::BindVBO() FModelVertexBuffer::~FModelVertexBuffer() { - if (ibo_id != 0) - { - glDeleteBuffers(1, &ibo_id); - } - if (vbo_ptr != nullptr) - { - delete[] vbo_ptr; - } + if (mIndexBuffer) delete mIndexBuffer; + delete mVertexBuffer; } //=========================================================================== @@ -208,19 +197,7 @@ FModelVertexBuffer::~FModelVertexBuffer() FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size) { - if (vbo_id > 0) - { - 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; - } + return static_cast(mVertexBuffer->Lock(size * sizeof(FModelVertex))); } //=========================================================================== @@ -231,11 +208,7 @@ FModelVertex *FModelVertexBuffer::LockVertexBuffer(unsigned int size) void FModelVertexBuffer::UnlockVertexBuffer() { - if (vbo_id > 0) - { - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glUnmapBuffer(GL_ARRAY_BUFFER); - } + mVertexBuffer->Unlock(); } //=========================================================================== @@ -246,16 +219,8 @@ void FModelVertexBuffer::UnlockVertexBuffer() unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size) { - if (ibo_id != 0) - { - 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; - } + if (mIndexBuffer) return static_cast(mIndexBuffer->Lock(size * sizeof(unsigned int))); + else return nullptr; } //=========================================================================== @@ -266,27 +231,18 @@ unsigned int *FModelVertexBuffer::LockIndexBuffer(unsigned int size) void FModelVertexBuffer::UnlockIndexBuffer() { - if (ibo_id > 0) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id); - glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); - } + if (mIndexBuffer) mIndexBuffer->Unlock(); } //=========================================================================== // -// Sets up the buffer starts for frame interpolation -// This must be called after gl_RenderState.Apply! +// // //=========================================================================== -static TArray iBuffer; void FModelVertexBuffer::SetupFrame(FModelRenderer *renderer, unsigned int frame1, unsigned int frame2, unsigned int size) { - glBindBuffer(GL_ARRAY_BUFFER, vbo_id); - glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].x); - 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); + mIndexFrame[0] = frame1; + mIndexFrame[1] = frame2; } diff --git a/src/gl/models/gl_models.h b/src/gl/models/gl_models.h index fb044c49f..786391cd5 100644 --- a/src/gl/models/gl_models.h +++ b/src/gl/models/gl_models.h @@ -30,6 +30,28 @@ class GLSprite; 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 { diff --git a/src/gl/renderer/gl_renderstate.cpp b/src/gl/renderer/gl_renderstate.cpp index f9198d3fb..49279375c 100644 --- a/src/gl/renderer/gl_renderstate.cpp +++ b/src/gl/renderer/gl_renderstate.cpp @@ -276,7 +276,7 @@ void FGLRenderState::ApplyBuffers() } if (mIndexBuffer != mCurrentIndexBuffer) { - static_cast(mIndexBuffer)->Bind(); + if (mIndexBuffer) static_cast(mIndexBuffer)->Bind(); mCurrentIndexBuffer = mIndexBuffer; } } diff --git a/src/gl/system/glsys_vertexbuffer.cpp b/src/gl/system/glsys_vertexbuffer.cpp index 91d5205f6..2a37d4ceb 100644 --- a/src/gl/system/glsys_vertexbuffer.cpp +++ b/src/gl/system/glsys_vertexbuffer.cpp @@ -192,11 +192,8 @@ GLIndexBuffer::~GLIndexBuffer() 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; gl_RenderState.ResetVertexBuffer(); // This is needed because glBindBuffer overwrites the setting stored in the render state. }