1 #include <assert.h>
2 #include <inttypes.h>
3 #include <string.h>
4 #ifndef LINUX_GNU
5 #include "GLee.h"
6 #else
7 #include <GLee.h>
8 #endif
9 #ifdef MAC
10 #include <OpenGL/CGLMacro.h>
11 //#include <OpenGL/gl.h>
12 #include <GLUT/glut.h>
13 #else
14 #include <GL/gl.h>
15 #include <GL/glut.h>
16 #endif
17
18 #include "base.h"
19 #include "Log.h"
20 #include "MathBase.h"
21 #include "Exception.h"
22 #include "DisplayOutput.h"
23 #include "RendererGL.h"
24 #include "TextureFlatGL.h"
25
26 namespace DisplayOutput
27 {
28
29 // These map 1:1 with eImageFormat in Image.h... *Keep them in sync!!!*
30 static const GLint internalFormats[] =
31 {
32 0,
33
34
35 GL_INTENSITY8,
36 GL_LUMINANCE8_ALPHA8,
37 GL_RGB8,
38 #ifdef MAC
39 GL_RGBA,
40 #else
41 GL_RGBA8,
42 #endif
43
44 GL_INTENSITY16,
45 GL_LUMINANCE16_ALPHA16,
46 GL_RGB16,
47 GL_RGBA16,
48
49 GL_INTENSITY_FLOAT16_ATI,
50 GL_LUMINANCE_ALPHA_FLOAT16_ATI,
51 GL_RGB_FLOAT16_ATI,
52 GL_RGBA_FLOAT16_ATI,
53
54 GL_INTENSITY_FLOAT32_ATI,
55 GL_LUMINANCE_ALPHA_FLOAT32_ATI,
56 GL_RGB_FLOAT32_ATI,
57 GL_RGBA_FLOAT32_ATI,
58
59 GL_RGBA4,
60 GL_RGB5,
61
62 GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
63 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
64 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
65
66 GL_DEPTH_COMPONENT16,
67 GL_DEPTH_COMPONENT24,
68 };
69
70 //
71 static const GLenum srcTypes[] =
72 {
73 0,
74
75 GL_UNSIGNED_BYTE,
76 GL_UNSIGNED_BYTE,
77 GL_UNSIGNED_BYTE,
78 #ifdef MAC
79 GL_UNSIGNED_INT_8_8_8_8_REV,
80 #else
81 GL_UNSIGNED_BYTE,
82 #endif
83
84 GL_UNSIGNED_SHORT,
85 GL_UNSIGNED_SHORT,
86 GL_UNSIGNED_SHORT,
87 GL_UNSIGNED_SHORT,
88
89 0,//GL_HALF_FLOAT_ARB,
90 0,//GL_HALF_FLOAT_ARB,
91 0,//GL_HALF_FLOAT_ARB,
92 0,//GL_HALF_FLOAT_ARB,
93
94 GL_FLOAT,
95 GL_FLOAT,
96 GL_FLOAT,
97 GL_FLOAT,
98
99 GL_UNSIGNED_SHORT_4_4_4_4_REV,
100 GL_UNSIGNED_SHORT_5_6_5,
101
102 0,
103 0,
104 0,
105
106 GL_UNSIGNED_SHORT,
107 GL_UNSIGNED_INT,
108 };
109
110 /*
111 */
112 #ifdef MAC
CTextureFlatGL(const uint32 _flags,CGLContextObj glCtx)113 CTextureFlatGL::CTextureFlatGL( const uint32 _flags, CGLContextObj glCtx ) : CTextureFlat( _flags )
114 #else
115 CTextureFlatGL::CTextureFlatGL( const uint32 _flags ) : CTextureFlat( _flags )
116 #endif
117 {
118 m_TexTarget = GL_TEXTURE_2D;
119
120 #ifdef MAC
121 cgl_ctx = glCtx;//CGLGetCurrentContext();
122
123 if ( _flags & kRectTexture )
124 m_TexTarget = GL_TEXTURE_RECTANGLE_EXT;
125 #endif
126
127 glGenTextures( (GLsizei)1, &m_TexID );
128 VERIFYGL;
129 }
130
131 /*
132 */
~CTextureFlatGL()133 CTextureFlatGL::~CTextureFlatGL()
134 {
135 glDeleteTextures( 1, &m_TexID );
136 VERIFYGL;
137 }
138
139 /*
140 */
Upload(spCImage _spImage)141 bool CTextureFlatGL::Upload( spCImage _spImage )
142 {
143 m_spImage = _spImage;
144
145 if (m_spImage==NULL) return false;
146
147 CImageFormat format = _spImage->GetFormat();
148
149 static const GLenum srcFormats[] =
150 {
151 0,
152 GL_LUMINANCE,
153 GL_LUMINANCE_ALPHA,
154 GL_RGB,
155 #ifdef MAC
156 GL_BGRA
157 #else
158 GL_RGBA
159 #endif
160 };
161
162 GLenum srcFormat = srcFormats[ format.GetChannels() ];
163 GLenum srcType = srcTypes[ format.getFormatEnum() ];
164 GLint internalFormat = internalFormats[ format.getFormatEnum() ];
165
166 if( format.isFloat() )
167 internalFormat = internalFormats[ format.getFormatEnum() - (eImage_RGBA32F - eImage_I16F)];
168
169 glBindTexture( m_TexTarget, m_TexID );
170
171 glTexParameteri( m_TexTarget, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
172 glTexParameteri( m_TexTarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
173
174 // Set filter modes.
175 glTexParameteri( m_TexTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
176 glTexParameteri( m_TexTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
177
178 // Upload it all
179 uint8 *pSrc;
180 uint32 mipMapLevel = 0;
181 while( (pSrc = _spImage->GetData( mipMapLevel ) ) != NULL )
182 {
183 if( format.isCompressed() )
184 {
185 // does the glCompressedTexImage2DARB need also power-of-two sized texture???
186 glCompressedTexImage2DARB( m_TexTarget, mipMapLevel, internalFormat, _spImage->GetWidth( mipMapLevel ), _spImage->GetHeight( mipMapLevel ), 0, _spImage->getMipMappedSize( mipMapLevel, 1 ), pSrc );
187
188 if (mipMapLevel == 0)
189 SetRect( Base::Math::CRect( 1, 1 ) );
190 }
191 else
192 {
193 uint32 imgWidth = _spImage->GetWidth( mipMapLevel );
194 uint32 imgHeight = _spImage->GetHeight( mipMapLevel );
195
196 uint32 texWidth, texHeight;
197
198 #ifdef MAC
199 GLint save2,
200 save3,
201 save4,
202 save5;
203
204 glGetIntegerv(GL_UNPACK_ALIGNMENT, &save2);
205 glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
206 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &save3);
207 glPixelStorei(GL_UNPACK_ROW_LENGTH, _spImage->GetPitch() / 4);
208 glGetIntegerv(GL_UNPACK_CLIENT_STORAGE_APPLE, &save4);
209 glGetIntegerv(GL_TEXTURE_STORAGE_HINT_APPLE, &save5);
210 #endif
211
212 #ifndef LINUX_GNU
213 if( GLEE_ARB_texture_non_power_of_two || m_TexTarget == GL_TEXTURE_RECTANGLE_EXT )
214 #else
215 if( GLEE_ARB_texture_non_power_of_two || m_TexTarget == GL_TEXTURE_RECTANGLE_ARB )
216
217 #endif
218 {
219 texWidth = imgWidth;
220 texHeight = imgHeight;
221 }
222 else
223 {
224 texWidth = Base::Math::UpperPowerOfTwo( _spImage->GetWidth( mipMapLevel ) );
225 texHeight = Base::Math::UpperPowerOfTwo( _spImage->GetHeight( mipMapLevel ) );
226 }
227
228 if ( texWidth == imgWidth && texHeight == imgHeight )
229 {
230 #ifdef MAC
231 //glTexParameteri(m_TexTarget, GL_TEXTURE_STORAGE_HINT_APPLE , GL_STORAGE_SHARED_APPLE);
232 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE);
233 #endif
234 glTexImage2D( m_TexTarget, mipMapLevel, internalFormat, texWidth, texHeight, 0, srcFormat, srcType, pSrc );
235
236 if ( mipMapLevel == 0 )
237 {
238 #ifndef LINUX_GNU
239 if ( m_TexTarget == GL_TEXTURE_RECTANGLE_EXT )
240 #else
241 if ( m_TexTarget == GL_TEXTURE_RECTANGLE_ARB )
242 #endif
243 SetRect( Base::Math::CRect( texWidth, texHeight ) );
244 else
245 SetRect( Base::Math::CRect( 1, 1 ) );
246 }
247 }
248 else
249 {
250 glTexImage2D( m_TexTarget, mipMapLevel, internalFormat, texWidth, texHeight, 0, srcFormat, srcType, NULL );
251 glTexSubImage2D( m_TexTarget, mipMapLevel, 0, 0, _spImage->GetWidth( mipMapLevel ), _spImage->GetHeight( mipMapLevel ), srcFormat, srcType, pSrc );
252
253 if (mipMapLevel == 0)
254 {
255 #ifndef LINUX_GNU
256 if ( m_TexTarget == GL_TEXTURE_RECTANGLE_EXT )
257 #else
258 if ( m_TexTarget == GL_TEXTURE_RECTANGLE_ARB )
259 #endif
260 SetRect( Base::Math::CRect( (fp4)imgWidth, (fp4)imgHeight ) );
261 else
262 SetRect( Base::Math::CRect( (fp4)imgWidth / (fp4)texWidth, (fp4)imgHeight / (fp4)texHeight ) );
263 }
264 }
265
266 #ifdef MAC
267 glTexParameteri(m_TexTarget, GL_TEXTURE_STORAGE_HINT_APPLE , save5);
268 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, save4);
269 glPixelStorei(GL_UNPACK_ROW_LENGTH, save3);
270 glPixelStorei(GL_UNPACK_ALIGNMENT, save2);
271 #endif
272 }
273
274 m_bufferCache = _spImage->GetStorageBuffer();
275
276 mipMapLevel++;
277 }
278
279 m_bDirty = true;
280
281 VERIFYGL;
282
283 glBindTexture( m_TexTarget, 0 );
284
285 return true;
286 }
287
288 /*
289 */
Bind(const uint32 _index)290 bool CTextureFlatGL::Bind( const uint32 _index )
291 {
292 glActiveTextureARB( GL_TEXTURE0 + _index );
293 glEnable( m_TexTarget );
294 glBindTexture( m_TexTarget, m_TexID );
295
296 m_bDirty = false;
297
298 VERIFYGL;
299 return true;
300 }
301
302 /*
303 */
Unbind(const uint32 _index)304 bool CTextureFlatGL::Unbind( const uint32 _index )
305 {
306 glActiveTextureARB( GL_TEXTURE0 + _index );
307 glBindTexture( m_TexTarget, 0 );
308 glDisable( m_TexTarget );
309 VERIFYGL;
310 return true;
311 }
312
313 }
314