implemented client vertex array support for old GPU's

This commit is contained in:
rachytski 2011-04-28 19:23:47 +03:00 committed by Alex Zolotarev
parent 179db664d0
commit 1d26145e3e
13 changed files with 119 additions and 45 deletions

View file

@ -135,15 +135,15 @@ namespace yg
immDrawTexturedPrimitives(rectPoints, texRectPoints, 4, texture, true, yg::Color(), false);
}
void Blitter::setupAuxVertexLayout(bool hasColor, bool hasTexture)
void Blitter::setupAuxVertexLayout(bool hasColor, bool hasTexture, void * glPtr)
{
OGLCHECK(glEnableClientState(GL_VERTEX_ARRAY));
OGLCHECK(glVertexPointer(2, GL_FLOAT, sizeof(AuxVertex), (void*)AuxVertex::vertexOffs));
OGLCHECK(glVertexPointer(2, GL_FLOAT, sizeof(AuxVertex), (void*)((char*)glPtr + AuxVertex::vertexOffs)));
if (hasColor)
{
OGLCHECK(glEnableClientState(GL_COLOR_ARRAY));
OGLCHECK(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(AuxVertex), (void*)AuxVertex::colorOffs));
OGLCHECK(glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(AuxVertex), (void*)((char*)glPtr + AuxVertex::colorOffs)));
}
else
OGLCHECK(glDisableClientState(GL_COLOR_ARRAY));
@ -151,7 +151,7 @@ namespace yg
if (hasTexture)
{
OGLCHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
OGLCHECK(glTexCoordPointer(2, GL_FLOAT, sizeof(AuxVertex), (void*)AuxVertex::texCoordsOffs));
OGLCHECK(glTexCoordPointer(2, GL_FLOAT, sizeof(AuxVertex), (void*)((char*)glPtr + AuxVertex::texCoordsOffs)));
}
else
{
@ -184,7 +184,7 @@ namespace yg
m_blitStorage.m_vertices->unlock();
m_blitStorage.m_vertices->makeCurrent();
setupAuxVertexLayout(hasColor, hasTexture);
setupAuxVertexLayout(hasColor, hasTexture, m_blitStorage.m_vertices->glPtr());
if (texture)
texture->makeCurrent();
@ -194,17 +194,17 @@ namespace yg
m_blitStorage.m_indices->unlock();
m_blitStorage.m_indices->makeCurrent();
resourceManager()->freeBlitStorage(m_blitStorage);
m_blitStorage = yg::gl::Storage();
OGLCHECK(glDisable(GL_BLEND));
OGLCHECK(glDisable(GL_DEPTH_TEST));
OGLCHECK(glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, 0));
OGLCHECK(glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_SHORT, m_blitStorage.m_indices->glPtr()));
OGLCHECK(glEnable(GL_DEPTH_TEST));
OGLCHECK(glEnable(GL_TEXTURE_2D));
OGLCHECK(glEnable(GL_BLEND));
/// This call is necessary to avoid parasite blitting in updateActualTarget() on IPhone.
OGLCHECK(glFinish());
resourceManager()->freeBlitStorage(m_blitStorage);
m_blitStorage = yg::gl::Storage();
}
}
}

View file

@ -27,7 +27,7 @@ namespace yg
typedef Clipper base_t;
void setupAuxVertexLayout(bool hasColor, bool hasTexture);
void setupAuxVertexLayout(bool hasColor, bool hasTexture, void * glPtr);
public:

View file

@ -19,7 +19,8 @@ namespace yg
size_t indicesCount)
{
vertices->makeCurrent();
Vertex::setupLayout();
/// it's important to setupLayout after vertices->makeCurrent
Vertex::setupLayout(vertices->glPtr());
indices->makeCurrent();
texture->makeCurrent();
@ -28,7 +29,7 @@ namespace yg
GL_TRIANGLES,
indicesCount,
GL_UNSIGNED_SHORT,
0));
indices->glPtr()));
}
}
}

View file

@ -32,14 +32,18 @@ namespace yg
indexBufferStack.pop_back();
}
IndexBuffer::IndexBuffer() : m_size(0), m_gpuData(0)
IndexBuffer::IndexBuffer(bool useVA)
: m_size(0), m_gpuData(0), m_useVA(useVA)
{
OGLCHECK(glGenBuffers(1, &m_id));
if (!m_useVA)
OGLCHECK(glGenBuffers(1, &m_id));
}
IndexBuffer::IndexBuffer(size_t size) : m_size(0), m_gpuData(0)
IndexBuffer::IndexBuffer(size_t size, bool useVA)
: m_size(0), m_gpuData(0), m_useVA(useVA)
{
OGLCHECK(glGenBuffers(1, &m_id));
if (!m_useVA)
OGLCHECK(glGenBuffers(1, &m_id));
resize(size);
}
@ -49,7 +53,13 @@ namespace yg
{
m_size = size;
makeCurrent();
OGLCHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_size, 0, GL_DYNAMIC_DRAW));
if (m_useVA)
{
delete [] (unsigned char*) m_gpuData;
m_gpuData = new unsigned char[size];
}
else
OGLCHECK(glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_size, 0, GL_DYNAMIC_DRAW));
}
}
@ -60,11 +70,15 @@ namespace yg
IndexBuffer::~IndexBuffer()
{
OGLCHECK(glDeleteBuffers(1, &m_id));
if (!m_useVA)
OGLCHECK(glDeleteBuffers(1, &m_id));
}
void * IndexBuffer::lock()
{
if (m_useVA)
return m_gpuData;
makeCurrent();
/// orphaning the old copy of the buffer data.
@ -82,6 +96,9 @@ namespace yg
void IndexBuffer::unlock()
{
if (m_useVA)
return;
ASSERT(m_gpuData != 0, ("IndexBuffer is not locked"));
makeCurrent();
#ifdef OMIM_GL_ES
@ -94,9 +111,20 @@ namespace yg
void IndexBuffer::makeCurrent()
{
if (m_useVA)
return;
if (m_id != current())
OGLCHECK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_id));
}
void * IndexBuffer::glPtr()
{
if (m_useVA)
return m_gpuData;
else
return 0;
}
}
}

View file

@ -11,11 +11,12 @@ namespace yg
unsigned int m_id;
unsigned int m_size;
void * m_gpuData;
bool m_useVA;
public:
IndexBuffer();
IndexBuffer(size_t size);
IndexBuffer(bool useVA);
IndexBuffer(size_t size, bool useVA);
~IndexBuffer();
void resize(size_t size);
@ -25,9 +26,12 @@ namespace yg
void * lock();
void unlock();
void * glPtr();
static void pushCurrent();
static void popCurrent();
static int current();
};
}
}

View file

@ -22,26 +22,31 @@ namespace yg
size_t blitVBSize, size_t blitIBSize, size_t blitStoragesCount,
size_t texWidth, size_t texHeight, size_t texCount,
char const * blocksFile, char const * whiteListFile, char const * blackListFile, size_t maxGlyphCacheSize,
RtFormat fmt)
RtFormat fmt,
bool useVA)
: m_textureWidth(texWidth), m_textureHeight(texHeight),
m_vbSize(vbSize), m_ibSize(ibSize),
m_smallVBSize(smallVBSize), m_smallIBSize(smallIBSize),
m_blitVBSize(blitVBSize), m_blitIBSize(blitIBSize),
m_glyphCache(GlyphCache::Params(blocksFile, whiteListFile, blackListFile, maxGlyphCacheSize)),
m_format(fmt)
m_format(fmt),
m_useVA(useVA)
{
if (useVA)
LOG(LINFO, ("buffer objects are unsupported. using client vertex array instead."));
for (size_t i = 0; i < storagesCount; ++i)
m_storages.push_back(gl::Storage(vbSize, ibSize));
m_storages.push_back(gl::Storage(vbSize, ibSize, m_useVA));
LOG(LINFO, ("allocating ", (vbSize + ibSize) * storagesCount, " bytes for main storage"));
for (size_t i = 0; i < smallStoragesCount; ++i)
m_smallStorages.push_back(gl::Storage(smallVBSize, smallIBSize));
m_smallStorages.push_back(gl::Storage(smallVBSize, smallIBSize, m_useVA));
LOG(LINFO, ("allocating ", (smallVBSize + smallIBSize) * smallStoragesCount, " bytes for small storage"));
for (size_t i = 0; i < blitStoragesCount; ++i)
m_blitStorages.push_back(gl::Storage(blitVBSize, blitIBSize));
m_blitStorages.push_back(gl::Storage(blitVBSize, blitIBSize, m_useVA));
LOG(LINFO, ("allocating ", (blitVBSize + blitIBSize) * blitStoragesCount, " bytes for blit storage"));
@ -227,11 +232,11 @@ namespace yg
threads::MutexGuard guard(m_mutex);
for (list<gl::Storage>::iterator it = m_storages.begin(); it != m_storages.end(); ++it)
*it = gl::Storage(m_vbSize, m_ibSize);
*it = gl::Storage(m_vbSize, m_ibSize, m_useVA);
for (list<gl::Storage>::iterator it = m_smallStorages.begin(); it != m_smallStorages.end(); ++it)
*it = gl::Storage(m_smallVBSize, m_smallIBSize);
*it = gl::Storage(m_smallVBSize, m_smallIBSize, m_useVA);
for (list<gl::Storage>::iterator it = m_blitStorages.begin(); it != m_blitStorages.end(); ++it)
*it = gl::Storage(m_blitVBSize, m_blitIBSize);
*it = gl::Storage(m_blitVBSize, m_blitIBSize, m_useVA);
for (list<shared_ptr<gl::BaseTexture> >::iterator it = m_dynamicTextures.begin(); it != m_dynamicTextures.end(); ++it)
*it = shared_ptr<gl::BaseTexture>(new TDynamicTexture(m_textureWidth, m_textureHeight));

View file

@ -63,6 +63,8 @@ namespace yg
RtFormat m_format;
bool m_useVA;
public:
ResourceManager(size_t vbSize, size_t ibSize, size_t storagesCount,
@ -70,7 +72,8 @@ namespace yg
size_t blitVBSize, size_t blitIBSize, size_t blitStoragesCount,
size_t texWidth, size_t texHeight, size_t texCount,
char const * blocksFile, char const * whileListFile, char const * blackListFile, size_t maxGlyphCacheSize,
RtFormat fmt);
RtFormat fmt,
bool useVA);
shared_ptr<gl::BaseTexture> const & getTexture(string const & fileName);

View file

@ -10,9 +10,9 @@ namespace yg
Storage::Storage()
{}
Storage::Storage(size_t vbSize, size_t ibSize) :
m_vertices(new VertexBuffer(vbSize)),
m_indices(new IndexBuffer(ibSize))
Storage::Storage(size_t vbSize, size_t ibSize, bool useVA) :
m_vertices(new VertexBuffer(vbSize, useVA)),
m_indices(new IndexBuffer(ibSize, useVA))
{}
}
}

View file

@ -16,7 +16,7 @@ namespace yg
shared_ptr<IndexBuffer> m_indices;
Storage();
Storage(size_t vbSize, size_t ibSize);
Storage(size_t vbSize, size_t ibSize, bool useVA);
};
}
}

View file

@ -29,14 +29,14 @@ namespace yg
return *this;
}
void Vertex::setupLayout()
void Vertex::setupLayout(void * glPtr)
{
OGLCHECK(glDisableClientState(GL_COLOR_ARRAY));
OGLCHECK(glEnableClientState(GL_VERTEX_ARRAY));
OGLCHECK(glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)Vertex::vertexOffset));
OGLCHECK(glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (void*)((char*)glPtr + Vertex::vertexOffset)));
OGLCHECK(glEnable(GL_TEXTURE_2D));
OGLCHECK(glEnableClientState(GL_TEXTURE_COORD_ARRAY));
OGLCHECK(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)Vertex::texCoordOffset));
OGLCHECK(glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), (void*)((char*)glPtr + Vertex::texCoordOffset)));
}
}
}

View file

@ -22,7 +22,7 @@ namespace yg
Vertex(Vertex const & v);
Vertex const & operator=(Vertex const & v);
static void setupLayout();
static void setupLayout(void * glPtr);
};
struct AuxVertex

View file

@ -32,14 +32,18 @@ namespace yg
vertexBufferStack.pop_back();
}
VertexBuffer::VertexBuffer() : m_size(0), m_gpuData(0)
VertexBuffer::VertexBuffer(bool useVA)
: m_size(0), m_gpuData(0), m_useVA(useVA)
{
OGLCHECK(glGenBuffers(1, &m_id));
if (!m_useVA)
OGLCHECK(glGenBuffers(1, &m_id));
}
VertexBuffer::VertexBuffer(size_t size) : m_size(0), m_gpuData(0)
VertexBuffer::VertexBuffer(size_t size, bool useVA)
: m_size(0), m_gpuData(0), m_useVA(useVA)
{
OGLCHECK(glGenBuffers(1, &m_id));
if (!m_useVA)
OGLCHECK(glGenBuffers(1, &m_id));
resize(size);
}
@ -49,7 +53,13 @@ namespace yg
{
m_size = size;
makeCurrent();
OGLCHECK(glBufferData(GL_ARRAY_BUFFER, m_size, 0, GL_DYNAMIC_DRAW));
if (m_useVA)
{
delete [] (unsigned char*)m_gpuData;
m_gpuData = new unsigned char [size];
}
else
OGLCHECK(glBufferData(GL_ARRAY_BUFFER, m_size, 0, GL_DYNAMIC_DRAW));
}
}
@ -60,11 +70,17 @@ namespace yg
VertexBuffer::~VertexBuffer()
{
OGLCHECK(glDeleteBuffers(1, &m_id));
if (m_useVA)
delete [] (unsigned char*)m_gpuData;
else
OGLCHECK(glDeleteBuffers(1, &m_id));
}
void * VertexBuffer::lock()
{
if (m_useVA)
return m_gpuData;
makeCurrent();
/// orphaning the old copy of the buffer data.
@ -82,6 +98,9 @@ namespace yg
void VertexBuffer::unlock()
{
if (m_useVA)
return;
ASSERT(m_gpuData != 0, ("VertexBuffer is not locked"));
makeCurrent();
#ifdef OMIM_GL_ES
@ -92,8 +111,18 @@ namespace yg
m_gpuData = 0;
}
void * VertexBuffer::glPtr() const
{
if (m_useVA)
return m_gpuData;
return 0;
}
void VertexBuffer::makeCurrent()
{
if (m_useVA)
return;
if (m_id != current())
OGLCHECK(glBindBuffer(GL_ARRAY_BUFFER, m_id));
}

View file

@ -12,10 +12,13 @@ namespace yg
unsigned int m_size;
void * m_gpuData;
/// using VA instead of buffer objects on some old GPU's
bool m_useVA;
public:
VertexBuffer();
VertexBuffer(size_t size);
VertexBuffer(bool useVA);
VertexBuffer(size_t size, bool useVA);
~VertexBuffer();
void resize(size_t size);
@ -24,6 +27,7 @@ namespace yg
void makeCurrent();
void * lock();
void unlock();
void * glPtr() const;
static unsigned current();
static void pushCurrent();