2
// libavg - Media Playback Engine.
3
// Copyright (C) 2003-2008 Ulrich von Zadow
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2 of the License, or (at your option) any later version.
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
// Current versions can be found at www.libavg.de
22
#include "PBOTexture.h"
23
#include "SDLDisplayEngine.h"
24
#include "../graphics/VertexArray.h"
25
#include "../base/Logger.h"
26
#include "../base/Exception.h"
27
#include "../base/ScopeTimer.h"
28
#include "../base/ObjectCounter.h"
29
#include "../base/MathHelper.h"
30
#include "../base/StringHelper.h"
39
PBOTexture::PBOTexture(IntPoint size, PixelFormat pf, const MaterialInfo& material,
40
SDLDisplayEngine * pEngine, OGLMemoryMode memoryMode)
44
m_MemoryMode(memoryMode)
46
ObjectCounter::get()->incRef(&typeid(*this));
48
if (pEngine->usePOTTextures()) {
49
m_Size.x = nextpow2(m_ActiveSize.x);
50
m_Size.y = nextpow2(m_ActiveSize.y);
52
m_Size = m_ActiveSize;
54
if (m_Size.x > pEngine->getMaxTexSize() || m_Size.y > pEngine->getMaxTexSize()) {
55
throw Exception(AVG_ERR_VIDEO_GENERAL, "Texture too large (" +toString(m_Size)
56
+ "). Maximum supported by graphics card is "
57
+ toString(pEngine->getMaxTexSize()));
63
PBOTexture::~PBOTexture()
65
ObjectCounter::get()->decRef(&typeid(*this));
68
BitmapPtr PBOTexture::lockBmp()
70
if (m_MemoryMode == MM_PBO) {
71
return m_pWritePBO->lock();
77
void PBOTexture::unlockBmp()
79
if (m_MemoryMode == MM_PBO) {
80
m_pWritePBO->unlock();
84
BitmapPtr PBOTexture::readbackBmp()
86
if (m_MemoryMode == MM_PBO) {
88
m_pReadPBO = PBOPtr(new PBO(m_Size, m_pf, GL_DYNAMIC_READ));
90
return m_pReadPBO->moveTextureToBmp(m_pTex);
92
return BitmapPtr(new Bitmap(*m_pBmp));
96
static ProfilingZoneID TexSubImageProfilingZone("Texture download");
98
void PBOTexture::download() const
100
ScopeTimer Timer(TexSubImageProfilingZone);
101
if (m_MemoryMode == MM_PBO) {
102
m_pWritePBO->movePBOToTexture(m_pTex);
103
if (m_pTex->hasMipmaps()) {
104
m_pTex->generateMipmaps();
108
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
109
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
110
OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "PBOTexture::download: GL_UNPACK_ALIGNMENT");
111
unsigned char * pStartPos = m_pBmp->getPixels();
112
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_ActiveSize.x, m_ActiveSize.y,
113
m_pTex->getGLFormat(m_pf), m_pTex->getGLType(m_pf),
115
OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "PBOTexture::download: glTexSubImage2D()");
119
void PBOTexture::setTex(GLTexturePtr pTex)
121
AVG_ASSERT(m_MemoryMode == MM_PBO);
127
void PBOTexture::activate(int textureUnit)
129
m_pTex->activate(textureUnit);
132
void PBOTexture::setMaterial(const MaterialInfo& material)
134
if (m_Material.getUseMipmaps() != material.getUseMipmaps()) {
135
m_Material = material;
138
m_Material = material;
142
const IntPoint& PBOTexture::getTextureSize() const
147
void PBOTexture::createBitmap()
149
switch (m_MemoryMode) {
152
m_pWritePBO = PBOPtr(new PBO(m_ActiveSize, m_pf, GL_DYNAMIC_DRAW));
153
m_pBmp = BitmapPtr();
157
m_pBmp = BitmapPtr(new Bitmap(m_ActiveSize, m_pf));
164
void PBOTexture::createTexture()
166
m_pTex = GLTexturePtr(new GLTexture(m_Size, m_pf, m_Material.getUseMipmaps(),
167
m_Material.getTexWrapSMode(), m_Material.getTexWrapTMode()));
169
if (m_pEngine->usePOTTextures()) {
170
// Make sure the texture is transparent and black before loading stuff
171
// into it to avoid garbage at the borders.
172
int TexMemNeeded = m_Size.x*m_Size.y*Bitmap::getBytesPerPixel(m_pf);
173
char * pPixels = new char[TexMemNeeded];
174
memset(pPixels, 0, TexMemNeeded);
175
glTexImage2D(GL_TEXTURE_2D, 0, m_pTex->getGLInternalFormat(), m_Size.x,
176
m_Size.y, 0, m_pTex->getGLFormat(m_pf), m_pTex->getGLType(m_pf), pPixels);
177
OGLErrorCheck(AVG_ERR_VIDEO_GENERAL, "PBOTexture::createTexture: glTexImage2D()");