2 Copyright (C) 2003 Rice1964
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.
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.
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.
19 #include "osal_opengl.h"
22 #include "OGLExtensions.h"
25 #include "OGLExtRender.h"
26 #include "OGLTexture.h"
28 void COGLExtRender::Initialize(void)
30 OGLRender::Initialize();
32 // Initialize multitexture
33 glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB,&m_maxTexUnits);
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
43 void COGLExtRender::BindTexture(GLuint texture, int unitno)
45 if( m_bEnableMultiTexture )
47 if( unitno < m_maxTexUnits )
49 if( m_curBoundTex[unitno] != texture )
51 pglActiveTexture(GL_TEXTURE0_ARB+unitno);
53 glBindTexture(GL_TEXTURE_2D,texture);
55 m_curBoundTex[unitno] = texture;
61 OGLRender::BindTexture(texture, unitno);
65 void COGLExtRender::DisBindTexture(GLuint texture, int unitno)
67 if( m_bEnableMultiTexture )
69 pglActiveTexture(GL_TEXTURE0_ARB+unitno);
71 glBindTexture(GL_TEXTURE_2D, 0); //Not to bind any texture
75 OGLRender::DisBindTexture(texture, unitno);
78 void COGLExtRender::TexCoord2f(float u, float v)
81 if( m_bEnableMultiTexture )
83 //printf("*SEB* overloaded TexCoord2f(%f, %f)\n", u, v);
84 for( int i=0; i<8; i++ )
86 if( m_textureUnitMap[i] >= 0 )
88 pglMultiTexCoord2f(GL_TEXTURE0_ARB+i, u, v);
94 OGLRender::TexCoord2f(u,v);
99 void COGLExtRender::TexCoord(TLITVERTEX &vtxInfo)
102 if( m_bEnableMultiTexture )
104 //printf("*SEB* overloaded TexCoord(%f, %f)\n", vtxInfo.tcord[0].u, vtxInfo.tcord[0].v);
105 for( int i=0; i<8; i++ )
107 if( m_textureUnitMap[i] >= 0 )
109 pglMultiTexCoord2fv(GL_TEXTURE0_ARB+i, &(vtxInfo.tcord[m_textureUnitMap[i]].u));
115 OGLRender::TexCoord(vtxInfo);
121 void COGLExtRender::SetTexWrapS(int unitno,GLuint flag)
123 static GLuint mflag[8];
124 static GLuint mtex[8];
125 if( m_curBoundTex[unitno] != mtex[unitno] || mflag[unitno] != flag )
127 mtex[unitno] = m_curBoundTex[0];
128 mflag[unitno] = flag;
129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, flag);
133 void COGLExtRender::SetTexWrapT(int unitno,GLuint flag)
135 static GLuint mflag[8];
136 static GLuint mtex[8];
137 if( m_curBoundTex[unitno] != mtex[unitno] || mflag[unitno] != flag )
139 mtex[unitno] = m_curBoundTex[0];
140 mflag[unitno] = flag;
141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, flag);
146 extern UVFlagMap OGLXUVFlagMaps[];
147 void COGLExtRender::SetTextureUFlag(TextureUVFlag dwFlag, uint32 dwTile)
149 TileUFlags[dwTile] = dwFlag;
150 if( !m_bEnableMultiTexture )
152 OGLRender::SetTextureUFlag(dwFlag, dwTile);
157 if( dwTile == gRSP.curTile )
159 else if( dwTile == ((gRSP.curTile+1)&7) )
163 if( dwTile == ((gRSP.curTile+2)&7) )
165 else if( dwTile == ((gRSP.curTile+3)&7) )
169 TRACE2("Incorrect tile number for OGL SetTextureUFlag: cur=%d, tile=%d", gRSP.curTile, dwTile);
174 for( int textureNo=0; textureNo<8; textureNo++)
176 if( m_textureUnitMap[textureNo] == tex )
178 pglActiveTexture(GL_TEXTURE0_ARB+textureNo);
180 COGLTexture* pTexture = g_textures[(gRSP.curTile+tex)&7].m_pCOGLTexture;
183 EnableTexUnit(textureNo,TRUE);
184 BindTexture(pTexture->m_dwTextureName, textureNo);
186 SetTexWrapS(textureNo, OGLXUVFlagMaps[dwFlag].realFlag);
190 void COGLExtRender::SetTextureVFlag(TextureUVFlag dwFlag, uint32 dwTile)
192 TileVFlags[dwTile] = dwFlag;
193 if( !m_bEnableMultiTexture )
195 OGLRender::SetTextureVFlag(dwFlag, dwTile);
200 if( dwTile == gRSP.curTile )
202 else if( dwTile == ((gRSP.curTile+1)&7) )
206 if( dwTile == ((gRSP.curTile+2)&7) )
208 else if( dwTile == ((gRSP.curTile+3)&7) )
212 TRACE2("Incorrect tile number for OGL SetTextureVFlag: cur=%d, tile=%d", gRSP.curTile, dwTile);
217 for( int textureNo=0; textureNo<8; textureNo++)
219 if( m_textureUnitMap[textureNo] == tex )
221 COGLTexture* pTexture = g_textures[(gRSP.curTile+tex)&7].m_pCOGLTexture;
224 EnableTexUnit(textureNo,TRUE);
225 BindTexture(pTexture->m_dwTextureName, textureNo);
227 SetTexWrapT(textureNo, OGLXUVFlagMaps[dwFlag].realFlag);
232 void COGLExtRender::EnableTexUnit(int unitno, BOOL flag)
234 if( m_texUnitEnabled[unitno] != flag )
236 m_texUnitEnabled[unitno] = flag;
237 pglActiveTexture(GL_TEXTURE0_ARB+unitno);
240 glEnable(GL_TEXTURE_2D);
242 glDisable(GL_TEXTURE_2D);
247 void COGLExtRender::ApplyTextureFilter()
249 static uint32 minflag[8], magflag[8];
250 static uint32 mtex[8];
252 int iMinFilter, iMagFilter;
254 for( int i=0; i<m_maxTexUnits; i++ )
256 //Compute iMinFilter and iMagFilter
257 if(m_dwMinFilter == FILTER_LINEAR) //Texture will use filtering
259 iMagFilter = GL_LINEAR;
261 //Texture filtering method user want
262 switch(options.mipmapping)
264 case TEXTURE_BILINEAR_FILTER:
265 iMinFilter = GL_LINEAR_MIPMAP_NEAREST;
267 case TEXTURE_TRILINEAR_FILTER:
268 iMinFilter = GL_LINEAR_MIPMAP_LINEAR;
270 case TEXTURE_NO_FILTER:
271 iMinFilter = GL_NEAREST_MIPMAP_NEAREST;
273 case TEXTURE_NO_MIPMAP:
275 //Bilinear without mipmap
276 iMinFilter = GL_LINEAR;
279 else //dont use filtering, all is nearest
281 iMagFilter = GL_NEAREST;
283 if(options.mipmapping)
285 iMinFilter = GL_NEAREST_MIPMAP_NEAREST;
289 iMinFilter = GL_NEAREST;
293 if( m_texUnitEnabled[i] )
295 if( mtex[i] != m_curBoundTex[i] )
297 mtex[i] = m_curBoundTex[i];
298 pglActiveTexture(GL_TEXTURE0_ARB+i);
300 minflag[i] = m_dwMinFilter;
301 magflag[i] = m_dwMagFilter;
302 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iMinFilter);
304 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iMagFilter);
309 if( minflag[i] != (unsigned int)m_dwMinFilter )
311 minflag[i] = m_dwMinFilter;
312 pglActiveTexture(GL_TEXTURE0_ARB+i);
314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, iMinFilter);
317 if( magflag[i] != (unsigned int)m_dwMagFilter )
319 magflag[i] = m_dwMagFilter;
320 pglActiveTexture(GL_TEXTURE0_ARB+i);
322 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, iMagFilter);
330 void COGLExtRender::SetTextureToTextureUnitMap(int tex, int unit)
332 if( unit < 8 && (tex >= -1 || tex <= 1))
333 m_textureUnitMap[unit] = tex;