Added missing launcher
[mupen64plus-pandora.git] / source / rice_gles / src / OGLExtRender.cpp
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