Merge pull request #1162 from AbigailBuccaneer/gl-cleanup

Clean up and improve CGLxxDevice code
1008-fix
tomangelo 2018-07-23 12:15:08 +02:00 committed by GitHub
commit d90592f7b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 325 additions and 1341 deletions

View File

@ -416,14 +416,6 @@ public:
//! Sets only the texture wrap modes (for faster than thru stage params)
virtual void SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode wrapT) = 0;
//! Renders primitive composed of generic vertices
virtual void DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount) = 0;
//! Renders multiple primitives composed of generic vertices
virtual void DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount) = 0;
//! Renders primitive composed of vertices with single texture
virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount,
Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) = 0;

View File

@ -168,16 +168,6 @@ void CNullDevice::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
{
}
void CNullDevice::DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount)
{
}
void CNullDevice::DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount)
{
}
void CNullDevice::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
int first[], int count[], int drawCount, Color color)
{

View File

@ -81,11 +81,6 @@ public:
void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override;
void DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount) override;
void DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount) override;
void DrawPrimitive(PrimitiveType type, const Vertex* vertices, int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override;
void DrawPrimitive(PrimitiveType type, const VertexTex2* vertices, int vertexCount, Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override;
void DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount) override;

View File

@ -39,57 +39,11 @@
namespace Gfx
{
/**
* \struct VertexAttribute
* \brief Vertex attribute
*
* This structure contains parameters for a vertex attribute.
*/
struct VertexAttribute
enum VertexType
{
//! true enables vertex attribute
bool enabled = false;
//! true means normalized value (integer types only)
bool normalized = false;
//! Number of elements in the vertex attribute.
//! Valid values are 1, 2, 3, and 4. Depends on specific attribute.
unsigned char size = 0;
//! Type of values in vertex attribute
Type type = Type::UBYTE;
//! Offset to the vertex attribute
int offset = 0;
//! Stride of vertex attribute
int stride = 0;
//! Default values used when attribute is disabled
float values[4] = {0.0f, 0.0f, 0.0f, 0.0f};
};
/**
* \struct VertexFormat
* \brief Vertex format
*
* This structure defines vertex formats for generic vertex arrays.
*
* It contains:
* - vertex coordinate specification
* - color specification
* - normal specification
* - texture coordinate 1 specification
* - texture coordinate 2 specification
*/
struct VertexFormat
{
//! Vertex coordinate
VertexAttribute vertex{};
//! Color
VertexAttribute color{};
//! Normal
VertexAttribute normal{};
//! Texture coordinate 1
VertexAttribute tex1{};
//! Texture coordinate 2
VertexAttribute tex2{};
VERTEX_TYPE_NORMAL,
VERTEX_TYPE_TEX2,
VERTEX_TYPE_COL,
};
/**
@ -105,6 +59,8 @@ struct VertexFormat
*/
struct Vertex
{
static constexpr VertexType VERTEX_TYPE = VERTEX_TYPE_NORMAL;
Math::Vector coord;
Math::Vector normal;
Math::Point texCoord;
@ -137,6 +93,8 @@ struct Vertex
*/
struct VertexCol
{
static constexpr VertexType VERTEX_TYPE = VERTEX_TYPE_COL;
Math::Vector coord;
Color color;
@ -166,6 +124,8 @@ struct VertexCol
*/
struct VertexTex2
{
static constexpr VertexType VERTEX_TYPE = VERTEX_TYPE_TEX2;
Math::Vector coord;
Math::Vector normal;
Math::Point texCoord;

View File

@ -257,7 +257,6 @@ bool CGL14Device::Create()
if (glVersion >= 15)
{
GetLogger()->Info("Core VBO supported\n", glMajor, glMinor);
m_vertexBufferType = VBT_VBO_CORE;
// Set function pointers
m_glGenBuffers = glGenBuffers;
@ -269,7 +268,6 @@ bool CGL14Device::Create()
else if (vboARB) // VBO ARB extension available
{
GetLogger()->Info("ARB VBO supported\n");
m_vertexBufferType = VBT_VBO_ARB;
// Set function pointers
m_glGenBuffers = glGenBuffersARB;
@ -280,8 +278,11 @@ bool CGL14Device::Create()
}
else // no VBO support
{
GetLogger()->Info("VBO not supported\n");
m_vertexBufferType = VBT_DISPLAY_LIST;
m_errorMessage = "Your graphics card or drivers don't support OpenGL 1.5 or vertex buffer objects.\n"
"Ensure you have the latest graphics drivers for your graphics card.\n\n";
GetLogger()->Error(m_errorMessage.c_str());
m_errorMessage += GetHardwareInfo();
return false;
}
// This is mostly done in all modern hardware by default
@ -1299,255 +1300,93 @@ void CGL14Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode
else assert(false);
}
namespace
{
void SetVertexAttributes(const Vertex* bufferBase, const std::vector<int>& textureRemapping)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast<const char*>(bufferBase) + offsetof(Vertex, coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast<const char*>(bufferBase) + offsetof(Vertex, normal));
glClientActiveTexture(GL_TEXTURE0 + textureRemapping[1]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + textureRemapping[0]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<const char*>(bufferBase) + offsetof(Vertex, texCoord));
glDisableClientState(GL_COLOR_ARRAY);
}
void SetVertexAttributes(const VertexTex2* bufferBase, const std::vector<int>& textureRemapping)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexTex2, coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexTex2, normal));
glClientActiveTexture(GL_TEXTURE0 + textureRemapping[1]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexTex2, texCoord2));
glClientActiveTexture(GL_TEXTURE0 + textureRemapping[0]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexTex2, texCoord));
glDisableClientState(GL_COLOR_ARRAY);
}
void SetVertexAttributes(const VertexCol* bufferBase, const std::vector<int>& textureRemapping)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexCol, coord));
glDisableClientState(GL_NORMAL_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + textureRemapping[1]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0 + textureRemapping[0]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexCol, color));
}
} // namespace
void CGL14Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount,
Color color)
{
Vertex* vs = const_cast<Vertex*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].normal));
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].texCoord));
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
SetVertexAttributes(vertices, m_remap);
glColor4fv(color.Array());
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0
}
void CGL14Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount,
Color color)
{
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].normal));
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].texCoord));
glClientActiveTexture(GL_TEXTURE0 + m_remap[1]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].texCoord2));
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
SetVertexAttributes(vertices, m_remap);
glColor4fv(color.Array());
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void CGL14Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
{
VertexCol* vs = const_cast<VertexCol*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].color));
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
SetVertexAttributes(vertices, m_remap);
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
void CGL14Device::DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount)
{
const char *ptr = reinterpret_cast<const char*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(format.vertex.size,
TransformType(format.vertex.type),
format.vertex.stride,
ptr + format.vertex.offset);
if (format.color.enabled)
{
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(format.color.size,
TransformType(format.color.type),
format.color.stride,
ptr + format.color.offset);
}
else
glColor4fv(format.color.values);
if (format.normal.enabled)
{
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(TransformType(format.normal.type),
format.normal.stride,
ptr + format.normal.offset);
}
else
glNormal3fv(format.normal.values);
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
if (format.tex1.enabled)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(format.tex1.size,
TransformType(format.tex1.type),
format.tex1.stride,
ptr + format.tex1.offset);
}
else
glTexCoord2fv(format.tex1.values);
glClientActiveTexture(GL_TEXTURE0 + m_remap[1]);
if (format.tex2.enabled)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(format.tex2.size,
TransformType(format.tex2.type),
format.tex2.stride,
ptr + format.tex2.offset);
}
else
glTexCoord2fv(format.tex2.values);
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY);
if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY);
if (format.tex1.enabled)
{
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (format.tex2.enabled)
{
glClientActiveTexture(GL_TEXTURE0 + m_remap[1]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
void CGL14Device::DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount)
{
const char *ptr = reinterpret_cast<const char*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(format.vertex.size,
TransformType(format.vertex.type),
format.vertex.stride,
ptr + format.vertex.offset);
if (format.color.enabled)
{
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(format.color.size,
TransformType(format.color.type),
format.color.stride,
ptr + format.color.offset);
}
else
glColor4fv(format.color.values);
if (format.normal.enabled)
{
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(TransformType(format.normal.type),
format.normal.stride,
ptr + format.normal.offset);
}
else
glNormal3fv(format.normal.values);
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
if (format.tex1.enabled)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(format.tex1.size,
TransformType(format.tex1.type),
format.tex1.stride,
ptr + format.tex1.offset);
}
else
glTexCoord2fv(format.tex1.values);
glClientActiveTexture(GL_TEXTURE0 + m_remap[1]);
if (format.tex2.enabled)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(format.tex2.size,
TransformType(format.tex2.type),
format.tex2.stride,
ptr + format.tex2.offset);
}
else
glTexCoord2fv(format.tex2.values);
GLenum t = TranslateGfxPrimitive(type);
if (m_multiDrawArrays)
{
glMultiDrawArrays(t, first, count, drawCount);
}
else
{
for (int i = 0; i < drawCount; i++)
glDrawArrays(t, first[i], count[i]);
}
glDisableClientState(GL_VERTEX_ARRAY);
if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY);
if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY);
if (format.tex1.enabled)
{
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (format.tex2.enabled)
{
glClientActiveTexture(GL_TEXTURE0 + m_remap[1]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
void CGL14Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
int first[], int count[], int drawCount, Color color)
{
Vertex* vs = const_cast<Vertex*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].normal));
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].texCoord));
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
SetVertexAttributes(vertices, m_remap);
glColor4fv(color.Array());
GLenum t = TranslateGfxPrimitive(type);
@ -1561,31 +1400,13 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
for (int i = 0; i < drawCount; i++)
glDrawArrays(t, first[i], count[i]);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0
}
void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
int first[], int count[], int drawCount, Color color)
{
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].normal));
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].texCoord));
glClientActiveTexture(GL_TEXTURE0 + m_remap[1]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].texCoord2));
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
SetVertexAttributes(vertices, m_remap);
glColor4fv(color.Array());
GLenum t = TranslateGfxPrimitive(type);
@ -1599,25 +1420,13 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
for (int i = 0; i < drawCount; i++)
glDrawArrays(t, first[i], count[i]);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
int first[], int count[], int drawCount)
{
VertexCol* vs = const_cast<VertexCol*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].color));
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
SetVertexAttributes(vertices, m_remap);
GLenum t = TranslateGfxPrimitive(type);
@ -1630,289 +1439,81 @@ void CGL14Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
for (int i = 0; i < drawCount; i++)
glDrawArrays(t, first[i], count[i]);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
template <typename Vertex>
unsigned int CGL14Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
{
unsigned int id = 0;
if (m_vertexBufferType != VBT_DISPLAY_LIST)
{
id = ++m_lastVboId;
unsigned int id = ++m_lastVboId;
VboObjectInfo info;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_NORMAL;
info.vertexCount = vertexCount;
info.bufferId = 0;
VboObjectInfo info;
info.primitiveType = primitiveType;
info.vertexType = Vertex::VERTEX_TYPE;
info.vertexCount = vertexCount;
info.bufferId = 0;
m_glGenBuffers(1, &info.bufferId);
m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
m_glGenBuffers(1, &info.bufferId);
m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
m_vboObjects[id] = info;
}
else
{
id = glGenLists(1);
glNewList(id, GL_COMPILE);
DrawPrimitive(primitiveType, vertices, vertexCount);
glEndList();
}
m_vboObjects[id] = info;
return id;
}
unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount)
template <typename Vertex>
void CGL14Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
{
unsigned int id = 0;
if (m_vertexBufferType != VBT_DISPLAY_LIST)
{
id = ++m_lastVboId;
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
VboObjectInfo info;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_TEX2;
info.vertexCount = vertexCount;
info.bufferId = 0;
VboObjectInfo& info = (*it).second;
info.primitiveType = primitiveType;
info.vertexType = Vertex::VERTEX_TYPE;
info.vertexCount = vertexCount;
m_glGenBuffers(1, &info.bufferId);
m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW);
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
m_vboObjects[id] = info;
}
else
{
id = glGenLists(1);
glNewList(id, GL_COMPILE);
DrawPrimitive(primitiveType, vertices, vertexCount);
glEndList();
}
return id;
}
unsigned int CGL14Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount)
{
unsigned int id = 0;
if (m_vertexBufferType != VBT_DISPLAY_LIST)
{
id = ++m_lastVboId;
VboObjectInfo info;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_COL;
info.vertexCount = vertexCount;
info.bufferId = 0;
m_glGenBuffers(1, &info.bufferId);
m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW);
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
m_vboObjects[id] = info;
}
else
{
id = glGenLists(1);
glNewList(id, GL_COMPILE);
DrawPrimitive(primitiveType, vertices, vertexCount);
glEndList();
}
return id;
}
void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
{
if (m_vertexBufferType != VBT_DISPLAY_LIST)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
VboObjectInfo& info = (*it).second;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_NORMAL;
info.vertexCount = vertexCount;
m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
}
else
{
glNewList(bufferId, GL_COMPILE);
DrawPrimitive(primitiveType, vertices, vertexCount);
glEndList();
}
}
void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount)
{
if (m_vertexBufferType != VBT_DISPLAY_LIST)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
VboObjectInfo& info = (*it).second;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_TEX2;
info.vertexCount = vertexCount;
m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexTex2), vertices, GL_STATIC_DRAW);
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
}
else
{
glNewList(bufferId, GL_COMPILE);
DrawPrimitive(primitiveType, vertices, vertexCount);
glEndList();
}
}
void CGL14Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount)
{
if (m_vertexBufferType != VBT_DISPLAY_LIST)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
VboObjectInfo& info = (*it).second;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_COL;
info.vertexCount = vertexCount;
m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(VertexCol), vertices, GL_STATIC_DRAW);
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
}
else
{
glNewList(bufferId, GL_COMPILE);
DrawPrimitive(primitiveType, vertices, vertexCount);
glEndList();
}
m_glBindBuffer(GL_ARRAY_BUFFER, info.bufferId);
m_glBufferData(GL_ARRAY_BUFFER, vertexCount * sizeof(Vertex), vertices, GL_STATIC_DRAW);
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void CGL14Device::DrawStaticBuffer(unsigned int bufferId)
{
if (m_vertexBufferType != VBT_DISPLAY_LIST)
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
m_glBindBuffer(GL_ARRAY_BUFFER, (*it).second.bufferId);
if ((*it).second.vertexType == VERTEX_TYPE_NORMAL)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
m_glBindBuffer(GL_ARRAY_BUFFER, (*it).second.bufferId);
if ((*it).second.vertexType == VERTEX_TYPE_NORMAL)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), static_cast<char*>(nullptr) + offsetof(Vertex, coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast<char*>(nullptr) + offsetof(Vertex, normal));
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast<char*>(nullptr) + offsetof(Vertex, texCoord));
}
else if ((*it).second.vertexType == VERTEX_TYPE_TEX2)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), static_cast<char*>(nullptr) + offsetof(VertexTex2, coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(VertexTex2), static_cast<char*>(nullptr) + offsetof(VertexTex2, normal));
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast<char*>(nullptr) + offsetof(VertexTex2, texCoord));
glClientActiveTexture(GL_TEXTURE0 + m_remap[1]);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast<char*>(nullptr) + offsetof(VertexTex2, texCoord2));
}
else if ((*it).second.vertexType == VERTEX_TYPE_COL)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), static_cast<char*>(nullptr) + offsetof(VertexCol, coord));
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(VertexCol), static_cast<char*>(nullptr) + offsetof(VertexCol, color));
}
GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType);
glDrawArrays(mode, 0, (*it).second.vertexCount);
if ((*it).second.vertexType == VERTEX_TYPE_NORMAL)
{
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0
}
else if ((*it).second.vertexType == VERTEX_TYPE_TEX2)
{
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1
glClientActiveTexture(GL_TEXTURE0 + m_remap[0]);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
else if ((*it).second.vertexType == VERTEX_TYPE_COL)
{
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
m_glBindBuffer(GL_ARRAY_BUFFER, 0);
SetVertexAttributes(static_cast<Vertex*>(nullptr), m_remap);
}
else
else if ((*it).second.vertexType == VERTEX_TYPE_TEX2)
{
glCallList(bufferId);
SetVertexAttributes(static_cast<VertexTex2*>(nullptr), m_remap);
}
else if ((*it).second.vertexType == VERTEX_TYPE_COL)
{
SetVertexAttributes(static_cast<VertexCol*>(nullptr), m_remap);
}
GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType);
glDrawArrays(mode, 0, (*it).second.vertexCount);
}
void CGL14Device::DestroyStaticBuffer(unsigned int bufferId)
{
if (m_vertexBufferType != VBT_DISPLAY_LIST)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
m_glDeleteBuffers(1, &(*it).second.bufferId);
m_glDeleteBuffers(1, &(*it).second.bufferId);
m_vboObjects.erase(it);
}
else
{
glDeleteLists(bufferId, 1);
}
m_vboObjects.erase(it);
}
/* Based on libwine's implementation */

View File

@ -43,17 +43,6 @@
namespace Gfx
{
/**
\enum VertexBufferType
\brief Specifies type of vertex buffer to use
*/
enum VertexBufferType
{
VBT_DISPLAY_LIST, //! use display lists
VBT_VBO_CORE, //! use core OpenGL 1.5 VBOs
VBT_VBO_ARB //! use ARB extension VBOs
};
enum ShadowMappingSupport
{
SMS_NONE, //! No support for depth textures
@ -119,11 +108,6 @@ public:
void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override;
virtual void DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount) override;
virtual void DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount) override;
virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount,
Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override;
virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount,
@ -139,12 +123,31 @@ public:
virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
int first[], int count[], int drawCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override;
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override;
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override;
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override
{
return CreateStaticBufferImpl(primitiveType, vertices, vertexCount);
}
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override
{
return CreateStaticBufferImpl(primitiveType, vertices, vertexCount);
}
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override
{
return CreateStaticBufferImpl(primitiveType, vertices, vertexCount);
}
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override
{
UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount);
}
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override
{
UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount);
}
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override
{
UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount);
}
void DrawStaticBuffer(unsigned int bufferId) override;
void DestroyStaticBuffer(unsigned int bufferId) override;
@ -214,6 +217,11 @@ private:
//! Disables shadows
void DisableShadows();
template <typename Vertex>
unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount);
template <typename Vertex>
void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount);
private:
//! Current config
DeviceConfig m_config;
@ -260,14 +268,6 @@ private:
//! Map of framebuffers
std::map<std::string, std::unique_ptr<CFramebuffer>> m_framebuffers;
//! Type of vertex structure
enum VertexType
{
VERTEX_TYPE_NORMAL,
VERTEX_TYPE_TEX2,
VERTEX_TYPE_COL,
};
//! Info about static VBO buffers
struct VboObjectInfo
{
@ -284,8 +284,6 @@ private:
bool m_multiDrawArrays = false;
//! Framebuffer support
FramebufferSupport m_framebufferSupport = FBS_NONE;
//! Which vertex buffer type to use
VertexBufferType m_vertexBufferType = VBT_DISPLAY_LIST;
//! Map of saved VBO objects
std::map<unsigned int, VboObjectInfo> m_vboObjects;
//! Last ID of VBO object

View File

@ -1115,33 +1115,70 @@ void CGL21Device::SetTextureStageWrap(int index, TexWrapMode wrapS, TexWrapMode
else assert(false);
}
namespace
{
void SetVertexAttributes(const Vertex* bufferBase)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast<const char*>(bufferBase) + offsetof(Vertex, coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast<const char*>(bufferBase) + offsetof(Vertex, normal));
glClientActiveTexture(GL_TEXTURE1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<const char*>(bufferBase) + offsetof(Vertex, texCoord));
glDisableClientState(GL_COLOR_ARRAY);
}
void SetVertexAttributes(const VertexTex2* bufferBase)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexTex2, coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexTex2, normal));
glClientActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexTex2, texCoord2));
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexTex2, texCoord));
glDisableClientState(GL_COLOR_ARRAY);
}
void SetVertexAttributes(const VertexCol* bufferBase)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexCol, coord));
glDisableClientState(GL_NORMAL_ARRAY);
glClientActiveTexture(GL_TEXTURE1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<const char*>(bufferBase) + offsetof(VertexCol, color));
}
} // namespace
void CGL21Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int vertexCount,
Color color)
{
if (m_updateLights) UpdateLights();
BindVBO(0);
Vertex* vs = const_cast<Vertex*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].normal));
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].texCoord));
SetVertexAttributes(vertices);
glColor4fv(color.Array());
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0
}
void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount,
@ -1150,33 +1187,10 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices,
if (m_updateLights) UpdateLights();
BindVBO(0);
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].normal));
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].texCoord));
glClientActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].texCoord2));
SetVertexAttributes(vertices);
glColor4fv(color.Array());
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1
glClientActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
@ -1184,179 +1198,8 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
if (m_updateLights) UpdateLights();
BindVBO(0);
VertexCol* vs = const_cast<VertexCol*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].color));
SetVertexAttributes(vertices);
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
void CGL21Device::DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount)
{
if (m_updateLights) UpdateLights();
BindVBO(0);
const char *ptr = reinterpret_cast<const char*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(format.vertex.size,
TransformType(format.vertex.type),
format.vertex.stride,
ptr + format.vertex.offset);
if (format.color.enabled)
{
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(format.color.size,
TransformType(format.color.type),
format.color.stride,
ptr + format.color.offset);
}
else
glColor4fv(format.color.values);
if (format.normal.enabled)
{
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(TransformType(format.normal.type),
format.normal.stride,
ptr + format.normal.offset);
}
else
glNormal3fv(format.normal.values);
glClientActiveTexture(GL_TEXTURE0);
if (format.tex1.enabled)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(format.tex1.size,
TransformType(format.tex1.type),
format.tex1.stride,
ptr + format.tex1.offset);
}
else
glTexCoord2fv(format.tex1.values);
glClientActiveTexture(GL_TEXTURE1);
if (format.tex2.enabled)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(format.tex2.size,
TransformType(format.tex2.type),
format.tex2.stride,
ptr + format.tex2.offset);
}
else
glTexCoord2fv(format.tex2.values);
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
glDisableClientState(GL_VERTEX_ARRAY);
if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY);
if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY);
if (format.tex1.enabled)
{
glClientActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (format.tex2.enabled)
{
glClientActiveTexture(GL_TEXTURE1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
void CGL21Device::DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount)
{
if (m_updateLights) UpdateLights();
BindVBO(0);
const char *ptr = reinterpret_cast<const char*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(format.vertex.size,
TransformType(format.vertex.type),
format.vertex.stride,
ptr + format.vertex.offset);
if (format.color.enabled)
{
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(format.color.size,
TransformType(format.color.type),
format.color.stride,
ptr + format.color.offset);
}
else
glColor4fv(format.color.values);
if (format.normal.enabled)
{
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(TransformType(format.normal.type),
format.normal.stride,
ptr + format.normal.offset);
}
else
glNormal3fv(format.normal.values);
glClientActiveTexture(GL_TEXTURE0);
if (format.tex1.enabled)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(format.tex1.size,
TransformType(format.tex1.type),
format.tex1.stride,
ptr + format.tex1.offset);
}
else
glTexCoord2fv(format.tex1.values);
glClientActiveTexture(GL_TEXTURE1);
if (format.tex2.enabled)
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(format.tex2.size,
TransformType(format.tex2.type),
format.tex2.stride,
ptr + format.tex2.offset);
}
else
glTexCoord2fv(format.tex2.values);
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
glDisableClientState(GL_VERTEX_ARRAY);
if (format.color.enabled) glDisableClientState(GL_COLOR_ARRAY);
if (format.normal.enabled) glDisableClientState(GL_NORMAL_ARRAY);
if (format.tex1.enabled)
{
glClientActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
if (format.tex2.enabled)
{
glClientActiveTexture(GL_TEXTURE1);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
@ -1365,26 +1208,10 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
if (m_updateLights) UpdateLights();
BindVBO(0);
Vertex* vs = const_cast<Vertex*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].normal));
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), reinterpret_cast<GLfloat*>(&vs[0].texCoord));
SetVertexAttributes(vertices);
glColor4fv(color.Array());
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0
}
void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
@ -1393,33 +1220,10 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
if (m_updateLights) UpdateLights();
BindVBO(0);
VertexTex2* vs = const_cast<VertexTex2*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].normal));
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].texCoord));
glClientActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), reinterpret_cast<GLfloat*>(&vs[0].texCoord2));
SetVertexAttributes(vertices);
glColor4fv(color.Array());
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1
glClientActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
@ -1428,28 +1232,20 @@ void CGL21Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
if (m_updateLights) UpdateLights();
BindVBO(0);
VertexCol* vs = const_cast<VertexCol*>(vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].coord));
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(VertexCol), reinterpret_cast<GLfloat*>(&vs[0].color));
SetVertexAttributes(vertices);
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
template <typename Vertex>
unsigned int CGL21Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
{
unsigned int id = ++m_lastVboId;
VboObjectInfo info;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_NORMAL;
info.vertexType = Vertex::VERTEX_TYPE;
info.vertexCount = vertexCount;
info.bufferId = 0;
info.size = vertexCount * sizeof(Vertex);
@ -1463,47 +1259,8 @@ unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const
return id;
}
unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount)
{
unsigned int id = ++m_lastVboId;
VboObjectInfo info;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_TEX2;
info.vertexCount = vertexCount;
info.bufferId = 0;
info.size = vertexCount * sizeof(VertexTex2);
glGenBuffers(1, &info.bufferId);
BindVBO(info.bufferId);
glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW);
m_vboObjects[id] = info;
return id;
}
unsigned int CGL21Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount)
{
unsigned int id = ++m_lastVboId;
VboObjectInfo info;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_COL;
info.vertexCount = vertexCount;
info.bufferId = 0;
info.size = vertexCount * sizeof(VertexCol);
glGenBuffers(1, &info.bufferId);
BindVBO(info.bufferId);
glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW);
m_vboObjects[id] = info;
return id;
}
void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
template <typename Vertex>
void CGL21Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
@ -1513,7 +1270,7 @@ void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit
VboObjectInfo& info = (*it).second;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_NORMAL;
info.vertexType = Vertex::VERTEX_TYPE;
info.vertexCount = vertexCount;
BindVBO(info.bufferId);
@ -1529,58 +1286,6 @@ void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit
}
}
void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
VboObjectInfo& info = (*it).second;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_TEX2;
info.vertexCount = vertexCount;
int newSize = vertexCount * sizeof(VertexTex2);
BindVBO(info.bufferId);
if (info.size < newSize)
{
glBufferData(GL_ARRAY_BUFFER, newSize, vertices, GL_STATIC_DRAW);
info.size = newSize;
}
else
{
glBufferSubData(GL_ARRAY_BUFFER, 0, newSize, vertices);
}
}
void CGL21Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
VboObjectInfo& info = (*it).second;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_COL;
info.vertexCount = vertexCount;
int newSize = vertexCount * sizeof(VertexCol);
BindVBO(info.bufferId);
if (info.size < newSize)
{
glBufferData(GL_ARRAY_BUFFER, newSize, vertices, GL_STATIC_DRAW);
info.size = newSize;
}
else
{
glBufferSubData(GL_ARRAY_BUFFER, 0, newSize, vertices);
}
}
void CGL21Device::DrawStaticBuffer(unsigned int bufferId)
{
auto it = m_vboObjects.find(bufferId);
@ -1593,64 +1298,20 @@ void CGL21Device::DrawStaticBuffer(unsigned int bufferId)
if ((*it).second.vertexType == VERTEX_TYPE_NORMAL)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), static_cast<char*>(nullptr) + offsetof(Vertex, coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(Vertex), static_cast<char*>(nullptr) + offsetof(Vertex, normal));
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), static_cast<char*>(nullptr) + offsetof(Vertex, texCoord));
SetVertexAttributes(static_cast<const Vertex*>(nullptr));
}
else if ((*it).second.vertexType == VERTEX_TYPE_TEX2)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexTex2), static_cast<char*>(nullptr) + offsetof(VertexTex2, coord));
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, sizeof(VertexTex2), static_cast<char*>(nullptr) + offsetof(VertexTex2, normal));
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast<char*>(nullptr) + offsetof(VertexTex2, texCoord));
glClientActiveTexture(GL_TEXTURE1);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, sizeof(VertexTex2), static_cast<char*>(nullptr) + offsetof(VertexTex2, texCoord2));
SetVertexAttributes(static_cast<const VertexTex2*>(nullptr));
}
else if ((*it).second.vertexType == VERTEX_TYPE_COL)
{
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(VertexCol), static_cast<char*>(nullptr) + offsetof(VertexCol, coord));
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, sizeof(VertexCol), static_cast<char*>(nullptr) + offsetof(VertexCol, color));
SetVertexAttributes(static_cast<const VertexCol*>(nullptr));
}
GLenum mode = TranslateGfxPrimitive((*it).second.primitiveType);
glDrawArrays(mode, 0, (*it).second.vertexCount);
if ((*it).second.vertexType == VERTEX_TYPE_NORMAL)
{
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE0
}
else if ((*it).second.vertexType == VERTEX_TYPE_TEX2)
{
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY); // GL_TEXTURE1
glClientActiveTexture(GL_TEXTURE0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
else if ((*it).second.vertexType == VERTEX_TYPE_COL)
{
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
}
}
void CGL21Device::DestroyStaticBuffer(unsigned int bufferId)

View File

@ -100,11 +100,6 @@ public:
void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override;
virtual void DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount) override;
virtual void DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount) override;
virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount,
Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override;
virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount,
@ -120,12 +115,30 @@ public:
virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
int first[], int count[], int drawCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override;
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override;
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override;
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override
{
return CreateStaticBufferImpl(primitiveType, vertices, vertexCount);
}
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override
{
return CreateStaticBufferImpl(primitiveType, vertices, vertexCount);
}
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override
{
return CreateStaticBufferImpl(primitiveType, vertices, vertexCount);
}
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override
{
UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount);
}
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override
{
UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount);
}
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override
{
UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount);
}
void DrawStaticBuffer(unsigned int bufferId) override;
void DestroyStaticBuffer(unsigned int bufferId) override;
@ -192,6 +205,11 @@ private:
//! Binds texture
inline void BindTexture(int index, GLuint texture);
template <typename Vertex>
unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount);
template <typename Vertex>
void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount);
private:
//! Current config
DeviceConfig m_config;
@ -232,14 +250,6 @@ private:
//! Map of framebuffers
std::map<std::string, std::unique_ptr<CFramebuffer>> m_framebuffers;
//! Type of vertex structure
enum VertexType
{
VERTEX_TYPE_NORMAL,
VERTEX_TYPE_TEX2,
VERTEX_TYPE_COL,
};
//! Info about static VBO buffers
struct VboObjectInfo
{

View File

@ -1158,50 +1158,6 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
}
void CGL33Device::DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount)
{
if (m_updateLights) UpdateLights();
DynamicBuffer& buffer = m_dynamicBuffer;
BindVAO(buffer.vao);
BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vertices, size);
// Update vertex attribute bindings
UpdateVertexAttribute(0, format.vertex, offset);
UpdateVertexAttribute(1, format.normal, offset);
UpdateVertexAttribute(2, format.color, offset);
UpdateVertexAttribute(3, format.tex1, offset);
UpdateVertexAttribute(4, format.tex2, offset);
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
}
void CGL33Device::DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount)
{
if (m_updateLights) UpdateLights();
DynamicBuffer& buffer = m_dynamicBuffer;
BindVAO(buffer.vao);
BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vertices, size);
// Update vertex attribute bindings
UpdateVertexAttribute(0, format.vertex, offset);
UpdateVertexAttribute(1, format.normal, offset);
UpdateVertexAttribute(2, format.color, offset);
UpdateVertexAttribute(3, format.tex1, offset);
UpdateVertexAttribute(4, format.tex2, offset);
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
}
void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
int first[], int count[], int drawCount, Color color)
{
@ -1358,27 +1314,12 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
}
unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
namespace
{
unsigned int id = 0;
id = ++m_lastVboId;
VertexBufferInfo info;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_NORMAL;
info.vertexCount = vertexCount;
info.size = vertexCount * sizeof(Vertex);
glGenVertexArrays(1, &info.vao);
BindVAO(info.vao);
glGenBuffers(1, &info.vbo);
BindVBO(info.vbo);
glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW);
m_vboMemory += info.size;
template <typename Vertex> void SetVertexAttributes();
template <> void SetVertexAttributes<Vertex>()
{
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, coord)));
@ -1398,33 +1339,10 @@ unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
m_vboObjects[id] = info;
return id;
}
unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount)
template <> void SetVertexAttributes<VertexTex2>()
{
unsigned int id = 0;
id = ++m_lastVboId;
VertexBufferInfo info;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_TEX2;
info.vertexCount = vertexCount;
info.size = vertexCount * sizeof(VertexTex2);
glGenVertexArrays(1, &info.vao);
BindVAO(info.vao);
glGenBuffers(1, &info.vbo);
BindVBO(info.vbo);
glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW);
m_vboMemory += info.size;
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
@ -1444,31 +1362,10 @@ unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
m_vboObjects[id] = info;
return id;
}
unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount)
template <> void SetVertexAttributes<VertexCol>()
{
unsigned int id = ++m_lastVboId;
VertexBufferInfo info;
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_COL;
info.vertexCount = vertexCount;
info.size = vertexCount * sizeof(VertexCol);
glGenVertexArrays(1, &info.vao);
BindVAO(info.vao);
glGenBuffers(1, &info.vbo);
BindVBO(info.vbo);
glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW);
m_vboMemory += info.size;
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast<void*>(offsetof(VertexCol, coord)));
@ -1488,13 +1385,40 @@ unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
}
} // namespace
template <typename Vertex>
unsigned int CGL33Device::CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
{
unsigned int id = 0;
id = ++m_lastVboId;
VertexBufferInfo info;
info.primitiveType = primitiveType;
info.vertexType = Vertex::VERTEX_TYPE;
info.vertexCount = vertexCount;
info.size = vertexCount * sizeof(Vertex);
glGenVertexArrays(1, &info.vao);
BindVAO(info.vao);
glGenBuffers(1, &info.vbo);
BindVBO(info.vbo);
glBufferData(GL_ARRAY_BUFFER, info.size, vertices, GL_STATIC_DRAW);
m_vboMemory += info.size;
SetVertexAttributes<Vertex>();
m_vboObjects[id] = info;
return id;
}
void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
template <typename Vertex>
void CGL33Device::UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
@ -1504,12 +1428,12 @@ void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit
unsigned int size = vertexCount * sizeof(Vertex);
bool changed = (info.vertexType != VERTEX_TYPE_NORMAL) || (size > info.size);
bool changed = (info.vertexType != Vertex::VERTEX_TYPE) || (size > info.size);
if (info.vertexType != VERTEX_TYPE_NORMAL) CLogger::GetInstance().Debug("Changing static buffer type\n");
if (info.vertexType != Vertex::VERTEX_TYPE) CLogger::GetInstance().Debug("Changing static buffer type\n");
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_NORMAL;
info.vertexType = Vertex::VERTEX_TYPE;
info.vertexCount = vertexCount;
BindVBO(info.vbo);
@ -1531,143 +1455,7 @@ void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primit
{
BindVAO(info.vao);
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, normal)));
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4f(2, 1.0f, 1.0f, 1.0f, 1.0f);
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, texCoord)));
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
}
}
void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
VertexBufferInfo& info = (*it).second;
unsigned int size = vertexCount * sizeof(VertexTex2);
bool changed = (info.vertexType != VERTEX_TYPE_TEX2) || (size > info.size);
if (info.vertexType != VERTEX_TYPE_TEX2) CLogger::GetInstance().Debug("Changing static buffer type\n");
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_TEX2;
info.vertexCount = vertexCount;
BindVBO(info.vbo);
if (info.size < size)
{
CLogger::GetInstance().Debug("Resizing static buffer: %d->%d\n", info.size, size);
glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW);
m_vboMemory -= info.size;
info.size = size;
m_vboMemory += info.size;
}
else
{
glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices);
}
if (changed) // Update vertex array bindings
{
BindVAO(info.vao);
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast<void*>(offsetof(VertexTex2, normal)));
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4f(2, 1.0f, 1.0f, 1.0f, 1.0f);
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast<void*>(offsetof(VertexTex2, texCoord)));
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2), reinterpret_cast<void*>(offsetof(VertexTex2, texCoord2)));
}
}
void CGL33Device::UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount)
{
auto it = m_vboObjects.find(bufferId);
if (it == m_vboObjects.end())
return;
VertexBufferInfo& info = (*it).second;
unsigned int size = vertexCount * sizeof(VertexCol);
bool changed = (info.vertexType != VERTEX_TYPE_COL) || (size > info.size);
if (info.vertexType != VERTEX_TYPE_NORMAL) CLogger::GetInstance().Debug("Changing static buffer type\n");
info.primitiveType = primitiveType;
info.vertexType = VERTEX_TYPE_COL;
info.vertexCount = vertexCount;
BindVBO(info.vbo);
if (info.size < size)
{
CLogger::GetInstance().Debug("Resizing static buffer: %d->%d\n", info.size, size);
glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW);
m_vboMemory -= info.size;
info.size = size;
m_vboMemory += info.size;
}
else
{
glBufferSubData(GL_ARRAY_BUFFER, 0, size, vertices);
}
if (changed) // Update vertex array bindings
{
BindVAO(info.vao);
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast<void*>(offsetof(VertexCol, coord)));
// Normal
glDisableVertexAttribArray(1);
glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
// Color
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol), reinterpret_cast<void*>(offsetof(VertexCol, color)));
// Texture coordinate 0
glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
SetVertexAttributes<Vertex>();
}
}
@ -2092,25 +1880,6 @@ unsigned int CGL33Device::UploadVertexData(DynamicBuffer& buffer, const void* da
return currentOffset;
}
void CGL33Device::UpdateVertexAttribute(int index, const VertexAttribute &attribute, int offset)
{
if (attribute.enabled)
{
glEnableVertexAttribArray(index);
glVertexAttribPointer(index,
attribute.size,
TranslateType(attribute.type),
attribute.normalized ? GL_TRUE : GL_FALSE,
attribute.stride,
reinterpret_cast<void*>(offset + attribute.offset));
}
else
{
glDisableVertexAttribArray(index);
glVertexAttrib4fv(index, attribute.values);
}
}
bool CGL33Device::IsAnisotropySupported()
{
return m_capabilities.anisotropySupported;

View File

@ -115,11 +115,6 @@ public:
void SetTextureStageWrap(int index, Gfx::TexWrapMode wrapS, Gfx::TexWrapMode wrapT) override;
virtual void DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount) override;
virtual void DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount) override;
virtual void DrawPrimitive(PrimitiveType type, const Vertex *vertices , int vertexCount,
Color color = Color(1.0f, 1.0f, 1.0f, 1.0f)) override;
virtual void DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount,
@ -135,12 +130,30 @@ public:
virtual void DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
int first[], int count[], int drawCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override;
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override;
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override;
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override;
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override
{
return CreateStaticBufferImpl(primitiveType, vertices, vertexCount);
}
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override
{
return CreateStaticBufferImpl(primitiveType, vertices, vertexCount);
}
unsigned int CreateStaticBuffer(PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override
{
return CreateStaticBufferImpl(primitiveType, vertices, vertexCount);
}
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount) override
{
UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount);
}
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexTex2* vertices, int vertexCount) override
{
UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount);
}
void UpdateStaticBuffer(unsigned int bufferId, PrimitiveType primitiveType, const VertexCol* vertices, int vertexCount) override
{
UpdateStaticBufferImpl(bufferId, primitiveType, vertices, vertexCount);
}
void DrawStaticBuffer(unsigned int bufferId) override;
void DestroyStaticBuffer(unsigned int bufferId) override;
@ -213,7 +226,10 @@ private:
//! Uploads data to dynamic buffer and returns offset to it
unsigned int UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size);
inline void UpdateVertexAttribute(int index, const VertexAttribute &attribute, int offset);
template <typename Vertex>
unsigned int CreateStaticBufferImpl(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount);
template <typename Vertex>
void UpdateStaticBufferImpl(unsigned int bufferId, PrimitiveType primitiveType, const Vertex* vertices, int vertexCount);
private:
//! Current config
@ -256,14 +272,6 @@ private:
//! Free texture unit
const int m_freeTexture = 3;
//! Type of vertex structure
enum VertexType
{
VERTEX_TYPE_NORMAL,
VERTEX_TYPE_TEX2,
VERTEX_TYPE_COL,
};
//! Info about static VBO buffers
struct VertexBufferInfo
{