mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 15:22:15 +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_load/gl_interface.cpp
|
||||||
gl/system/gl_framebuffer.cpp
|
gl/system/gl_framebuffer.cpp
|
||||||
gl/system/gl_debug.cpp
|
gl/system/gl_debug.cpp
|
||||||
|
gl/system/glsys_vertexbuffer.cpp
|
||||||
gl/textures/gl_hwtexture.cpp
|
gl/textures/gl_hwtexture.cpp
|
||||||
gl/textures/gl_samplers.cpp
|
gl/textures/gl_samplers.cpp
|
||||||
hwrenderer/data/flatvertices.cpp
|
hwrenderer/data/flatvertices.cpp
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "r_data/models/models.h"
|
#include "r_data/models/models.h"
|
||||||
#include "hwrenderer/data/flatvertices.h"
|
#include "hwrenderer/data/flatvertices.h"
|
||||||
#include "hwrenderer/scene/hw_skydome.h"
|
#include "hwrenderer/scene/hw_skydome.h"
|
||||||
|
#include "hwrenderer/data/vertexbuffer.h"
|
||||||
|
|
||||||
struct vertex_t;
|
struct vertex_t;
|
||||||
struct secplane_t;
|
struct secplane_t;
|
||||||
|
@ -39,14 +40,6 @@ struct subsector_t;
|
||||||
struct sector_t;
|
struct sector_t;
|
||||||
class FMaterial;
|
class FMaterial;
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
VATTR_VERTEX_BIT,
|
|
||||||
VATTR_TEXCOORD_BIT,
|
|
||||||
VATTR_COLOR_BIT,
|
|
||||||
VATTR_VERTEX2_BIT,
|
|
||||||
VATTR_NORMAL_BIT
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class FVertexBuffer
|
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;
|
break;
|
||||||
|
|
||||||
case PORTALTYPE_LINETOLINE:
|
case PORTALTYPE_LINETOLINE:
|
||||||
|
if (!lineportal)
|
||||||
|
return;
|
||||||
portal = di->FindPortal(lineportal);
|
portal = di->FindPortal(lineportal);
|
||||||
if (!portal)
|
if (!portal)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue