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