292f9317 |
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 | for( int i=0; i<8; i++ ) |
84 | { |
85 | if( m_textureUnitMap[i] >= 0 ) |
86 | { |
87 | pglMultiTexCoord2f(GL_TEXTURE0_ARB+i, u, v); |
88 | } |
89 | } |
90 | } |
91 | else |
92 | { |
93 | OGLRender::TexCoord2f(u,v); |
94 | } |
95 | #endif |
96 | } |
97 | |
98 | void COGLExtRender::TexCoord(TLITVERTEX &vtxInfo) |
99 | { |
100 | #if SDL_VIDEO_OPENGL |
101 | if( m_bEnableMultiTexture ) |
102 | { |
103 | for( int i=0; i<8; i++ ) |
104 | { |
105 | if( m_textureUnitMap[i] >= 0 ) |
106 | { |
107 | pglMultiTexCoord2fv(GL_TEXTURE0_ARB+i, &(vtxInfo.tcord[m_textureUnitMap[i]].u)); |
108 | } |
109 | } |
110 | } |
111 | else |
112 | { |
113 | OGLRender::TexCoord(vtxInfo); |
114 | } |
115 | #endif |
116 | } |
117 | |
118 | |
119 | void COGLExtRender::SetTexWrapS(int unitno,GLuint flag) |
120 | { |
121 | static GLuint mflag[8]; |
122 | static GLuint mtex[8]; |
123 | if( m_curBoundTex[unitno] != mtex[unitno] || mflag[unitno] != flag ) |
124 | { |
6c753368 |
125 | pglActiveTexture(GL_TEXTURE0_ARB+unitno); |
126 | OPENGL_CHECK_ERRORS; |
292f9317 |
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 | { |
292f9317 |
178 | COGLTexture* pTexture = g_textures[(gRSP.curTile+tex)&7].m_pCOGLTexture; |
179 | if( pTexture ) |
180 | { |
181 | EnableTexUnit(textureNo,TRUE); |
182 | BindTexture(pTexture->m_dwTextureName, textureNo); |
183 | } |
184 | SetTexWrapS(textureNo, OGLXUVFlagMaps[dwFlag].realFlag); |
185 | } |
186 | } |
187 | } |
188 | void COGLExtRender::SetTextureVFlag(TextureUVFlag dwFlag, uint32 dwTile) |
189 | { |
190 | TileVFlags[dwTile] = dwFlag; |
191 | if( !m_bEnableMultiTexture ) |
192 | { |
193 | OGLRender::SetTextureVFlag(dwFlag, dwTile); |
194 | return; |
195 | } |
196 | |
197 | int tex; |
198 | if( dwTile == gRSP.curTile ) |
199 | tex=0; |
200 | else if( dwTile == ((gRSP.curTile+1)&7) ) |
201 | tex=1; |
202 | else |
203 | { |
204 | if( dwTile == ((gRSP.curTile+2)&7) ) |
205 | tex=2; |
206 | else if( dwTile == ((gRSP.curTile+3)&7) ) |
207 | tex=3; |
208 | else |
209 | { |
210 | TRACE2("Incorrect tile number for OGL SetTextureVFlag: cur=%d, tile=%d", gRSP.curTile, dwTile); |
211 | return; |
212 | } |
213 | } |
214 | |
215 | for( int textureNo=0; textureNo<8; textureNo++) |
216 | { |
217 | if( m_textureUnitMap[textureNo] == tex ) |
218 | { |
219 | COGLTexture* pTexture = g_textures[(gRSP.curTile+tex)&7].m_pCOGLTexture; |
220 | if( pTexture ) |
221 | { |
222 | EnableTexUnit(textureNo,TRUE); |
223 | BindTexture(pTexture->m_dwTextureName, textureNo); |
224 | } |
225 | SetTexWrapT(textureNo, OGLXUVFlagMaps[dwFlag].realFlag); |
226 | } |
227 | } |
228 | } |
229 | |
230 | void COGLExtRender::EnableTexUnit(int unitno, BOOL flag) |
231 | { |
232 | if( m_texUnitEnabled[unitno] != flag ) |
233 | { |
234 | m_texUnitEnabled[unitno] = flag; |
235 | pglActiveTexture(GL_TEXTURE0_ARB+unitno); |
236 | OPENGL_CHECK_ERRORS; |
237 | if( flag == TRUE ) |
238 | glEnable(GL_TEXTURE_2D); |
239 | else |
240 | glDisable(GL_TEXTURE_2D); |
241 | OPENGL_CHECK_ERRORS; |
242 | } |
243 | } |
244 | |
245 | void COGLExtRender::ApplyTextureFilter() |
246 | { |
247 | static uint32 minflag[8], magflag[8]; |
248 | static uint32 mtex[8]; |
249 | |
250 | int iMinFilter, iMagFilter; |
251 | |
252 | for( int i=0; i<m_maxTexUnits; i++ ) |
253 | { |
254 | //Compute iMinFilter and iMagFilter |
255 | if(m_dwMinFilter == FILTER_LINEAR) //Texture will use filtering |
256 | { |
257 | iMagFilter = GL_LINEAR; |
258 | |
259 | //Texture filtering method user want |
260 | switch(options.mipmapping) |
261 | { |
262 | case TEXTURE_BILINEAR_FILTER: |
263 | iMinFilter = GL_LINEAR_MIPMAP_NEAREST; |
264 | break; |
265 | case TEXTURE_TRILINEAR_FILTER: |
266 | iMinFilter = GL_LINEAR_MIPMAP_LINEAR; |
267 | break; |
268 | case TEXTURE_NO_FILTER: |
269 | iMinFilter = GL_NEAREST_MIPMAP_NEAREST; |
270 | break; |
271 | case TEXTURE_NO_MIPMAP: |
272 | default: |
273 | //Bilinear without mipmap |
274 | iMinFilter = GL_LINEAR; |
275 | } |
276 | } |
277 | else //dont use filtering, all is nearest |
278 | { |
279 | iMagFilter = GL_NEAREST; |
280 | |
281 | if(options.mipmapping) |
282 | { |
283 | iMinFilter = GL_NEAREST_MIPMAP_NEAREST; |
284 | } |
285 | else |
286 | { |
287 | iMinFilter = GL_NEAREST; |
288 | } |
289 | } |
290 | |
291 | if( m_texUnitEnabled[i] ) |
292 | { |
293 | if( mtex[i] != m_curBoundTex[i] ) |
294 | { |
295 | mtex[i] = m_curBoundTex[i]; |
296 | pglActiveTexture(GL_TEXTURE0_ARB+i); |
297 | OPENGL_CHECK_ERRORS; |
298 | minflag[i] = m_dwMinFilter; |
299 | magflag[i] = m_dwMagFilter; |
300 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iMinFilter); |
301 | OPENGL_CHECK_ERRORS; |
302 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iMagFilter); |
303 | OPENGL_CHECK_ERRORS; |
304 | } |
305 | else |
306 | { |
307 | if( minflag[i] != (unsigned int)m_dwMinFilter ) |
308 | { |
309 | minflag[i] = m_dwMinFilter; |
310 | pglActiveTexture(GL_TEXTURE0_ARB+i); |
311 | OPENGL_CHECK_ERRORS; |
312 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iMinFilter); |
313 | OPENGL_CHECK_ERRORS; |
314 | } |
315 | if( magflag[i] != (unsigned int)m_dwMagFilter ) |
316 | { |
317 | magflag[i] = m_dwMagFilter; |
318 | pglActiveTexture(GL_TEXTURE0_ARB+i); |
319 | OPENGL_CHECK_ERRORS; |
320 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iMagFilter); |
321 | OPENGL_CHECK_ERRORS; |
322 | } |
323 | } |
324 | } |
325 | } |
326 | } |
327 | |
328 | void COGLExtRender::SetTextureToTextureUnitMap(int tex, int unit) |
329 | { |
330 | if( unit < 8 && (tex >= -1 || tex <= 1)) |
331 | m_textureUnitMap[unit] = tex; |
332 | } |
333 | |