diff options
author | Dimitri John Ledkov <dimitri.ledkov@canonical.com> | 2014-02-20 16:10:52 +0000 |
---|---|---|
committer | Dimitri John Ledkov <dimitri.ledkov@canonical.com> | 2014-02-20 19:15:57 +0000 |
commit | d20f4a64eba38690337ac914a04a113de7caf125 (patch) | |
tree | 6828990e93ca5d8847b8cde2f2febb6566b0d53f /src/graphics/VertexArray.cpp | |
parent | 28161e9209f21be1a600f637565ecede94855a36 (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.cpp | 217 |
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); } } |