Back to index

nux  3.0.0
IOpenGLVolumeTexture.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2010 Inalogic® Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License, as
00006  * published by the  Free Software Foundation; either version 2.1 or 3.0
00007  * of the License.
00008  *
00009  * This program is distributed in the hope that it will be useful, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License along with this program. If not, see <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00019  *
00020  */
00021 
00022 
00023 #include "GLDeviceObjects.h"
00024 #include "IOpenGLVolumeTexture.h"
00025 
00026 namespace nux
00027 {
00028 
00029   NUX_IMPLEMENT_OBJECT_TYPE(IOpenGLVolumeTexture);
00030 
00031   IOpenGLVolumeTexture::IOpenGLVolumeTexture(
00032     int Width
00033     , int Height
00034     , int Depth
00035     , int Levels
00036     , BitmapFormat PixelFormat)
00037     : IOpenGLBaseTexture(RTVOLUMETEXTURE, Width, Height, Depth, Levels, PixelFormat)
00038   {
00039 #ifndef NUX_OPENGLES_20
00040     CHECKGL(glGenTextures(1, &_OpenGLID));
00041     CHECKGL(glBindTexture(GL_TEXTURE_3D, _OpenGLID));
00042 
00043     _VolumeSurfaceArray = new std::vector< ObjectPtr<IOpenGLSurface> >[_NumMipLevel];
00044 
00045     for (int mip = 0; mip < _NumMipLevel; mip++)
00046     {
00047       for (int slice = 0; slice < ImageSurface::GetLevelDim(_PixelFormat, _Depth, mip); slice++)
00048       {
00049         //IOpenGLSurface* surface = new IOpenGLSurface(this, _OpenGLID, GL_TEXTURE_3D, GL_TEXTURE_3D, mip, slice);
00050         //surface->InitializeLevel();
00051         IOpenGLSurface* surface = new IOpenGLSurface(this, _OpenGLID, GL_TEXTURE_3D, GL_TEXTURE_3D, mip, slice);
00052         _VolumeSurfaceArray[mip].push_back(ObjectPtr<IOpenGLSurface> (surface));
00053         surface->UnReference();
00054       }
00055     }
00056 
00057     for (int mip = 0; mip < _NumMipLevel; mip++)
00058     {
00059       IOpenGLVolume *volume = new IOpenGLVolume(this, _OpenGLID, GL_TEXTURE_3D, GL_TEXTURE_3D, mip);
00060       volume->InitializeLevel();
00061       _VolumeArray.push_back(ObjectPtr<IOpenGLVolume> (volume));
00062     }
00063 
00064     CHECKGL(glBindTexture(GL_TEXTURE_3D, _OpenGLID));
00065     SetFiltering(GL_NEAREST, GL_NEAREST);
00066     SetWrap(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
00067     SetRenderStates();
00068     GRunTimeStats.Register(this);
00069 #endif
00070   }
00071 
00072   IOpenGLVolumeTexture::~IOpenGLVolumeTexture()
00073   {
00074 
00075     for (int mip = 0; mip < _NumMipLevel; mip++)
00076     {
00077       for (int slice = 0; slice < ImageSurface::GetLevelDim(_PixelFormat, _Depth, mip); slice++)
00078       {
00079         // destroying a surface
00080         _VolumeSurfaceArray[mip][slice] = ObjectPtr<IOpenGLSurface> (0);
00081       }
00082 
00083       _VolumeSurfaceArray[mip].clear();
00084     }
00085 
00086     NUX_SAFE_DELETE_ARRAY(_VolumeSurfaceArray);
00087 
00088 
00089     for (int mip = 0; mip < _NumMipLevel; mip++)
00090     {
00091       // destroying a IOpenGLVolume
00092       _VolumeArray[mip] = ObjectPtr<IOpenGLVolume> (0);
00093     }
00094 
00095     CHECKGL(glDeleteTextures(1, &_OpenGLID));
00096     _OpenGLID = 0;
00097     GRunTimeStats.UnRegister(this);
00098   }
00099 
00100   int IOpenGLVolumeTexture::LockRect(
00101     int Slice,
00102     int Level,
00103     SURFACE_LOCKED_RECT *pLockedRect,
00104     const SURFACE_RECT *pRect)
00105   {
00106     nuxAssertMsg(pLockedRect, "[IOpenGLVolumeTexture::LockRect] Invalid parameter 'pLockedRect'.");
00107     nuxAssertMsg(Level >= 0, "[IOpenGLVolumeTexture::LockRect] Invalid mipmap level.");
00108     nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLVolumeTexture::LockRect] Invalid mipmap level.");
00109     nuxAssertMsg(Slice >= 0, "[IOpenGLVolumeTexture::LockRect] Invalid slice index.");
00110     nuxAssertMsg(Slice < ImageSurface::GetLevelDim(_PixelFormat, _Depth, Level), "[IOpenGLVolumeTexture::LockRect] Invalid slice index.");
00111 
00112     if (Slice < 0)
00113       Slice = 0;
00114 
00115     if (Slice >= _Depth)
00116       Slice = _Depth - 1;
00117 
00118     if (Level < _NumMipLevel)
00119     {
00120       ObjectPtr<IOpenGLSurface> pVolumeSurfaceLevel = _VolumeSurfaceArray[Level][Slice];
00121       return pVolumeSurfaceLevel->LockRect(pLockedRect, pRect);
00122     }
00123     else
00124     {
00125       pLockedRect->pBits = 0;
00126       pLockedRect->Pitch = 0;
00127       return OGL_INVALID_SURFACE_LEVEL;
00128     }
00129 
00130     return OGL_OK;
00131   }
00132 
00133   int IOpenGLVolumeTexture::UnlockRect(
00134     int Slice,
00135     int Level
00136   )
00137   {
00138     nuxAssertMsg(Level >= 0, "[IOpenGLVolumeTexture::LockRect] Invalid mipmap level.");
00139     nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLVolumeTexture::LockRect] Invalid mipmap level.");
00140 
00141     if (Level < _NumMipLevel)
00142     {
00143       ObjectPtr<IOpenGLSurface> pVolumeSurfaceLevel = _VolumeSurfaceArray[Level][Slice];
00144       return pVolumeSurfaceLevel->UnlockRect();
00145     }
00146     else
00147     {
00148       return OGL_INVALID_SURFACE_LEVEL;
00149     }
00150 
00151     return OGL_OK;
00152   }
00153 
00154   int IOpenGLVolumeTexture::LockBox(int Level,
00155                                      VOLUME_LOCKED_BOX *pLockedVolume,
00156                                      const VOLUME_BOX *pBox)
00157   {
00158     nuxAssertMsg(pLockedVolume, "[IOpenGLVolumeTexture::LockBox] Invalid parameter 'pLockedRect'.");
00159     nuxAssertMsg(Level >= 0, "[IOpenGLVolumeTexture::LockBox] Invalid mipmap level.");
00160     nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLVolumeTexture::LockBox] Invalid mipmap level.");
00161 
00162     if (pBox)
00163     {
00164       nuxAssertMsg(pBox->Front >= 0, "[IOpenGLVolumeTexture::LockBox] Invalid slice index.");
00165       nuxAssertMsg(pBox->Front < pBox->Back, "[IOpenGLVolumeTexture::LockBox] Invalid slice index.");
00166       nuxAssertMsg(pBox->Back <= ImageSurface::GetLevelDim(_PixelFormat, _Depth, Level),
00167                     "[IOpenGLVolumeTexture::LockBox] Invalid slice index.");
00168     }
00169 
00170     return _VolumeArray[Level]->LockBox(pLockedVolume, pBox);
00171   }
00172 
00173   int IOpenGLVolumeTexture::UnlockBox(int Level)
00174   {
00175     nuxAssertMsg(Level >= 0, "[IOpenGLVolumeTexture::LockBox] Invalid mipmap level.");
00176     nuxAssertMsg(Level < _NumMipLevel, "[IOpenGLVolumeTexture::LockBox] Invalid mipmap level.");
00177 
00178     return _VolumeArray[Level]->UnlockBox();
00179   }
00180 
00181 }
00182