rice: avoid redundant gl calls
[mupen64plus-pandora.git] / source / gles2rice / src / OGLExtRender.cpp
CommitLineData
292f9317 1/*
2Copyright (C) 2003 Rice1964
3
4This program is free software; you can redistribute it and/or
5modify it under the terms of the GNU General Public License
6as published by the Free Software Foundation; either version 2
7of the License, or (at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, 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
28void 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
43void 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
65void 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
78void 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
98void 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
119void 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}
133void 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
146extern UVFlagMap OGLXUVFlagMaps[];
147void 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}
188void 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
230void 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
245void 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
328void COGLExtRender::SetTextureToTextureUnitMap(int tex, int unit)
329{
330 if( unit < 8 && (tex >= -1 || tex <= 1))
331 m_textureUnitMap[unit] = tex;
332}
333