summaryrefslogtreecommitdiff
path: root/src/graphics/VertexArray.cpp
diff options
context:
space:
mode:
authorDimitri John Ledkov <dimitri.ledkov@canonical.com>2014-02-20 16:10:52 +0000
committerDimitri John Ledkov <dimitri.ledkov@canonical.com>2014-02-20 19:15:57 +0000
commitd20f4a64eba38690337ac914a04a113de7caf125 (patch)
tree6828990e93ca5d8847b8cde2f2febb6566b0d53f /src/graphics/VertexArray.cpp
parent28161e9209f21be1a600f637565ecede94855a36 (diff)
New upstream release. Closes: #721047debian/1.8.0-1
Drop all patches, none are needed with this new upstream release. Port to dh. Specify foreign in configure.ac.
Diffstat (limited to 'src/graphics/VertexArray.cpp')
-rw-r--r--src/graphics/VertexArray.cpp217
1 files changed, 73 insertions, 144 deletions
diff --git a/src/graphics/VertexArray.cpp b/src/graphics/VertexArray.cpp
index 2b658e1..45da798 100644
--- a/src/graphics/VertexArray.cpp
+++ b/src/graphics/VertexArray.cpp
@@ -1,6 +1,6 @@
//
// libavg - Media Playback Engine.
-// Copyright (C) 2003-2011 Ulrich von Zadow
+// Copyright (C) 2003-2014 Ulrich von Zadow
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
@@ -22,6 +22,7 @@
#include "VertexArray.h"
#include "GLContext.h"
+#include "SubVertexArray.h"
#include "../base/Exception.h"
#include "../base/WideLine.h"
@@ -35,194 +36,122 @@ using namespace std;
using namespace boost;
namespace avg {
-
-const int MIN_VERTEXES = 100;
-const int MIN_INDEXES = 100;
+
+const unsigned VertexArray::TEX_INDEX = 0;
+const unsigned VertexArray::POS_INDEX = 1;
+const unsigned VertexArray::COLOR_INDEX = 2;
VertexArray::VertexArray(int reserveVerts, int reserveIndexes)
- : m_NumVerts(0),
- m_NumIndexes(0),
- m_ReserveVerts(reserveVerts),
- m_ReserveIndexes(reserveIndexes),
- m_bDataChanged(true)
+ : VertexData(reserveVerts, reserveIndexes)
{
- ObjectCounter::get()->incRef(&typeid(*this));
- if (m_ReserveVerts < MIN_VERTEXES) {
- m_ReserveVerts = MIN_VERTEXES;
- }
- if (m_ReserveIndexes < MIN_INDEXES) {
- m_ReserveIndexes = MIN_INDEXES;
- }
- m_pVertexData = new T2V3C4Vertex[m_ReserveVerts];
- m_pIndexData = new unsigned int[m_ReserveIndexes];
-
- if (m_ReserveVerts != MIN_VERTEXES || m_ReserveIndexes != MIN_INDEXES) {
+ GLContext* pContext = GLContext::getCurrent();
+ if (getReserveVerts() != MIN_VERTEXES || getReserveIndexes() != MIN_INDEXES) {
glproc::GenBuffers(1, &m_GLVertexBufferID);
glproc::GenBuffers(1, &m_GLIndexBufferID);
} else {
- GLContext* pContext = GLContext::getCurrent();
m_GLVertexBufferID = pContext->getVertexBufferCache().getBuffer();
m_GLIndexBufferID = pContext->getIndexBufferCache().getBuffer();
}
+ m_bUseMapBuffer = (!pContext->isGLES());
}
VertexArray::~VertexArray()
{
GLContext* pContext = GLContext::getCurrent();
if (pContext) {
- if (m_ReserveVerts == MIN_VERTEXES) {
+ if (getReserveVerts() == MIN_VERTEXES) {
pContext->getVertexBufferCache().returnBuffer(m_GLVertexBufferID);
} else {
glproc::DeleteBuffers(1, &m_GLVertexBufferID);
}
- if (m_ReserveIndexes == MIN_INDEXES) {
+ if (getReserveIndexes() == MIN_INDEXES) {
pContext->getIndexBufferCache().returnBuffer(m_GLIndexBufferID);
} else {
glproc::DeleteBuffers(1, &m_GLIndexBufferID);
}
}
- delete[] m_pVertexData;
- delete[] m_pIndexData;
- ObjectCounter::get()->decRef(&typeid(*this));
-}
-
-void VertexArray::appendPos(const DPoint& pos, const DPoint& texPos, const Pixel32& color)
-{
- if (m_NumVerts >= m_ReserveVerts-1) {
- grow();
- }
- T2V3C4Vertex* pVertex = &(m_pVertexData[m_NumVerts]);
- pVertex->m_Pos[0] = (GLfloat)pos.x;
- pVertex->m_Pos[1] = (GLfloat)pos.y;
- pVertex->m_Pos[2] = 0.0;
- pVertex->m_Tex[0] = (GLfloat)texPos.x;
- pVertex->m_Tex[1] = (GLfloat)texPos.y;
- pVertex->m_Color = color;
- m_bDataChanged = true;
- m_NumVerts++;
-}
-
-void VertexArray::appendTriIndexes(int v0, int v1, int v2)
-{
- if (m_NumIndexes >= m_ReserveIndexes-3) {
- grow();
- }
- m_pIndexData[m_NumIndexes] = v0;
- m_pIndexData[m_NumIndexes+1] = v1;
- m_pIndexData[m_NumIndexes+2] = v2;
- m_NumIndexes += 3;
}
-void VertexArray::appendQuadIndexes(int v0, int v1, int v2, int v3)
+void VertexArray::update()
{
- if (m_NumIndexes >= m_ReserveIndexes-6) {
- grow();
+ if (hasDataChanged()) {
+ transferBuffer(GL_ARRAY_BUFFER, m_GLVertexBufferID,
+ getReserveVerts()*sizeof(Vertex),
+ getNumVerts()*sizeof(Vertex), getVertexPointer());
+#ifdef AVG_ENABLE_EGL
+ transferBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID,
+ getReserveIndexes()*sizeof(unsigned short),
+ getNumIndexes()*sizeof(unsigned short), getIndexPointer());
+#else
+ transferBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID,
+ getReserveIndexes()*sizeof(unsigned int),
+ getNumIndexes()*sizeof(unsigned int), getIndexPointer());
+#endif
+ GLContext::checkError("VertexArray::update()");
}
- m_pIndexData[m_NumIndexes] = v0;
- m_pIndexData[m_NumIndexes+1] = v1;
- m_pIndexData[m_NumIndexes+2] = v2;
- m_pIndexData[m_NumIndexes+3] = v1;
- m_pIndexData[m_NumIndexes+4] = v2;
- m_pIndexData[m_NumIndexes+5] = v3;
- m_NumIndexes += 6;
-}
-
-void VertexArray::addLineData(Pixel32 color, const DPoint& p1, const DPoint& p2,
- double width, double tc1, double tc2)
-{
- WideLine wl(p1, p2, width);
- int curVertex = getCurVert();
- appendPos(wl.pl0, DPoint(tc1, 1), color);
- appendPos(wl.pr0, DPoint(tc1, 0), color);
- appendPos(wl.pl1, DPoint(tc2, 1), color);
- appendPos(wl.pr1, DPoint(tc2, 0), color);
- appendQuadIndexes(curVertex+1, curVertex, curVertex+3, curVertex+2);
-}
-
-void VertexArray::reset()
-{
- m_NumVerts = 0;
- m_NumIndexes = 0;
+ resetDataChanged();
}
-void VertexArray::update()
+void VertexArray::activate()
{
- if (m_bDataChanged) {
- glproc::BindBuffer(GL_ARRAY_BUFFER, m_GLVertexBufferID);
- glproc::BufferData(GL_ARRAY_BUFFER, m_ReserveVerts*sizeof(T2V3C4Vertex), 0,
- GL_DYNAMIC_DRAW);
- void * pBuffer = glproc::MapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
- memcpy(pBuffer, m_pVertexData, m_NumVerts*sizeof(T2V3C4Vertex));
- glproc::UnmapBuffer(GL_ARRAY_BUFFER);
-
- glproc::BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID);
- glproc::BufferData(GL_ELEMENT_ARRAY_BUFFER,
- m_ReserveIndexes*sizeof(unsigned int), 0, GL_DYNAMIC_DRAW);
- pBuffer = glproc::MapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
- memcpy(pBuffer, m_pIndexData, m_NumIndexes*sizeof(unsigned int));
- glproc::UnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
-
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "VertexArray::update");
- }
- m_bDataChanged = false;
+ glproc::BindBuffer(GL_ARRAY_BUFFER, m_GLVertexBufferID);
+ glproc::BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID);
+ glproc::VertexAttribPointer(TEX_INDEX, 2, GL_SHORT, GL_FALSE,
+ sizeof(Vertex), (void *)(offsetof(Vertex, m_Tex)));
+ glproc::VertexAttribPointer(POS_INDEX, 2, GL_FLOAT, GL_FALSE,
+ sizeof(Vertex), (void *)(offsetof(Vertex, m_Pos)));
+ glproc::VertexAttribPointer(COLOR_INDEX, 4, GL_UNSIGNED_BYTE, GL_TRUE,
+ sizeof(Vertex), (void *)(offsetof(Vertex, m_Color)));
+ glproc::EnableVertexAttribArray(TEX_INDEX);
+ glproc::EnableVertexAttribArray(POS_INDEX);
+ glproc::EnableVertexAttribArray(COLOR_INDEX);
+ GLContext::checkError("VertexArray::activate()");
}
void VertexArray::draw()
{
update();
- glproc::BindBuffer(GL_ARRAY_BUFFER, m_GLVertexBufferID);
- glTexCoordPointer(2, GL_FLOAT, sizeof(T2V3C4Vertex), 0);
- glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(T2V3C4Vertex),
- (void *)(offsetof(T2V3C4Vertex, m_Color)));
- glVertexPointer(3, GL_FLOAT, sizeof(T2V3C4Vertex),
- (void *)(offsetof(T2V3C4Vertex, m_Pos)));
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "VertexArray::draw:1");
-
- glproc::BindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_GLIndexBufferID);
- // TODO: glDrawRangeElements is allegedly faster.
- glDrawElements(GL_TRIANGLES, m_NumIndexes, GL_UNSIGNED_INT, 0);
- OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "VertexArray::draw():2");
+ activate();
+#ifdef AVG_ENABLE_EGL
+ glDrawElements(GL_TRIANGLES, getNumIndexes(), GL_UNSIGNED_SHORT, 0);
+#else
+ glDrawElements(GL_TRIANGLES, getNumIndexes(), GL_UNSIGNED_INT, 0);
+#endif
+ GLContext::checkError("VertexArray::draw()");
}
-int VertexArray::getCurVert() const
+void VertexArray::draw(unsigned startIndex, unsigned numIndexes, unsigned startVertex,
+ unsigned numVertexes)
{
- return m_NumVerts;
+#ifdef AVG_ENABLE_EGL
+ glDrawElements(GL_TRIANGLES, numIndexes, GL_UNSIGNED_SHORT,
+ (void *)(startIndex*sizeof(unsigned short)));
+#else
+ glDrawElements(GL_TRIANGLES, numIndexes, GL_UNSIGNED_INT,
+ (void *)(startIndex*sizeof(unsigned int)));
+#endif
+// XXX: Theoretically faster, but broken on Linux/Intel N10 graphics, Ubuntu 12/04
+// glproc::DrawRangeElements(GL_TRIANGLES, startVertex, startVertex+numVertexes,
+// numIndexes, GL_UNSIGNED_SHORT, (void *)(startIndex*sizeof(unsigned short)));
+ GLContext::checkError("VertexArray::draw()");
}
-int VertexArray::getCurIndex() const
+void VertexArray::startSubVA(SubVertexArray& subVA)
{
- return m_NumIndexes;
+ subVA.init(this, getNumVerts(), getNumIndexes());
}
-void VertexArray::grow()
+void VertexArray::transferBuffer(GLenum target, unsigned bufferID, unsigned reservedSize,
+ unsigned usedSize, const void* pData)
{
- bool bChanged = false;
- if (m_NumVerts >= m_ReserveVerts-1) {
- bChanged = true;
- int oldReserveVerts = m_ReserveVerts;
- m_ReserveVerts = int(m_ReserveVerts*1.5);
- if (m_ReserveVerts < m_NumVerts) {
- m_ReserveVerts = m_NumVerts;
- }
- T2V3C4Vertex* pVertexData = m_pVertexData;
- m_pVertexData = new T2V3C4Vertex[m_ReserveVerts];
- memcpy(m_pVertexData, pVertexData, sizeof(T2V3C4Vertex)*oldReserveVerts);
- delete[] pVertexData;
- }
- if (m_NumIndexes >= m_ReserveIndexes-6) {
- bChanged = true;
- int oldReserveIndexes = m_ReserveIndexes;
- m_ReserveIndexes = int(m_ReserveIndexes*1.5);
- if (m_ReserveIndexes < m_NumIndexes) {
- m_ReserveIndexes = m_NumIndexes;
- }
- unsigned int * pIndexData = m_pIndexData;
- m_pIndexData = new unsigned int[m_ReserveIndexes];
- memcpy(m_pIndexData, pIndexData, sizeof(unsigned int)*oldReserveIndexes);
- delete[] pIndexData;
- }
- if (bChanged) {
- m_bDataChanged = true;
+ glproc::BindBuffer(target, bufferID);
+ if (m_bUseMapBuffer) {
+ glproc::BufferData(target, reservedSize, 0, GL_STREAM_DRAW);
+ void * pBuffer = glproc::MapBuffer(target, GL_WRITE_ONLY);
+ memcpy(pBuffer, pData, usedSize);
+ glproc::UnmapBuffer(target);
+ } else {
+ glproc::BufferData(target, usedSize, pData, GL_STREAM_DRAW);
}
}