00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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
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
00108
00109
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
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
00136
00137
if (node->dims() == SH_TEXTURE_CUBE) {
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 }
else {
00185
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 }