Added rendering with generic vertex formats

dev-buzzingcars
Tomasz Kapuściński 2016-11-04 14:13:16 +01:00
parent ae3b2b8572
commit 993d9e9ed6
15 changed files with 642 additions and 237 deletions

View File

@ -165,6 +165,7 @@ set(BASE_SOURCES
graphics/core/nulldevice.cpp
graphics/core/nulldevice.h
graphics/core/texture.h
graphics/core/type.cpp
graphics/core/type.h
graphics/core/vertex.h
graphics/engine/camera.cpp

View File

@ -26,6 +26,7 @@
#include "graphics/core/color.h"
#include "graphics/core/texture.h"
#include "graphics/core/vertex.h"
#include "math/intpoint.h"
@ -267,8 +268,10 @@ enum PrimitiveType
PRIMITIVE_POINTS,
PRIMITIVE_LINES,
PRIMITIVE_LINE_STRIP,
PRIMITIVE_LINE_LOOP,
PRIMITIVE_TRIANGLES,
PRIMITIVE_TRIANGLE_STRIP
PRIMITIVE_TRIANGLE_STRIP,
PRIMITIVE_TRIANGLE_FAN
};
/**
@ -413,6 +416,14 @@ 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,6 +168,16 @@ 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,6 +81,11 @@ 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

@ -205,47 +205,6 @@ struct TextureStageParams
}
};
/**
* \struct TexGenMode
* \brief Texture generation mode
*/
enum TexGenMode
{
//! No texture generation
TEX_GEN_NONE,
//! Object linear mode
TEX_GEN_OBJECT_LINEAR,
//! Eye linear mode
TEX_GEN_EYE_LINEAR,
//! Spherical mapping mode
TEX_GEN_SPHERE_MAP,
//! Normal mapping mode
TEX_GEN_NORMAL_MAP,
//! Reflection mapping mode
TEX_GEN_REFLECTION_MAP
};
/**
* \struct TextureGenerationParams
* \brief Parameters for texture coordinate generation
*
* These params define the generation of texture coordinate for given texture unit.
*/
struct TextureGenerationParams
{
struct Coord
{
TexGenMode mode = TEX_GEN_NONE;
float plane[4] = {};
};
Coord coords[4];
void LoadDefault()
{
*this = TextureGenerationParams();
}
};
/**
* \struct Texture
* \brief Info about a texture

View File

@ -0,0 +1,56 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2016, Daniel Roux, EPSITEC SA & TerranovaTeam
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://gnu.org/licenses
*/
/**
* \file graphics/core/type.cpp
* \brief Type support and conversion
*/
#include "graphics/core/type.h"
#include <cassert>
// Graphics module namespace
namespace Gfx
{
//! Returns size in bytes of given type
int GetTypeSize(Type type)
{
switch (type)
{
case Type::BYTE:
case Type::UBYTE:
return 1;
case Type::SHORT:
case Type::USHORT:
case Type::HALF:
return 2;
case Type::INT:
case Type::UINT:
case Type::FLOAT:
return 4;
case Type::DOUBLE:
return 8;
default:
return 0;
}
}
} // namespace Gfx

View File

@ -54,6 +54,9 @@ enum class Type : unsigned char
DOUBLE,
};
//! Returns size in bytes of given type
int GetTypeSize(Type type);
// TODO: functions for conversion between types
} // namespace Gfx

View File

@ -1379,6 +1379,168 @@ void CGL14Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
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)
{

View File

@ -119,6 +119,11 @@ 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,

View File

@ -1196,6 +1196,162 @@ void CGL21Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
glDisableClientState(GL_COLOR_ARRAY);
}
void CGL21Device::DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount)
{
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)
{
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,
int first[], int count[], int drawCount, Color color)
{

View File

@ -100,6 +100,11 @@ 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,

View File

@ -523,21 +523,18 @@ bool CGL33Device::Create()
m_framebuffers["default"] = MakeUnique<CDefaultFramebuffer>(framebufferParams);
// create dynamic buffers
for (int i = 0; i < 3; i++)
{
glGenVertexArrays(1, &m_dynamicBuffers[i].vao);
// create dynamic buffer
glGenVertexArrays(1, &m_dynamicBuffer.vao);
m_dynamicBuffers[i].size = 4 * 1024 * 1024;
m_dynamicBuffers[i].offset = 0;
m_dynamicBuffer.size = 4 * 1024 * 1024;
m_dynamicBuffer.offset = 0;
glGenBuffers(1, &m_dynamicBuffers[i].vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_dynamicBuffers[i].vbo);
glBufferData(GL_ARRAY_BUFFER, m_dynamicBuffers[i].size, nullptr, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &m_dynamicBuffer.vbo);
glBindBuffer(GL_ARRAY_BUFFER, m_dynamicBuffer.vbo);
glBufferData(GL_ARRAY_BUFFER, m_dynamicBuffer.size, nullptr, GL_STREAM_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
m_vboMemory += m_dynamicBuffers[i].size;
}
m_vboMemory += m_dynamicBuffer.size;
GetLogger()->Info("CDevice created successfully\n");
@ -563,13 +560,10 @@ void CGL33Device::Destroy()
DestroyAllTextures();
// delete dynamic buffer
for (int i = 0; i < 3; i++)
{
glDeleteVertexArrays(1, &m_dynamicBuffers[i].vao);
glDeleteBuffers(1, &m_dynamicBuffers[i].vbo);
glDeleteVertexArrays(1, &m_dynamicBuffer.vao);
glDeleteBuffers(1, &m_dynamicBuffer.vbo);
m_vboMemory -= m_dynamicBuffers[i].size;
}
m_vboMemory -= m_dynamicBuffer.size;
m_lights.clear();
m_lightsEnabled.clear();
@ -1075,46 +1069,39 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const Vertex *vertices, int
unsigned int size = vertexCount * sizeof(Vertex);
DynamicBuffer& buffer = m_dynamicBuffers[0];
DynamicBuffer& buffer = m_dynamicBuffer;
BindVAO(buffer.vao);
BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size);
// Start of the buffer, reinitialize binding state
if (offset == 0)
{
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offset + offsetof(Vertex, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, normal)));
// Color
glDisableVertexAttribArray(2);
// 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);
}
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offset + offsetof(Vertex, normal)));
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offset + offsetof(Vertex, texCoord)));
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
UpdateRenderingMode();
int first = offset / sizeof(Vertex);
glDrawArrays(TranslateGfxPrimitive(type), first, vertexCount);
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
}
void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices, int vertexCount, Color color)
@ -1123,46 +1110,40 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexTex2 *vertices,
unsigned int size = vertexCount * sizeof(VertexTex2);
DynamicBuffer& buffer = m_dynamicBuffers[1];
DynamicBuffer& buffer = m_dynamicBuffer;
BindVAO(buffer.vao);
BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size);
if (offset == 0)
{
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offset + offsetof(VertexTex2, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, normal)));
// Color
glDisableVertexAttribArray(2);
// 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)));
}
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offset + offsetof(VertexTex2, normal)));
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offset + offsetof(VertexTex2, texCoord)));
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offset + offsetof(VertexTex2, texCoord2)));
UpdateRenderingMode();
int first = offset / sizeof(VertexTex2);
glDrawArrays(TranslateGfxPrimitive(type), first, vertexCount);
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
}
void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, int vertexCount)
@ -1171,43 +1152,82 @@ void CGL33Device::DrawPrimitive(PrimitiveType type, const VertexCol *vertices, i
unsigned int size = vertexCount * sizeof(VertexCol);
DynamicBuffer& buffer = m_dynamicBuffers[2];
DynamicBuffer& buffer = m_dynamicBuffer;
BindVAO(buffer.vao);
BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size);
if (offset == 0)
{
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offset + offsetof(VertexCol, coord)));
// Normal
glDisableVertexAttribArray(1);
glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
// 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)));
// Color
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offset + offsetof(VertexCol, color)));
// Texture coordinate 0
glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 0
glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
}
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
UpdateRenderingMode();
int first = offset / sizeof(VertexCol);
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
}
glDrawArrays(TranslateGfxPrimitive(type), first, vertexCount);
void CGL33Device::DrawPrimitive(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int vertexCount)
{
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);
UpdateRenderingMode();
glDrawArrays(TranslateGfxPrimitive(type), 0, vertexCount);
}
void CGL33Device::DrawPrimitives(PrimitiveType type, const void *vertices,
int size, const VertexFormat &format, int first[], int count[], int drawCount)
{
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);
UpdateRenderingMode();
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
}
void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
@ -1227,51 +1247,39 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const Vertex *vertices,
unsigned int size = vertexCount * sizeof(Vertex);
DynamicBuffer& buffer = m_dynamicBuffers[0];
DynamicBuffer& buffer = m_dynamicBuffer;
BindVAO(buffer.vao);
BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size);
if (offset == 0)
{
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offset + offsetof(Vertex, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offsetof(Vertex, normal)));
// Color
glDisableVertexAttribArray(2);
// 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);
}
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offset + offsetof(Vertex, normal)));
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex),
reinterpret_cast<void*>(offset + offsetof(Vertex, texCoord)));
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
UpdateRenderingMode();
int firstOffset = offset / sizeof(Vertex);
for (int i = 0; i < drawCount; i++)
first[i] += firstOffset;
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
for (int i = 0; i < drawCount; i++)
first[i] -= firstOffset;
}
void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
@ -1291,52 +1299,40 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexTex2 *vertices,
unsigned int size = vertexCount * sizeof(VertexTex2);
DynamicBuffer& buffer = m_dynamicBuffers[1];
DynamicBuffer& buffer = m_dynamicBuffer;
BindVAO(buffer.vao);
BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size);
if (offset == 0)
{
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offset + offsetof(VertexTex2, coord)));
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offsetof(VertexTex2, normal)));
// Color
glDisableVertexAttribArray(2);
// 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)));
}
// Normal
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offset + offsetof(VertexTex2, normal)));
// Color
glDisableVertexAttribArray(2);
glVertexAttrib4fv(2, color.Array());
// Texture coordinate 0
glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offset + offsetof(VertexTex2, texCoord)));
// Texture coordinate 1
glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 2, GL_FLOAT, GL_FALSE, sizeof(VertexTex2),
reinterpret_cast<void*>(offset + offsetof(VertexTex2, texCoord2)));
UpdateRenderingMode();
int firstOffset = offset / sizeof(VertexTex2);
for (int i = 0; i < drawCount; i++)
first[i] += firstOffset;
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
for (int i = 0; i < drawCount; i++)
first[i] -= firstOffset;
}
void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
@ -1356,49 +1352,38 @@ void CGL33Device::DrawPrimitives(PrimitiveType type, const VertexCol *vertices,
unsigned int size = vertexCount * sizeof(VertexCol);
DynamicBuffer& buffer = m_dynamicBuffers[2];
DynamicBuffer& buffer = m_dynamicBuffer;
BindVAO(buffer.vao);
BindVBO(buffer.vbo);
unsigned int offset = UploadVertexData(buffer, vs, size);
if (offset == 0)
{
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offsetof(VertexCol, coord)));
// Vertex coordinate
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offset + offsetof(VertexCol, coord)));
// Normal
glDisableVertexAttribArray(1);
glVertexAttrib3f(1, 0.0f, 0.0f, 1.0f);
// 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)));
// Color
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexCol),
reinterpret_cast<void*>(offset + offsetof(VertexCol, color)));
// Texture coordinate 0
glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 0
glDisableVertexAttribArray(3);
glVertexAttrib2f(3, 0.0f, 0.0f);
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
}
// Texture coordinate 1
glDisableVertexAttribArray(4);
glVertexAttrib2f(4, 0.0f, 0.0f);
UpdateRenderingMode();
int firstOffset = offset / sizeof(VertexCol);
for (int i = 0; i < drawCount; i++)
first[i] += firstOffset;
glMultiDrawArrays(TranslateGfxPrimitive(type), first, count, drawCount);
for (int i = 0; i < drawCount; i++)
first[i] -= firstOffset;
}
unsigned int CGL33Device::CreateStaticBuffer(PrimitiveType primitiveType, const Vertex* vertices, int vertexCount)
@ -2057,7 +2042,7 @@ inline void CGL33Device::BindVAO(GLuint vao)
m_currentVAO = vao;
}
unsigned int CGL33Device::UploadVertexData(DynamicBuffer& buffer, void* data, unsigned int size)
unsigned int CGL33Device::UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size)
{
unsigned int nextOffset = buffer.offset + size;
@ -2080,7 +2065,7 @@ unsigned int CGL33Device::UploadVertexData(DynamicBuffer& buffer, void* data, un
if (ptr != nullptr)
{
memcpy(ptr, data, size);
glUnmapBuffer(GL_ARRAY_BUFFER);
}
// mapping failed, we must upload data with glBufferSubData
@ -2095,6 +2080,25 @@ unsigned int CGL33Device::UploadVertexData(DynamicBuffer& buffer, void* data, un
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,6 +115,11 @@ 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,
@ -202,7 +207,9 @@ private:
inline void BindVAO(GLuint vao);
//! Uploads data to dynamic buffer and returns offset to it
unsigned int UploadVertexData(DynamicBuffer& buffer, void* data, unsigned int size);
unsigned int UploadVertexData(DynamicBuffer& buffer, const void* data, unsigned int size);
inline void UpdateVertexAttribute(int index, const VertexAttribute &attribute, int offset);
private:
//! Current config
@ -283,7 +290,7 @@ private:
//! Shader program for shadow rendering
GLuint m_shadowProgram = 0;
DynamicBuffer m_dynamicBuffers[3];
DynamicBuffer m_dynamicBuffer;
//! Current mode
unsigned int m_mode = 0;

View File

@ -335,8 +335,10 @@ GLenum TranslateGfxPrimitive(PrimitiveType type)
case PRIMITIVE_POINTS: flag = GL_POINTS; break;
case PRIMITIVE_LINES: flag = GL_LINES; break;
case PRIMITIVE_LINE_STRIP: flag = GL_LINE_STRIP; break;
case PRIMITIVE_LINE_LOOP: flag = GL_LINE_LOOP; break;
case PRIMITIVE_TRIANGLES: flag = GL_TRIANGLES; break;
case PRIMITIVE_TRIANGLE_STRIP: flag = GL_TRIANGLE_STRIP; break;
case PRIMITIVE_TRIANGLE_FAN: flag = GL_TRIANGLE_FAN; break;
default: assert(false); break;
}
return flag;
@ -441,6 +443,23 @@ GLenum TranslateTextureCoordinateGen(int index)
return textureCoordGen[index];
}
GLenum TranslateType(Type type)
{
switch (type)
{
case Type::BYTE: return GL_BYTE;
case Type::UBYTE: return GL_UNSIGNED_BYTE;
case Type::SHORT: return GL_SHORT;
case Type::USHORT: return GL_UNSIGNED_SHORT;
case Type::INT: return GL_INT;
case Type::UINT: return GL_UNSIGNED_INT;
case Type::HALF: return GL_HALF_FLOAT;
case Type::FLOAT: return GL_FLOAT;
case Type::DOUBLE: return GL_DOUBLE;
default: return 0;
}
}
std::string lastShaderError;
std::string GetLastShaderError()

View File

@ -93,6 +93,8 @@ GLenum TranslateTextureCoordinate(int index);
GLenum TranslateTextureCoordinateGen(int index);
GLenum TranslateType(Type type);
std::string GetLastShaderError();
GLint LoadShader(GLint type, const char* filename);