kwin: Change the way attrib formats are stored in GLVertexBuffer
Store the formats as an array in GLVertexBufferPrivate. This simplifies the code for enabling the generic vertex arrays, and also makes it easier to add new arrays.
This commit is contained in:
parent
1de20a39a0
commit
395ff72555
1 changed files with 50 additions and 37 deletions
|
@ -1278,6 +1278,18 @@ private:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct VertexAttrib
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
GLenum type;
|
||||||
|
int offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//*********************************
|
//*********************************
|
||||||
// GLVertexBufferPrivate
|
// GLVertexBufferPrivate
|
||||||
//*********************************
|
//*********************************
|
||||||
|
@ -1286,14 +1298,11 @@ class GLVertexBufferPrivate
|
||||||
public:
|
public:
|
||||||
GLVertexBufferPrivate(GLVertexBuffer::UsageHint usageHint)
|
GLVertexBufferPrivate(GLVertexBuffer::UsageHint usageHint)
|
||||||
: vertexCount(0)
|
: vertexCount(0)
|
||||||
, dimension(2)
|
|
||||||
, useColor(false)
|
, useColor(false)
|
||||||
, useTexCoords(true)
|
|
||||||
, color(0, 0, 0, 255)
|
, color(0, 0, 0, 255)
|
||||||
, bufferSize(0)
|
, bufferSize(0)
|
||||||
, nextOffset(0)
|
, nextOffset(0)
|
||||||
, vertexAddress(0)
|
, baseAddress(0)
|
||||||
, texCoordAddress(0)
|
|
||||||
{
|
{
|
||||||
if (GLVertexBufferPrivate::supported)
|
if (GLVertexBufferPrivate::supported)
|
||||||
glGenBuffers(1, &buffer);
|
glGenBuffers(1, &buffer);
|
||||||
|
@ -1323,20 +1332,19 @@ public:
|
||||||
|
|
||||||
GLuint buffer;
|
GLuint buffer;
|
||||||
GLenum usage;
|
GLenum usage;
|
||||||
int vertexCount;
|
|
||||||
int dimension;
|
|
||||||
int stride;
|
int stride;
|
||||||
|
int vertexCount;
|
||||||
static bool supported;
|
static bool supported;
|
||||||
static GLVertexBuffer *streamingBuffer;
|
static GLVertexBuffer *streamingBuffer;
|
||||||
static bool hasMapBufferRange;
|
static bool hasMapBufferRange;
|
||||||
QByteArray dataStore;
|
QByteArray dataStore;
|
||||||
bool useColor;
|
bool useColor;
|
||||||
bool useTexCoords;
|
|
||||||
QVector4D color;
|
QVector4D color;
|
||||||
size_t bufferSize;
|
size_t bufferSize;
|
||||||
intptr_t nextOffset;
|
intptr_t nextOffset;
|
||||||
intptr_t vertexAddress;
|
intptr_t baseAddress;
|
||||||
intptr_t texCoordAddress;
|
VertexAttrib attrib[2];
|
||||||
|
Bitfield enabledArrays;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GLVertexBufferPrivate::supported = false;
|
bool GLVertexBufferPrivate::supported = false;
|
||||||
|
@ -1396,12 +1404,12 @@ void GLVertexBufferPrivate::bindArrays()
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||||
|
|
||||||
glVertexAttribPointer(VA_Position, dimension, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) vertexAddress);
|
BitfieldIterator it(enabledArrays);
|
||||||
glEnableVertexAttribArray(VA_Position);
|
while (it.hasNext()) {
|
||||||
|
const int index = it.next();
|
||||||
if (useTexCoords) {
|
glVertexAttribPointer(index, attrib[index].size, attrib[index].type, GL_FALSE, stride,
|
||||||
glVertexAttribPointer(VA_TexCoord, 2, GL_FLOAT, GL_FALSE, stride, (const GLvoid *) texCoordAddress);
|
(const GLvoid *) (baseAddress + attrib[index].offset));
|
||||||
glEnableVertexAttribArray(VA_TexCoord);
|
glEnableVertexAttribArray(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
@ -1413,11 +1421,13 @@ void GLVertexBufferPrivate::bindArrays()
|
||||||
// FIXME Is there any good reason to not leave this array permanently enabled?
|
// FIXME Is there any good reason to not leave this array permanently enabled?
|
||||||
// When do we not use it in the GL 1.x path?
|
// When do we not use it in the GL 1.x path?
|
||||||
glEnableClientState(GL_VERTEX_ARRAY);
|
glEnableClientState(GL_VERTEX_ARRAY);
|
||||||
glVertexPointer(dimension, GL_FLOAT, stride, (const GLvoid *) vertexAddress);
|
glVertexPointer(attrib[VA_Position].size, attrib[VA_Position].type, stride,
|
||||||
|
(const GLvoid *) (baseAddress + attrib[VA_Position].offset));
|
||||||
|
|
||||||
if (useTexCoords) {
|
if (enabledArrays[VA_TexCoord]) {
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
glTexCoordPointer(2, GL_FLOAT, stride, (const GLvoid *) texCoordAddress);
|
glTexCoordPointer(attrib[VA_TexCoord].size, attrib[VA_TexCoord].type, stride,
|
||||||
|
(const GLvoid *) (baseAddress + attrib[VA_TexCoord].offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (useColor)
|
if (useColor)
|
||||||
|
@ -1434,15 +1444,15 @@ void GLVertexBufferPrivate::unbindArrays()
|
||||||
#ifndef KWIN_HAVE_OPENGLES
|
#ifndef KWIN_HAVE_OPENGLES
|
||||||
if (ShaderManager::instance()->isShaderBound()) {
|
if (ShaderManager::instance()->isShaderBound()) {
|
||||||
#endif
|
#endif
|
||||||
glDisableVertexAttribArray(VA_Position);
|
BitfieldIterator it(enabledArrays);
|
||||||
|
while (it.hasNext())
|
||||||
if (useTexCoords) {
|
glDisableVertexAttribArray(it.next());
|
||||||
glDisableVertexAttribArray(VA_TexCoord);
|
|
||||||
}
|
|
||||||
#ifndef KWIN_HAVE_OPENGLES
|
#ifndef KWIN_HAVE_OPENGLES
|
||||||
} else {
|
} else {
|
||||||
// Assume that the conventional arrays were enabled
|
// Assume that the conventional arrays were enabled
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
|
||||||
|
if (enabledArrays[VA_TexCoord])
|
||||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1496,10 +1506,19 @@ GLVertexBuffer::~GLVertexBuffer()
|
||||||
void GLVertexBuffer::setData(int vertexCount, int dim, const float* vertices, const float* texcoords)
|
void GLVertexBuffer::setData(int vertexCount, int dim, const float* vertices, const float* texcoords)
|
||||||
{
|
{
|
||||||
d->vertexCount = vertexCount;
|
d->vertexCount = vertexCount;
|
||||||
d->dimension = dim;
|
|
||||||
d->useTexCoords = (texcoords != NULL);
|
|
||||||
d->stride = (dim + (texcoords ? 2 : 0)) * sizeof(float);
|
d->stride = (dim + (texcoords ? 2 : 0)) * sizeof(float);
|
||||||
|
|
||||||
|
d->attrib[VA_Position].size = dim;
|
||||||
|
d->attrib[VA_Position].type = GL_FLOAT;
|
||||||
|
d->attrib[VA_Position].offset = 0;
|
||||||
|
|
||||||
|
d->attrib[VA_TexCoord].size = 2;
|
||||||
|
d->attrib[VA_TexCoord].type = GL_FLOAT;
|
||||||
|
d->attrib[VA_TexCoord].offset = dim * sizeof(float);
|
||||||
|
|
||||||
|
d->enabledArrays[VA_Position] = true;
|
||||||
|
d->enabledArrays[VA_TexCoord] = texcoords != 0;
|
||||||
|
|
||||||
size_t size = vertexCount * d->stride;
|
size_t size = vertexCount * d->stride;
|
||||||
|
|
||||||
if (!GLVertexBufferPrivate::supported) {
|
if (!GLVertexBufferPrivate::supported) {
|
||||||
|
@ -1507,11 +1526,9 @@ void GLVertexBuffer::setData(int vertexCount, int dim, const float* vertices, co
|
||||||
if (size_t(d->dataStore.size()) < size)
|
if (size_t(d->dataStore.size()) < size)
|
||||||
d->dataStore.resize(size);
|
d->dataStore.resize(size);
|
||||||
|
|
||||||
d->interleaveArrays((float *) d->dataStore.data(),
|
d->baseAddress = intptr_t(d->dataStore.data());
|
||||||
|
d->interleaveArrays((float *) d->baseAddress,
|
||||||
dim, vertices, texcoords, vertexCount);
|
dim, vertices, texcoords, vertexCount);
|
||||||
|
|
||||||
d->vertexAddress = intptr_t(d->dataStore.data());
|
|
||||||
d->texCoordAddress = d->vertexAddress + dim * sizeof(float);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1523,14 +1540,13 @@ void GLVertexBuffer::setData(int vertexCount, int dim, const float* vertices, co
|
||||||
d->interleaveArrays(map, dim, vertices, texcoords, vertexCount);
|
d->interleaveArrays(map, dim, vertices, texcoords, vertexCount);
|
||||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||||
|
|
||||||
d->vertexAddress = d->nextOffset;
|
d->baseAddress = d->nextOffset;
|
||||||
d->texCoordAddress = d->nextOffset + d->dimension * sizeof(float);
|
|
||||||
d->nextOffset += align(size, 16); // Align to 16 bytes for SSE
|
d->nextOffset += align(size, 16); // Align to 16 bytes for SSE
|
||||||
} else {
|
} else {
|
||||||
// We always reallocate the data store when we can't map the buffer.
|
// We always reallocate the data store when we can't map the buffer.
|
||||||
// The rationale is that there will almost always be contention
|
// The rationale is that there will almost always be contention
|
||||||
// in a glBufferSubData() call.
|
// in a glBufferSubData() call.
|
||||||
if (d->useTexCoords) {
|
if (texcoords) {
|
||||||
QByteArray array;
|
QByteArray array;
|
||||||
array.resize(size);
|
array.resize(size);
|
||||||
|
|
||||||
|
@ -1539,8 +1555,7 @@ void GLVertexBuffer::setData(int vertexCount, int dim, const float* vertices, co
|
||||||
} else
|
} else
|
||||||
glBufferData(GL_ARRAY_BUFFER, size, vertices, d->usage);
|
glBufferData(GL_ARRAY_BUFFER, size, vertices, d->usage);
|
||||||
|
|
||||||
d->vertexAddress = 0;
|
d->baseAddress = 0;
|
||||||
d->texCoordAddress = d->dimension * sizeof(float);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
@ -1594,8 +1609,6 @@ void GLVertexBuffer::reset()
|
||||||
d->useColor = false;
|
d->useColor = false;
|
||||||
d->color = QVector4D(0, 0, 0, 1);
|
d->color = QVector4D(0, 0, 0, 1);
|
||||||
d->vertexCount = 0;
|
d->vertexCount = 0;
|
||||||
d->dimension = 2;
|
|
||||||
d->useTexCoords = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLVertexBuffer::initStatic()
|
void GLVertexBuffer::initStatic()
|
||||||
|
|
Loading…
Reference in a new issue