mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-29 07:22:07 +00:00
- added an abstract base vertex buffer class.
This commit is contained in:
parent
5cce310f11
commit
bb09f5488f
6 changed files with 228 additions and 8 deletions
|
@ -1055,6 +1055,7 @@ set (PCH_SOURCES
|
|||
gl_load/gl_interface.cpp
|
||||
gl/system/gl_framebuffer.cpp
|
||||
gl/system/gl_debug.cpp
|
||||
gl/system/glsys_vertexbuffer.cpp
|
||||
gl/textures/gl_hwtexture.cpp
|
||||
gl/textures/gl_samplers.cpp
|
||||
hwrenderer/data/flatvertices.cpp
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "r_data/models/models.h"
|
||||
#include "hwrenderer/data/flatvertices.h"
|
||||
#include "hwrenderer/scene/hw_skydome.h"
|
||||
#include "hwrenderer/data/vertexbuffer.h"
|
||||
|
||||
struct vertex_t;
|
||||
struct secplane_t;
|
||||
|
@ -39,14 +40,6 @@ struct subsector_t;
|
|||
struct sector_t;
|
||||
class FMaterial;
|
||||
|
||||
enum
|
||||
{
|
||||
VATTR_VERTEX_BIT,
|
||||
VATTR_TEXCOORD_BIT,
|
||||
VATTR_COLOR_BIT,
|
||||
VATTR_VERTEX2_BIT,
|
||||
VATTR_NORMAL_BIT
|
||||
};
|
||||
|
||||
|
||||
class FVertexBuffer
|
||||
|
|
143
src/gl/system/glsys_vertexbuffer.cpp
Normal file
143
src/gl/system/glsys_vertexbuffer.cpp
Normal file
|
@ -0,0 +1,143 @@
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright(C) 2018 Christoph Oelckers
|
||||
// All rights reserved.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see http://www.gnu.org/licenses/
|
||||
//
|
||||
//--------------------------------------------------------------------------
|
||||
//
|
||||
/*
|
||||
** Low level vertex buffer class
|
||||
**
|
||||
**/
|
||||
|
||||
#include "gl_load/gl_system.h"
|
||||
#include "glsys_vertexbuffer.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Create / destroy the VBO
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
GLVertexBuffer::GLVertexBuffer()
|
||||
{
|
||||
glGenBuffers(1, &vbo_id);
|
||||
}
|
||||
|
||||
GLVertexBuffer::~GLVertexBuffer()
|
||||
{
|
||||
if (vbo_id != 0)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glDeleteBuffers(1, &vbo_id);
|
||||
}
|
||||
}
|
||||
|
||||
void GLVertexBuffer::SetData(size_t size, void *data, bool staticdata)
|
||||
{
|
||||
if (data != nullptr)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, size, data, staticdata? GL_STATIC_DRAW : GL_STREAM_DRAW);
|
||||
}
|
||||
else
|
||||
{
|
||||
mPersistent = screen->BuffersArePersistent();
|
||||
if (mPersistent)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferStorage(GL_ARRAY_BUFFER, size, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
map = glMapBufferRange(GL_ARRAY_BUFFER, 0, size, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, size, NULL, GL_STREAM_DRAW);
|
||||
map = nullptr;
|
||||
}
|
||||
nomap = false;
|
||||
}
|
||||
buffersize = size;
|
||||
gl_RenderState.ResetVertexBuffer(); // This is needed because glBindBuffer overwrites the setting stored in the render state.
|
||||
}
|
||||
|
||||
void GLVertexBuffer::Map()
|
||||
{
|
||||
assert(nomap == false);
|
||||
if (!mPersistent)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
gl_RenderState.ResetVertexBuffer();
|
||||
map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, buffersize, GL_MAP_WRITE_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void GLVertexBuffer::Unmap()
|
||||
{
|
||||
assert(nomap == false);
|
||||
if (!mPersistent)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
gl_RenderState.ResetVertexBuffer();
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
map = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void GLVertexBuffer::SetFormat(int numBindingPoints, int numAttributes, size_t stride, FVertexBufferAttribute *attrs)
|
||||
{
|
||||
static int VFmtToGLFmt[] = { GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_UNSIGNED_BYTE, GL_INT_2_10_10_10_REV };
|
||||
static uint8_t VFmtToSize[] = {4, 3, 2, 1, 4, 4};
|
||||
|
||||
mStride = stride;
|
||||
mNumBindingPoints = numBindingPoints;
|
||||
|
||||
for(int i = 0; i < numAttributes; i++)
|
||||
{
|
||||
if (attrs[i].location >= 0 && attrs[i].location < VATTR_MAX)
|
||||
{
|
||||
auto & attrinf = mAttributeInfo[attrs[i].location];
|
||||
attrinf.format = VFmtToGLFmt[attrs[i].format];
|
||||
attrinf.size = VFmtToSize[attrs[i].format];
|
||||
attrinf.offset = attrs[i].offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GLVertexBuffer::Bind(size_t *offsets)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
for(auto &attrinf : mAttributeInfo)
|
||||
{
|
||||
if (attrinf.size == 0)
|
||||
{
|
||||
glDisableVertexAttribArray(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
glEnableVertexAttribArray(i);
|
||||
size_t ofs = offsets == nullptr? attrinf.offset : attrinf.offset + mStride * offsets[attrinf.bindingpoint];
|
||||
glVertexAttribPointer(i, attrinf.size, attrinf.format, attrinf.format != GL_FLOAT, (GLsizei)mStride, (void*)(intptr_t)ofs);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
31
src/gl/system/glsys_vertexbuffer.h
Normal file
31
src/gl/system/glsys_vertexbuffer.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
#pragma once
|
||||
|
||||
#include "hwrenderer/data/vertexbuffer.h"
|
||||
|
||||
class GLVertexBuffer : IVertexBuffer
|
||||
{
|
||||
// If this could use the modern (since GL 4.3) binding system, things would be simpler... :(
|
||||
struct GLVertexBufferAttribute
|
||||
{
|
||||
int bindingpoint;
|
||||
int format;
|
||||
int size;
|
||||
int offset;
|
||||
};
|
||||
|
||||
unsigned int vbo_id = 0;
|
||||
int mNumBindingPoints;
|
||||
bool mPersistent = false;
|
||||
GLVertexBufferAttribute mAttributeInfo[VATTR_MAX] = {}; // Thanks to OpenGL's state system this needs to contain info about every attribute that may ever be in use throughout the entire renderer.
|
||||
size_t mStride = 0;
|
||||
|
||||
public:
|
||||
GLVertexBuffer();
|
||||
~GLVertexBuffer();
|
||||
void SetData(size_t size, void *data, bool staticdata) = 0;
|
||||
void SetFormat(int numBindingPoints, int numAttributes, size_t stride, FVertexBufferAttribute *attrs) override;
|
||||
void Bind(size_t *offsets);
|
||||
void Map() override;
|
||||
void Unmap() override;
|
||||
};
|
||||
|
50
src/hwrenderer/data/vertexbuffer.h
Normal file
50
src/hwrenderer/data/vertexbuffer.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
|
||||
// The low level code needs to know which attributes exist.
|
||||
// OpenGL needs to change the state of all of them per buffer binding.
|
||||
// VAOs are mostly useless for this because they lump buffer and binding state together which the model code does not want.
|
||||
enum
|
||||
{
|
||||
VATTR_VERTEX_BIT,
|
||||
VATTR_TEXCOORD_BIT,
|
||||
VATTR_COLOR_BIT,
|
||||
VATTR_VERTEX2_BIT,
|
||||
VATTR_NORMAL_BIT,
|
||||
VATTR_NORMAL2_BIT,
|
||||
|
||||
VATTR_MAX
|
||||
};
|
||||
|
||||
enum EVertexAttributeFormat
|
||||
{
|
||||
VFmt_Float4,
|
||||
VFmt_Float3,
|
||||
VFmt_Float2,
|
||||
VFmt_Float,
|
||||
VFmt_Byte4,
|
||||
VFmt_Packed_A2R10G10B10,
|
||||
};
|
||||
|
||||
struct FVertexBufferAttribute
|
||||
{
|
||||
int binding;
|
||||
int location;
|
||||
int format;
|
||||
int offset;
|
||||
};
|
||||
|
||||
class IVertexBuffer
|
||||
{
|
||||
protected:
|
||||
size_t buffersize = 0;
|
||||
void *map = nullptr;
|
||||
bool nomap = true;
|
||||
public:
|
||||
virtual ~IVertexBuffer() {}
|
||||
virtual void SetData(size_t size, void *data, bool staticdata = true) = 0;
|
||||
virtual void SetFormat(int numBindingPoints, int numAttributes, size_t stride, FVertexBufferAttribute *attrs) = 0;
|
||||
virtual void Map() {} // Only needed by old OpenGL but this needs to be in the interface.
|
||||
virtual void Unmap() {}
|
||||
void *Memory() { assert(map); return map; }
|
||||
};
|
||||
|
|
@ -511,6 +511,8 @@ void GLWall::PutPortal(HWDrawInfo *di, int ptype)
|
|||
break;
|
||||
|
||||
case PORTALTYPE_LINETOLINE:
|
||||
if (!lineportal)
|
||||
return;
|
||||
portal = di->FindPortal(lineportal);
|
||||
if (!portal)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue