PANDORA: Make GLES context compatible with latest driver (FB only, no X11)
[mupen64plus-pandora.git] / source / rice_gles / src / OGLExtRender.cpp
CommitLineData
d07c171f 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//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
99void 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
121void 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}
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 {
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}
190void 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
232void 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
247void 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
330void COGLExtRender::SetTextureToTextureUnitMap(int tex, int unit)
331{
332 if( unit < 8 && (tex >= -1 || tex <= 1))
333 m_textureUnitMap[unit] = tex;
334}
335