Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

UberTextures.cpp

00001 // Sh: A GPU metaprogramming language. 00002 // 00003 // Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory 00004 // Project administrator: Michael D. McCool 00005 // Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa, 00006 // Michael D. McCool 00007 // 00008 // This software is provided 'as-is', without any express or implied 00009 // warranty. In no event will the authors be held liable for any damages 00010 // arising from the use of this software. 00011 // 00012 // Permission is granted to anyone to use this software for any purpose, 00013 // including commercial applications, and to alter it and redistribute it 00014 // freely, subject to the following restrictions: 00015 // 00016 // 1. The origin of this software must not be misrepresented; you must 00017 // not claim that you wrote the original software. If you use this 00018 // software in a product, an acknowledgment in the product documentation 00019 // would be appreciated but is not required. 00020 // 00021 // 2. Altered source versions must be plainly marked as such, and must 00022 // not be misrepresented as being the original software. 00023 // 00024 // 3. This notice may not be removed or altered from any source 00025 // distribution. 00027 #include "UberTextures.hpp" 00028 #include "GlTextureName.hpp" 00029 #include "UberStorage.hpp" 00030 00031 namespace shgl { 00032 00033 using namespace SH; 00034 00035 const unsigned int shGlTargets[] = { 00036 GL_TEXTURE_1D, 00037 GL_TEXTURE_2D, 00038 GL_TEXTURE_RECTANGLE_NV, 00039 GL_TEXTURE_3D, 00040 GL_TEXTURE_CUBE_MAP, 00041 }; 00042 00043 const unsigned int shGlCubeMapTargets[] = { 00044 GL_TEXTURE_CUBE_MAP_POSITIVE_X, 00045 GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 00046 GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 00047 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 00048 GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 00049 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 00050 }; 00051 00052 ShCubeDirection glToShCubeDir(GLuint target) 00053 { 00054 switch (target) { 00055 case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 00056 return SH_CUBE_POS_X; 00057 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 00058 return SH_CUBE_NEG_X; 00059 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 00060 return SH_CUBE_POS_Y; 00061 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 00062 return SH_CUBE_NEG_Y; 00063 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 00064 return SH_CUBE_POS_Z; 00065 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 00066 return SH_CUBE_NEG_Z; 00067 } 00068 return SH_CUBE_POS_X; 00069 } 00070 00071 GLenum shGlInternalFormat(const ShTextureNodePtr& node) 00072 { 00073 // TODO: floating point etc. 00074 return node->size(); 00075 } 00076 00077 GLenum shGlFormat(const ShTextureNodePtr& node) 00078 { 00079 switch (node->size()) { 00080 case 1: 00081 return GL_LUMINANCE; 00082 case 2: 00083 return GL_LUMINANCE_ALPHA; 00084 case 3: 00085 return GL_RGB; 00086 case 4: 00087 return GL_RGBA; 00088 default: 00089 // TODO: Warn or something 00090 return 0; 00091 } 00092 } 00093 00094 struct StorageFinder { 00095 StorageFinder(const ShTextureNodePtr& node, int context, bool ignoreTarget = false) 00096 : node(node), context(context), ignoreTarget(ignoreTarget) 00097 { 00098 } 00099 00100 bool operator()(const ShStoragePtr& storage) const 00101 { 00102 UberStoragePtr t = shref_dynamic_cast<UberStorage>(storage); 00103 if (!t) return false; 00104 if (t->context() != context) return false; 00105 if (!ignoreTarget) { 00106 /* 00107 if (t->texName()->params() != node->traits()) return false; 00108 if (t->target() != shGlTargets[node->dims()]) return false; 00109 */ // TODO 00110 } 00111 if (t->width() != node->width()) return false; 00112 if (t->height() != node->height()) return false; 00113 if (t->pitch() != node->size()) return false; 00114 // if (t->depth() != node->depth()) return false; 00115 return true; 00116 } 00117 00118 const ShTextureNodePtr& node; 00119 int context; 00120 bool ignoreTarget; 00121 }; 00122 00123 00124 UberTextures::UberTextures(int context) 00125 : m_context(context) 00126 { 00127 } 00128 00129 void UberTextures::bindTexture(const ShTextureNodePtr& node, 00130 GLenum target) 00131 { 00132 if (!node) return; 00133 00134 00135 // TODO: Check for memories that are 0 00136 00137 if (node->dims() == SH_TEXTURE_CUBE) { 00138 // Look for a cubemap that happens to have just the right storages 00139 00140 /* TODO 00141 GlTextureName::NameList::const_iterator I; 00142 for (I = GlTextureName::beginNames(); I != GlTextureName::endNames(); ++I) { 00143 const GlTextureName* name = *I; 00144 if (name->target() != GL_TEXTURE_CUBE_MAP) continue; 00145 if (name->params() != node->traits()) continue; 00146 00147 GlTextureName::StorageList::const_iterator S; 00148 for (S = name->beginStorages(); S != name->endStorages(); ++S) { 00149 ShCubeDirection dir = glToShCubeDir((*S)->target()); 00150 if ((*S)->memory() != node->memory(dir).object() || !StorageFinder(node, m_context, true)(*S)) 00151 break; 00152 } 00153 // If we got through the whole list, we've found a matching list. 00154 if (S == name->endStorages()) break; 00155 } 00156 00157 if (I == GlTextureName::endNames()) { 00158 // Need to allocate new storages 00159 GlTextureNamePtr texname = new GlTextureName(GL_TEXTURE_CUBE_MAP); 00160 texname->params(node->traits()); 00161 for (int i = 0; i < 6; i++) { 00162 ShCubeDirection dir = static_cast<ShCubeDirection>(i); 00163 GlTextureStoragePtr storage = new GlTextureStorage(node->memory(dir).object(), 00164 shGlCubeMapTargets[i], 00165 shGlFormat(node), 00166 shGlInternalFormat(node), 00167 node->width(), node->height(), 00168 node->depth(), 00169 texname); 00170 storage->sync(); 00171 } 00172 SH_GL_CHECK_ERROR(glActiveTextureARB(target)); 00173 SH_GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_CUBE_MAP, texname->value())); 00174 } else { 00175 // Just synchronize the storages 00176 GlTextureName::StorageList::const_iterator S; 00177 for (S = (*I)->beginStorages(); S != (*I)->endStorages(); ++S) { 00178 (*S)->sync(); 00179 } 00180 SH_GL_CHECK_ERROR(glActiveTextureARB(target)); 00181 SH_GL_CHECK_ERROR(glBindTexture(GL_TEXTURE_CUBE_MAP, (*I)->value())); 00182 } 00183 */ 00184 } else { 00185 // Everything but cubemaps 00186 StorageFinder finder(node, m_context); 00187 UberStoragePtr storage = 00188 shref_dynamic_cast<UberStorage>(node->memory()->findStorage("uberbuffer", finder)); 00189 if (!storage) { 00190 GlTextureNamePtr name = new GlTextureName(shGlTargets[node->dims()]); 00191 storage = new UberStorage(m_context, 00192 node->memory().object(), name, 00193 node->width(), node->height(), node->size()); 00194 name->params(node->traits()); 00195 } 00196 storage->bindAsTexture(); 00197 00198 SH_GL_CHECK_ERROR(glActiveTextureARB(target)); 00199 storage->sync(); 00200 SH_GL_CHECK_ERROR(glBindTexture(shGlTargets[node->dims()], storage->textureName()->value())); 00201 } 00202 } 00203 00204 00205 }

Generated on Mon Oct 18 14:17:40 2004 for Sh by doxygen 1.3.7