d07c171f |
1 | /* |
2 | Copyright (C) 2003 Rice1964 |
3 | |
4 | This program is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU General Public License |
6 | as published by the Free Software Foundation; either version 2 |
7 | of the License, or (at your option) any later version. |
8 | |
9 | This program is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | GNU General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program; if not, write to the Free Software |
16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
17 | */ |
18 | |
19 | #include "osal_opengl.h" |
20 | |
21 | #if SDL_VIDEO_OPENGL |
22 | #include "OGLExtensions.h" |
23 | #endif |
24 | #include "OGLDebug.h" |
25 | #include "OGLExtRender.h" |
26 | #include "OGLTexture.h" |
27 | |
28 | void COGLExtRender::Initialize(void) |
29 | { |
30 | OGLRender::Initialize(); |
31 | |
32 | // Initialize multitexture |
33 | glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&m_maxTexUnits); |
34 | OPENGL_CHECK_ERRORS; |
35 | |
36 | for( int i=0; i<8; i++ ) |
37 | m_textureUnitMap[i] = -1; |
38 | m_textureUnitMap[0] = 0; // T0 is usually using texture unit 0 |
39 | m_textureUnitMap[1] = 1; // T1 is usually using texture unit 1 |
40 | } |
41 | |
42 | |
43 | void COGLExtRender::BindTexture(GLuint texture, int unitno) |
44 | { |
45 | if( m_bEnableMultiTexture ) |
46 | { |
47 | if( unitno < m_maxTexUnits ) |
48 | { |
49 | if( m_curBoundTex[unitno] != texture ) |
50 | { |
51 | pglActiveTexture(GL_TEXTURE0_ARB+unitno); |
52 | OPENGL_CHECK_ERRORS; |
53 | glBindTexture(GL_TEXTURE_2D,texture); |
54 | OPENGL_CHECK_ERRORS; |
55 | m_curBoundTex[unitno] = texture; |
56 | } |
57 | } |
58 | } |
59 | else |
60 | { |
61 | OGLRender::BindTexture(texture, unitno); |
62 | } |
63 | } |
64 | |
65 | void COGLExtRender::DisBindTexture(GLuint texture, int unitno) |
66 | { |
67 | if( m_bEnableMultiTexture ) |
68 | { |
69 | pglActiveTexture(GL_TEXTURE0_ARB+unitno); |
70 | OPENGL_CHECK_ERRORS; |
71 | glBindTexture(GL_TEXTURE_2D, 0); //Not to bind any texture |
72 | OPENGL_CHECK_ERRORS; |
73 | } |
74 | else |
75 | OGLRender::DisBindTexture(texture, unitno); |
76 | } |
77 | |
78 | void COGLExtRender::TexCoord2f(float u, float v) |
79 | { |
80 | #if SDL_VIDEO_OPENGL |
81 | if( m_bEnableMultiTexture ) |
82 | { |
83 | //printf("*SEB* overloaded TexCoord2f(%f, %f)\n", u, v); |
84 | for( int i=0; i<8; i++ ) |
85 | { |
86 | if( m_textureUnitMap[i] >= 0 ) |
87 | { |
88 | pglMultiTexCoord2f(GL_TEXTURE0_ARB+i, u, v); |
89 | } |
90 | } |
91 | } |
92 | else |
93 | { |
94 | OGLRender::TexCoord2f(u,v); |
95 | } |
96 | #endif |
97 | } |
98 | |
99 | void COGLExtRender::TexCoord(TLITVERTEX &vtxInfo) |
100 | { |
101 | #if SDL_VIDEO_OPENGL |
102 | if( m_bEnableMultiTexture ) |
103 | { |
104 | //printf("*SEB* overloaded TexCoord(%f, %f)\n", vtxInfo.tcord[0].u, vtxInfo.tcord[0].v); |
105 | for( int i=0; i<8; i++ ) |
106 | { |
107 | if( m_textureUnitMap[i] >= 0 ) |
108 | { |
109 | pglMultiTexCoord2fv(GL_TEXTURE0_ARB+i, &(vtxInfo.tcord[m_textureUnitMap[i]].u)); |
110 | } |
111 | } |
112 | } |
113 | else |
114 | { |
115 | OGLRender::TexCoord(vtxInfo); |
116 | } |
117 | #endif |
118 | } |
119 | |
120 | |
121 | void COGLExtRender::SetTexWrapS(int unitno,GLuint flag) |
122 | { |
123 | static GLuint mflag[8]; |
124 | static GLuint mtex[8]; |
125 | if( m_curBoundTex[unitno] != mtex[unitno] || mflag[unitno] != flag ) |
126 | { |
127 | mtex[unitno] = m_curBoundTex[0]; |
128 | mflag[unitno] = flag; |
129 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, flag); |
130 | OPENGL_CHECK_ERRORS; |
131 | } |
132 | } |
133 | void COGLExtRender::SetTexWrapT(int unitno,GLuint flag) |
134 | { |
135 | static GLuint mflag[8]; |
136 | static GLuint mtex[8]; |
137 | if( m_curBoundTex[unitno] != mtex[unitno] || mflag[unitno] != flag ) |
138 | { |
139 | mtex[unitno] = m_curBoundTex[0]; |
140 | mflag[unitno] = flag; |
141 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, flag); |
142 | OPENGL_CHECK_ERRORS; |
143 | } |
144 | } |
145 | |
146 | extern UVFlagMap OGLXUVFlagMaps[]; |
147 | void COGLExtRender::SetTextureUFlag(TextureUVFlag dwFlag, uint32 dwTile) |
148 | { |
149 | TileUFlags[dwTile] = dwFlag; |
150 | if( !m_bEnableMultiTexture ) |
151 | { |
152 | OGLRender::SetTextureUFlag(dwFlag, dwTile); |
153 | return; |
154 | } |
155 | |
156 | int tex; |
157 | if( dwTile == gRSP.curTile ) |
158 | tex=0; |
159 | else if( dwTile == ((gRSP.curTile+1)&7) ) |
160 | tex=1; |
161 | else |
162 | { |
163 | if( dwTile == ((gRSP.curTile+2)&7) ) |
164 | tex=2; |
165 | else if( dwTile == ((gRSP.curTile+3)&7) ) |
166 | tex=3; |
167 | else |
168 | { |
169 | TRACE2("Incorrect tile number for OGL SetTextureUFlag: cur=%d, tile=%d", gRSP.curTile, dwTile); |
170 | return; |
171 | } |
172 | } |
173 | |
174 | for( int textureNo=0; textureNo<8; textureNo++) |
175 | { |
176 | if( m_textureUnitMap[textureNo] == tex ) |
177 | { |
178 | pglActiveTexture(GL_TEXTURE0_ARB+textureNo); |
179 | OPENGL_CHECK_ERRORS; |
180 | COGLTexture* pTexture = g_textures[(gRSP.curTile+tex)&7].m_pCOGLTexture; |
181 | if( pTexture ) |
182 | { |
183 | EnableTexUnit(textureNo,TRUE); |
184 | BindTexture(pTexture->m_dwTextureName, textureNo); |
185 | } |
186 | SetTexWrapS(textureNo, OGLXUVFlagMaps[dwFlag].realFlag); |
187 | } |
188 | } |
189 | } |
190 | void COGLExtRender::SetTextureVFlag(TextureUVFlag dwFlag, uint32 dwTile) |
191 | { |
192 | TileVFlags[dwTile] = dwFlag; |
193 | if( !m_bEnableMultiTexture ) |
194 | { |
195 | OGLRender::SetTextureVFlag(dwFlag, dwTile); |
196 | return; |
197 | } |
198 | |
199 | int tex; |
200 | if( dwTile == gRSP.curTile ) |
201 | tex=0; |
202 | else if( dwTile == ((gRSP.curTile+1)&7) ) |
203 | tex=1; |
204 | else |
205 | { |
206 | if( dwTile == ((gRSP.curTile+2)&7) ) |
207 | tex=2; |
208 | else if( dwTile == ((gRSP.curTile+3)&7) ) |
209 | tex=3; |
210 | else |
211 | { |
212 | TRACE2("Incorrect tile number for OGL SetTextureVFlag: cur=%d, tile=%d", gRSP.curTile, dwTile); |
213 | return; |
214 | } |
215 | } |
216 | |
217 | for( int textureNo=0; textureNo<8; textureNo++) |
218 | { |
219 | if( m_textureUnitMap[textureNo] == tex ) |
220 | { |
221 | COGLTexture* pTexture = g_textures[(gRSP.curTile+tex)&7].m_pCOGLTexture; |
222 | if( pTexture ) |
223 | { |
224 | EnableTexUnit(textureNo,TRUE); |
225 | BindTexture(pTexture->m_dwTextureName, textureNo); |
226 | } |
227 | SetTexWrapT(textureNo, OGLXUVFlagMaps[dwFlag].realFlag); |
228 | } |
229 | } |
230 | } |
231 | |
232 | void COGLExtRender::EnableTexUnit(int unitno, BOOL flag) |
233 | { |
234 | if( m_texUnitEnabled[unitno] != flag ) |
235 | { |
236 | m_texUnitEnabled[unitno] = flag; |
237 | pglActiveTexture(GL_TEXTURE0_ARB+unitno); |
238 | OPENGL_CHECK_ERRORS; |
239 | if( flag == TRUE ) |
240 | glEnable(GL_TEXTURE_2D); |
241 | else |
242 | glDisable(GL_TEXTURE_2D); |
243 | OPENGL_CHECK_ERRORS; |
244 | } |
245 | } |
246 | |
247 | void COGLExtRender::ApplyTextureFilter() |
248 | { |
249 | static uint32 minflag[8], magflag[8]; |
250 | static uint32 mtex[8]; |
251 | |
252 | int iMinFilter, iMagFilter; |
253 | |
254 | for( int i=0; i<m_maxTexUnits; i++ ) |
255 | { |
256 | //Compute iMinFilter and iMagFilter |
257 | if(m_dwMinFilter == FILTER_LINEAR) //Texture will use filtering |
258 | { |
259 | iMagFilter = GL_LINEAR; |
260 | |
261 | //Texture filtering method user want |
262 | switch(options.mipmapping) |
263 | { |
264 | case TEXTURE_BILINEAR_FILTER: |
265 | iMinFilter = GL_LINEAR_MIPMAP_NEAREST; |
266 | break; |
267 | case TEXTURE_TRILINEAR_FILTER: |
268 | iMinFilter = GL_LINEAR_MIPMAP_LINEAR; |
269 | break; |
270 | case TEXTURE_NO_FILTER: |
271 | iMinFilter = GL_NEAREST_MIPMAP_NEAREST; |
272 | break; |
273 | case TEXTURE_NO_MIPMAP: |
274 | default: |
275 | //Bilinear without mipmap |
276 | iMinFilter = GL_LINEAR; |
277 | } |
278 | } |
279 | else //dont use filtering, all is nearest |
280 | { |
281 | iMagFilter = GL_NEAREST; |
282 | |
283 | if(options.mipmapping) |
284 | { |
285 | iMinFilter = GL_NEAREST_MIPMAP_NEAREST; |
286 | } |
287 | else |
288 | { |
289 | iMinFilter = GL_NEAREST; |
290 | } |
291 | } |
292 | |
293 | if( m_texUnitEnabled[i] ) |
294 | { |
295 | if( mtex[i] != m_curBoundTex[i] ) |
296 | { |
297 | mtex[i] = m_curBoundTex[i]; |
298 | pglActiveTexture(GL_TEXTURE0_ARB+i); |
299 | OPENGL_CHECK_ERRORS; |
300 | minflag[i] = m_dwMinFilter; |
301 | magflag[i] = m_dwMagFilter; |
302 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iMinFilter); |
303 | OPENGL_CHECK_ERRORS; |
304 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iMagFilter); |
305 | OPENGL_CHECK_ERRORS; |
306 | } |
307 | else |
308 | { |
309 | if( minflag[i] != (unsigned int)m_dwMinFilter ) |
310 | { |
311 | minflag[i] = m_dwMinFilter; |
312 | pglActiveTexture(GL_TEXTURE0_ARB+i); |
313 | OPENGL_CHECK_ERRORS; |
314 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iMinFilter); |
315 | OPENGL_CHECK_ERRORS; |
316 | } |
317 | if( magflag[i] != (unsigned int)m_dwMagFilter ) |
318 | { |
319 | magflag[i] = m_dwMagFilter; |
320 | pglActiveTexture(GL_TEXTURE0_ARB+i); |
321 | OPENGL_CHECK_ERRORS; |
322 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iMagFilter); |
323 | OPENGL_CHECK_ERRORS; |
324 | } |
325 | } |
326 | } |
327 | } |
328 | } |
329 | |
330 | void COGLExtRender::SetTextureToTextureUnitMap(int tex, int unit) |
331 | { |
332 | if( unit < 8 && (tex >= -1 || tex <= 1)) |
333 | m_textureUnitMap[unit] = tex; |
334 | } |
335 | |