| 1 | /****************************************************************************** |
| 2 | * Arachnoid Graphics Plugin for Mupen64Plus |
| 3 | * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ |
| 4 | * |
| 5 | * Copyright (C) 2009 Jon Ring |
| 6 | * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or |
| 9 | * modify it under the terms of the GNU General Public License |
| 10 | * as published by the Free Software Foundation; either version 2 |
| 11 | * of the License, or (at your option) any later version. |
| 12 | * |
| 13 | * This program is distributed in the hope that it will be useful, |
| 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | * GNU General Public License for more details. |
| 17 | * |
| 18 | * You should have received a copy of the GNU General Public License |
| 19 | * along with this program; if not, write to the Free Software |
| 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 21 | *****************************************************************************/ |
| 22 | |
| 23 | #include "m64p.h" |
| 24 | |
| 25 | #include <cmath> |
| 26 | #include <algorithm> |
| 27 | #include "OpenGLRenderer.h" |
| 28 | #include "OpenGLManager.h" |
| 29 | #include "RSP.h" |
| 30 | #include "RDP.h" |
| 31 | #include "TextureCache.h" |
| 32 | #include "VI.h" |
| 33 | #include "Logger.h" |
| 34 | //#include "CombinerManager.h" |
| 35 | #include "AdvancedCombinerManager.h" |
| 36 | #include "FogManager.h" |
| 37 | #include "ExtensionChecker.h" |
| 38 | #include "MultiTexturingExt.h" |
| 39 | #include "SecondaryColorExt.h" |
| 40 | |
| 41 | #ifdef HAVE_GLES |
| 42 | // save of arrays |
| 43 | GLint glsav_col_size; |
| 44 | GLenum glsav_col_type; |
| 45 | GLsizei glsav_col_stride; |
| 46 | GLvoid* glsav_col_array; |
| 47 | |
| 48 | GLint glsav_vtx_size; |
| 49 | GLenum glsav_vtx_type; |
| 50 | GLsizei glsav_vtx_stride; |
| 51 | GLvoid* glsav_vtx_array; |
| 52 | |
| 53 | GLint glsav_tex_size; |
| 54 | GLenum glsav_tex_type; |
| 55 | GLsizei glsav_tex_stride; |
| 56 | GLvoid* glsav_tex_array; |
| 57 | |
| 58 | GLint glsav_tex1_size; |
| 59 | GLenum glsav_tex1_type; |
| 60 | GLsizei glsav_tex1_stride; |
| 61 | GLvoid* glsav_tex1_array; |
| 62 | #endif |
| 63 | |
| 64 | using std::max; |
| 65 | |
| 66 | #ifndef GL_CLAMP_TO_EDGE |
| 67 | #define GL_CLAMP_TO_EDGE 0x812F |
| 68 | #endif |
| 69 | |
| 70 | bool ARB_multitexture = false; |
| 71 | bool EXT_secondary_color = false; |
| 72 | |
| 73 | //----------------------------------------------------------------------------- |
| 74 | //! Constructor |
| 75 | //----------------------------------------------------------------------------- |
| 76 | OpenGLRenderer::OpenGLRenderer() |
| 77 | { |
| 78 | m_numVertices = 0; |
| 79 | } |
| 80 | |
| 81 | //----------------------------------------------------------------------------- |
| 82 | //! Destructor |
| 83 | //----------------------------------------------------------------------------- |
| 84 | OpenGLRenderer::~OpenGLRenderer() |
| 85 | { |
| 86 | |
| 87 | } |
| 88 | |
| 89 | //----------------------------------------------------------------------------- |
| 90 | //* Initialize |
| 91 | //! Saves pointers and setup render OpenGl pointers to vertex data. |
| 92 | //----------------------------------------------------------------------------- |
| 93 | bool OpenGLRenderer::initialize(RSP* rsp, RDP* rdp, TextureCache* textureCache, VI* vi, FogManager* fogMgr) |
| 94 | { |
| 95 | m_rsp = rsp; |
| 96 | m_rdp = rdp; |
| 97 | m_textureCache = textureCache; |
| 98 | m_vi = vi; |
| 99 | m_fogMgr = fogMgr; |
| 100 | |
| 101 | m_numVertices = 0; |
| 102 | m_numTriangles = 0; |
| 103 | |
| 104 | //Init multitexturing |
| 105 | ARB_multitexture = initializeMultiTexturingExtensions(); |
| 106 | EXT_secondary_color = initializeSecondaryColorExtension(); |
| 107 | |
| 108 | //Vertices |
| 109 | glVertexPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].x ); |
| 110 | glEnableClientState( GL_VERTEX_ARRAY ); |
| 111 | |
| 112 | //Colors |
| 113 | glColorPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].color.r); |
| 114 | glEnableClientState( GL_COLOR_ARRAY ); |
| 115 | |
| 116 | //Secondary Color |
| 117 | if ( EXT_secondary_color) |
| 118 | { |
| 119 | glSecondaryColorPointerEXT( 3, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].secondaryColor.r ); |
| 120 | glEnableClientState( GL_SECONDARY_COLOR_ARRAY_EXT ); |
| 121 | } |
| 122 | |
| 123 | //Textureing 0 |
| 124 | glClientActiveTextureARB( GL_TEXTURE0_ARB ); |
| 125 | glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s0 ); |
| 126 | glEnableClientState( GL_TEXTURE_COORD_ARRAY ); |
| 127 | |
| 128 | //Textureing 1 |
| 129 | glClientActiveTextureARB( GL_TEXTURE1_ARB ); |
| 130 | glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s1 ); |
| 131 | glEnableClientState( GL_TEXTURE_COORD_ARRAY ); |
| 132 | |
| 133 | //Fog |
| 134 | m_fogMgr->setFogCoordPointer(GL_FLOAT, sizeof(GLVertex), &m_vertices[0].fog); |
| 135 | m_fogMgr->enableFogCoordArray(); |
| 136 | m_fogMgr->setLinearFog(); |
| 137 | |
| 138 | #ifdef HAVE_GLES |
| 139 | // save of arrays |
| 140 | glsav_col_size = 4; |
| 141 | glsav_col_type = GL_FLOAT; |
| 142 | glsav_col_stride = sizeof(GLVertex); |
| 143 | glsav_col_array = &m_vertices[0].color.r; |
| 144 | |
| 145 | glsav_vtx_size = 4; |
| 146 | glsav_vtx_type = GL_FLOAT; |
| 147 | glsav_vtx_stride = sizeof(GLVertex); |
| 148 | glsav_vtx_array = &m_vertices[0].x; |
| 149 | |
| 150 | glsav_tex_size = 2; |
| 151 | glsav_tex_type = GL_FLOAT; |
| 152 | glsav_tex_stride = sizeof(GLVertex); |
| 153 | glsav_tex_array = &m_vertices[0].s0; |
| 154 | |
| 155 | glsav_tex1_size = 2; |
| 156 | glsav_tex1_type = GL_FLOAT; |
| 157 | glsav_tex1_stride = sizeof(GLVertex); |
| 158 | glsav_tex1_array = &m_vertices[0].s1; |
| 159 | #endif |
| 160 | |
| 161 | |
| 162 | return true; |
| 163 | } |
| 164 | |
| 165 | |
| 166 | |
| 167 | //----------------------------------------------------------------------------- |
| 168 | // Add triangle |
| 169 | //----------------------------------------------------------------------------- |
| 170 | void OpenGLRenderer::addTriangle( SPVertex *vertices, int v0, int v1, int v2 ) |
| 171 | { |
| 172 | int v[] = { v0, v1, v2 }; |
| 173 | |
| 174 | //Update States |
| 175 | m_rdp->updateStates(); |
| 176 | |
| 177 | //For each vertex in triangle |
| 178 | for (int i=0; i<3; ++i) |
| 179 | { |
| 180 | //Set Vertex |
| 181 | m_vertices[m_numVertices].x = vertices[v[i]].x; |
| 182 | m_vertices[m_numVertices].y = vertices[v[i]].y; |
| 183 | m_vertices[m_numVertices].z = m_rdp->getDepthSource() == G_ZS_PRIM ? m_rdp->getPrimitiveZ() * vertices[v[i]].w : vertices[v[i]].z; |
| 184 | m_vertices[m_numVertices].w = vertices[v[i]].w; |
| 185 | |
| 186 | //Set Color |
| 187 | m_vertices[m_numVertices].color.r = vertices[v[i]].r; |
| 188 | m_vertices[m_numVertices].color.g = vertices[v[i]].g; |
| 189 | m_vertices[m_numVertices].color.b = vertices[v[i]].b; |
| 190 | m_vertices[m_numVertices].color.a = vertices[v[i]].a; |
| 191 | m_rdp->getCombinerMgr()->getCombinerColor( &m_vertices[m_numVertices].color.r ); |
| 192 | |
| 193 | if ( EXT_secondary_color ) |
| 194 | { |
| 195 | m_vertices[m_numVertices].secondaryColor.r = 0.0f;//lod_fraction; //vertices[v[i]].r; |
| 196 | m_vertices[m_numVertices].secondaryColor.g = 0.0f;//lod_fraction; //vertices[v[i]].g; |
| 197 | m_vertices[m_numVertices].secondaryColor.b = 0.0f;//lod_fraction; //vertices[v[i]].b; |
| 198 | m_vertices[m_numVertices].secondaryColor.a = 1.0f; |
| 199 | m_rdp->getCombinerMgr()->getSecondaryCombinerColor( &m_vertices[m_numVertices].secondaryColor.r ); |
| 200 | } |
| 201 | |
| 202 | //Set Fog |
| 203 | if ( OpenGLManager::getSingleton().getFogEnabled() ) |
| 204 | { |
| 205 | if (vertices[v[i]].z < -vertices[v[i]].w) |
| 206 | { |
| 207 | m_vertices[m_numVertices].fog = max(0.0f, -m_fogMgr->getMultiplier() + m_fogMgr->getOffset() ); |
| 208 | } |
| 209 | else |
| 210 | { |
| 211 | m_vertices[m_numVertices].fog = max(0.0f, vertices[v[i]].z / vertices[v[i]].w * m_fogMgr->getMultiplier() + m_fogMgr->getOffset()); |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | //Set TexCoords |
| 216 | if ( m_rdp->getCombinerMgr()->getUsesTexture0() ) |
| 217 | { |
| 218 | RSPTexture& rspTexture = m_rsp->getTexture(); |
| 219 | CachedTexture* cacheTexture = m_textureCache->getCurrentTexture(0); |
| 220 | RDPTile* rspTile = m_rsp->getTile(0); |
| 221 | if ( cacheTexture ) |
| 222 | { |
| 223 | m_vertices[m_numVertices].s0 = (vertices[v[i]].s * cacheTexture->shiftScaleS * rspTexture.scaleS - rspTile->fuls + cacheTexture->offsetS) * cacheTexture->scaleS; |
| 224 | m_vertices[m_numVertices].t0 = (vertices[v[i]].t * cacheTexture->shiftScaleT * rspTexture.scaleT - rspTile->fult + cacheTexture->offsetT) * cacheTexture->scaleT; |
| 225 | } |
| 226 | else |
| 227 | { |
| 228 | m_vertices[m_numVertices].s0 = (vertices[v[i]].s * rspTexture.scaleS - rspTile->fuls ); |
| 229 | m_vertices[m_numVertices].t0 = (vertices[v[i]].t * rspTexture.scaleT - rspTile->fult ); |
| 230 | } |
| 231 | } |
| 232 | |
| 233 | if ( m_rdp->getCombinerMgr()->getUsesTexture1() ) |
| 234 | { |
| 235 | RSPTexture& rspTexture = m_rsp->getTexture(); |
| 236 | CachedTexture* cache = m_textureCache->getCurrentTexture(1); |
| 237 | RDPTile* rspTile = m_rsp->getTile(1); |
| 238 | if ( cache && rspTile ) |
| 239 | { |
| 240 | m_vertices[m_numVertices].s1 = (vertices[v[i]].s * cache->shiftScaleS * rspTexture.scaleS - rspTile->fuls + cache->offsetS) * cache->scaleS; |
| 241 | m_vertices[m_numVertices].t1 = (vertices[v[i]].t * cache->shiftScaleT * rspTexture.scaleT - rspTile->fult + cache->offsetT) * cache->scaleT; |
| 242 | } |
| 243 | } |
| 244 | |
| 245 | m_numVertices++; |
| 246 | } |
| 247 | m_numTriangles++; |
| 248 | |
| 249 | if ( m_numVertices >= 255 ) |
| 250 | { |
| 251 | |
| 252 | Logger::getSingleton().printMsg("RENDER VERTICES!!! :)", M64MSG_ERROR); |
| 253 | OpenGLRenderer::getSingleton().render(); |
| 254 | } |
| 255 | } |
| 256 | |
| 257 | //----------------------------------------------------------------------------- |
| 258 | // Render |
| 259 | //----------------------------------------------------------------------------- |
| 260 | void OpenGLRenderer::render() |
| 261 | { |
| 262 | glDrawArrays(GL_TRIANGLES, 0, m_numVertices); |
| 263 | m_numTriangles = m_numVertices = 0; |
| 264 | } |
| 265 | |
| 266 | //----------------------------------------------------------------------------- |
| 267 | // Render Texture Rectangle |
| 268 | //----------------------------------------------------------------------------- |
| 269 | void OpenGLRenderer::renderTexRect( float ulx, float uly, //Upper left vertex |
| 270 | float lrx, float lry, //Lower right vertex |
| 271 | float uls, float ult, //Upper left texcoord |
| 272 | float lrs, float lrt, //Lower right texcoord |
| 273 | bool flip) //Flip |
| 274 | { |
| 275 | //Initialize first vertex (upper left vertex) |
| 276 | GLVertex rect[2]; |
| 277 | rect[0].x = ulx; |
| 278 | rect[0].y = uly; |
| 279 | rect[0].z = m_rdp->getDepthSource() == 1 ? m_rdp->getPrimitiveZ() : 0.0f; //FIXME: Use viewport.nearz? |
| 280 | rect[0].w = 1.0f; |
| 281 | rect[0].color.r = 1.0f; |
| 282 | rect[0].color.g = 1.0f; |
| 283 | rect[0].color.b = 1.0f; |
| 284 | rect[0].color.a = 0.0f; |
| 285 | rect[0].secondaryColor.r = 1.0f; |
| 286 | rect[0].secondaryColor.g = 1.0f; |
| 287 | rect[0].secondaryColor.b = 1.0f; |
| 288 | rect[0].secondaryColor.a = 1.0f; |
| 289 | rect[0].s0 = uls; |
| 290 | rect[0].t0 = ult; |
| 291 | rect[0].s1 = uls; |
| 292 | rect[0].t1 = ult; |
| 293 | rect[0].fog = 0.0f; |
| 294 | |
| 295 | //Initialize second vertex (lower right vertex) |
| 296 | rect[1].x = lrx; |
| 297 | rect[1].y = lry; |
| 298 | rect[1].z = m_rdp->getDepthSource() == 1 ? m_rdp->getPrimitiveZ() : 0.0f; //FIXME: Use viewport.nearz? |
| 299 | rect[1].w = 1.0f; |
| 300 | rect[1].color.r = 1.0f; |
| 301 | rect[1].color.g = 1.0f; |
| 302 | rect[1].color.b = 1.0f; |
| 303 | rect[1].color.a = 0.0f; |
| 304 | rect[1].secondaryColor.r = 1.0f; |
| 305 | rect[1].secondaryColor.g = 1.0f; |
| 306 | rect[1].secondaryColor.b = 1.0f; |
| 307 | rect[1].secondaryColor.a = 1.0f; |
| 308 | rect[1].s0 = lrs; |
| 309 | rect[1].t0 = lrt; |
| 310 | rect[1].s1 = lrs; |
| 311 | rect[1].t1 = lrt; |
| 312 | rect[1].fog = 0.0f; |
| 313 | |
| 314 | glDisable( GL_CULL_FACE ); |
| 315 | glMatrixMode( GL_PROJECTION ); |
| 316 | glLoadIdentity(); |
| 317 | |
| 318 | //glOrtho( 0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f ); |
| 319 | glOrtho( 0, m_vi->getWidth(), m_vi->getHeight(), 0, 1.0f, -1.0f ); |
| 320 | //glOrtho( 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight(), 0, 1.0f, -1.0f ); |
| 321 | //glViewport( 0, 0, m_vi->getWidth(), m_vi->getHeight() ); |
| 322 | //glViewport( 0, 0, 320, 240 ); |
| 323 | //glViewport( 0, 0, OpenGLManager::getSingleton().getWidth(), OpenGLManager::getSingleton().getHeight()); |
| 324 | |
| 325 | if ( m_rdp->getCombinerMgr()->getUsesTexture0() ) |
| 326 | { |
| 327 | rect[0].s0 = rect[0].s0 * m_textureCache->getCurrentTexture(0)->shiftScaleS - m_rsp->getTile(0)->fuls; |
| 328 | rect[0].t0 = rect[0].t0 * m_textureCache->getCurrentTexture(0)->shiftScaleT - m_rsp->getTile(0)->fult; |
| 329 | rect[1].s0 = (rect[1].s0 + 1.0f) * m_textureCache->getCurrentTexture(0)->shiftScaleS - m_rsp->getTile(0)->fuls; |
| 330 | rect[1].t0 = (rect[1].t0 + 1.0f) * m_textureCache->getCurrentTexture(0)->shiftScaleT - m_rsp->getTile(0)->fult; |
| 331 | |
| 332 | if ((m_textureCache->getCurrentTexture(0)->maskS) && (fmod( rect[0].s0, m_textureCache->getCurrentTexture(0)->width ) == 0.0f) && !(m_textureCache->getCurrentTexture(0)->mirrorS)) |
| 333 | { |
| 334 | rect[1].s0 -= rect[0].s0; |
| 335 | rect[0].s0 = 0.0f; |
| 336 | } |
| 337 | |
| 338 | if ((m_textureCache->getCurrentTexture(0)->maskT) && (fmod( rect[0].t0, m_textureCache->getCurrentTexture(0)->height ) == 0.0f) && !(m_textureCache->getCurrentTexture(0)->mirrorT)) |
| 339 | { |
| 340 | rect[1].t0 -= rect[0].t0; |
| 341 | rect[0].t0 = 0.0f; |
| 342 | } |
| 343 | // |
| 344 | // if (OGL.ARB_multitexture) |
| 345 | glActiveTextureARB( GL_TEXTURE0_ARB ); |
| 346 | // |
| 347 | if ((rect[0].s0 >= 0.0f) && (rect[1].s0 <= m_textureCache->getCurrentTexture(0)->width)) |
| 348 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); |
| 349 | |
| 350 | if ((rect[0].t0 >= 0.0f) && (rect[1].t0 <= m_textureCache->getCurrentTexture(0)->height)) |
| 351 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); |
| 352 | |
| 353 | // |
| 354 | rect[0].s0 *= m_textureCache->getCurrentTexture(0)->scaleS; |
| 355 | rect[0].t0 *= m_textureCache->getCurrentTexture(0)->scaleT; |
| 356 | rect[1].s0 *= m_textureCache->getCurrentTexture(0)->scaleS; |
| 357 | rect[1].t0 *= m_textureCache->getCurrentTexture(0)->scaleT; |
| 358 | } |
| 359 | |
| 360 | if ( m_rdp->getCombinerMgr()->getUsesTexture1() ) |
| 361 | { |
| 362 | rect[0].s1 = rect[0].s1 * m_textureCache->getCurrentTexture(1)->shiftScaleS - m_rsp->getTile(1)->fuls; |
| 363 | rect[0].t1 = rect[0].t1 * m_textureCache->getCurrentTexture(1)->shiftScaleT - m_rsp->getTile(1)->fult; |
| 364 | rect[1].s1 = (rect[1].s1 + 1.0f) * m_textureCache->getCurrentTexture(1)->shiftScaleS - m_rsp->getTile(1)->fuls; |
| 365 | rect[1].t1 = (rect[1].t1 + 1.0f) * m_textureCache->getCurrentTexture(1)->shiftScaleT - m_rsp->getTile(1)->fult; |
| 366 | |
| 367 | if ((m_textureCache->getCurrentTexture(1)->maskS) && (fmod( rect[0].s1, m_textureCache->getCurrentTexture(1)->width ) == 0.0f) && !(m_textureCache->getCurrentTexture(1)->mirrorS)) |
| 368 | { |
| 369 | rect[1].s1 -= rect[0].s1; |
| 370 | rect[0].s1 = 0.0f; |
| 371 | } |
| 372 | |
| 373 | if ((m_textureCache->getCurrentTexture(1)->maskT) && (fmod( rect[0].t1, m_textureCache->getCurrentTexture(1)->height ) == 0.0f) && !(m_textureCache->getCurrentTexture(1)->mirrorT)) |
| 374 | { |
| 375 | rect[1].t1 -= rect[0].t1; |
| 376 | rect[0].t1 = 0.0f; |
| 377 | } |
| 378 | |
| 379 | glActiveTextureARB( GL_TEXTURE1_ARB ); |
| 380 | |
| 381 | if ((rect[0].s1 == 0.0f) && (rect[1].s1 <= m_textureCache->getCurrentTexture(1)->width)) |
| 382 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); |
| 383 | |
| 384 | if ((rect[0].t1 == 0.0f) && (rect[1].t1 <= m_textureCache->getCurrentTexture(1)->height)) |
| 385 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); |
| 386 | |
| 387 | rect[0].s1 *= m_textureCache->getCurrentTexture(1)->scaleS; |
| 388 | rect[0].t1 *= m_textureCache->getCurrentTexture(1)->scaleT; |
| 389 | rect[1].s1 *= m_textureCache->getCurrentTexture(1)->scaleS; |
| 390 | rect[1].t1 *= m_textureCache->getCurrentTexture(1)->scaleT; |
| 391 | } |
| 392 | |
| 393 | |
| 394 | if ( m_rdp->m_otherMode.cycleType == G_CYC_COPY ) /*&& !OGL.forceBilinear )*/ |
| 395 | { |
| 396 | //if (OGL.ARB_multitexture) |
| 397 | glActiveTextureARB( GL_TEXTURE0_ARB ); |
| 398 | |
| 399 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); |
| 400 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); |
| 401 | } |
| 402 | |
| 403 | // SetConstant( rect[0].color, combiner.vertex.color, combiner.vertex.alpha ); |
| 404 | //rdp.updateStates(); |
| 405 | m_rdp->getCombinerMgr()->getCombinerColor(&rect[0].color.r); |
| 406 | |
| 407 | //if (OGL.EXT_secondary_color) |
| 408 | m_rdp->getCombinerMgr()->getSecondaryCombinerColor(&rect[0].secondaryColor.r); |
| 409 | // SetConstant( rect[0].secondaryColor, combiner.vertex.secondaryColor, combiner.vertex.alpha ); |
| 410 | |
| 411 | #ifdef HAVE_GLES |
| 412 | GLfloat col[] = { |
| 413 | rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a, |
| 414 | rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a, |
| 415 | rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a, |
| 416 | rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a |
| 417 | }; |
| 418 | |
| 419 | GLfloat tex[] = { |
| 420 | rect[0].s0, rect[0].t0, |
| 421 | rect[1].s0, rect[0].t0, |
| 422 | rect[1].s0, rect[1].t0, |
| 423 | rect[0].s0, rect[1].t0 |
| 424 | }; |
| 425 | GLfloat tex1[] = { |
| 426 | rect[0].s1, rect[0].t1, |
| 427 | rect[1].s1, rect[0].t1, |
| 428 | rect[1].s1, rect[1].t1, |
| 429 | rect[0].s1, rect[1].t1 |
| 430 | }; |
| 431 | |
| 432 | GLfloat vtx[] = { |
| 433 | rect[0].x, rect[0].y, rect[0].z, 1.0f, |
| 434 | rect[1].x, rect[0].y, rect[0].z, 1.0f, |
| 435 | rect[1].x, rect[1].y, rect[0].z, 1.0f, |
| 436 | rect[0].x, rect[1].y, rect[0].z, 1.0f |
| 437 | }; |
| 438 | // Setup pointer array |
| 439 | glColorPointer(4, GL_FLOAT, 0, &col ); |
| 440 | glVertexPointer(4,GL_FLOAT, 0,&vtx); |
| 441 | glClientActiveTexture( GL_TEXTURE1 ); |
| 442 | glTexCoordPointer(2, GL_FLOAT, 0, &tex1); |
| 443 | glClientActiveTexture( GL_TEXTURE0 ); |
| 444 | glTexCoordPointer(2, GL_FLOAT, 0, &tex); |
| 445 | // Draw |
| 446 | glDrawArrays(GL_TRIANGLE_FAN,0,4); |
| 447 | // Restaure default pointer |
| 448 | glVertexPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].x ); |
| 449 | glColorPointer(4, GL_FLOAT, sizeof(GLVertex), &m_vertices[0].color.r); |
| 450 | glClientActiveTexture( GL_TEXTURE1 ); |
| 451 | glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s1 ); |
| 452 | glClientActiveTexture( GL_TEXTURE0 ); |
| 453 | glTexCoordPointer( 2, GL_FLOAT, sizeof( GLVertex ), &m_vertices[0].s0 ); |
| 454 | #else |
| 455 | glBegin( GL_QUADS ); |
| 456 | |
| 457 | glColor4f( rect[0].color.r, rect[0].color.g, rect[0].color.b, rect[0].color.a ); |
| 458 | |
| 459 | //if (OGL.EXT_secondary_color) |
| 460 | glSecondaryColor3fEXT( rect[0].secondaryColor.r, rect[0].secondaryColor.g, rect[0].secondaryColor.b ); |
| 461 | |
| 462 | //if (OGL.ARB_multitexture) |
| 463 | //{ |
| 464 | // glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[0].s0, rect[0].t0 ); |
| 465 | // glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[0].s1, rect[0].t1 ); |
| 466 | // glVertex4f( rect[0].x, rect[0].y, rect[0].z, 1.0f ); |
| 467 | |
| 468 | // glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[1].s0, rect[0].t0 ); |
| 469 | // glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[1].s1, rect[0].t1 ); |
| 470 | // glVertex4f( rect[1].x, rect[0].y, rect[0].z, 1.0f ); |
| 471 | |
| 472 | // glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[1].s0, rect[1].t0 ); |
| 473 | // glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[1].s1, rect[1].t1 ); |
| 474 | // glVertex4f( rect[1].x, rect[1].y, rect[0].z, 1.0f ); |
| 475 | |
| 476 | // glMultiTexCoord2fARB( GL_TEXTURE0_ARB, rect[0].s0, rect[1].t0 ); |
| 477 | // glMultiTexCoord2fARB( GL_TEXTURE1_ARB, rect[0].s1, rect[1].t1 ); |
| 478 | // glVertex4f( rect[0].x, rect[1].y, rect[0].z, 1.0f ); |
| 479 | //} |
| 480 | // else |
| 481 | { |
| 482 | |
| 483 | /* |
| 484 | Logger::getSingleton() << "\n\nTexRect x0=" << rect[0].x << " y0=" << rect[0].y << |
| 485 | " x1=" << rect[1].x << "y1=" << rect[1].y << |
| 486 | " t0u0=" << rect[0].s0 << " t0v0=" << rect[0].t0 << |
| 487 | " t0u1=" << rect[1].s0 << " t0v1=" << rect[1].t0 << "\n"; |
| 488 | */ |
| 489 | glTexCoord2f(rect[0].s0, rect[0].t0 ); |
| 490 | //glTexCoord2f(rect[0].s1, rect[0].t1 ); |
| 491 | glVertex4f( rect[0].x, rect[0].y, rect[0].z, 1.0f ); |
| 492 | |
| 493 | glTexCoord2f(rect[1].s0, rect[0].t0 ); |
| 494 | //glTexCoord2f(rect[1].s1, rect[0].t1 ); |
| 495 | glVertex4f( rect[1].x, rect[0].y, rect[0].z, 1.0f ); |
| 496 | |
| 497 | glTexCoord2f(rect[1].s0, rect[1].t0 ); |
| 498 | //glTexCoord2f(rect[1].s1, rect[1].t1 ); |
| 499 | glVertex4f( rect[1].x, rect[1].y, rect[0].z, 1.0f ); |
| 500 | |
| 501 | glTexCoord2f(rect[0].s0, rect[1].t0 ); |
| 502 | //glTexCoord2f(rect[0].s1, rect[1].t1 ); |
| 503 | glVertex4f( rect[0].x, rect[1].y, rect[0].z, 1.0f ); |
| 504 | |
| 505 | |
| 506 | |
| 507 | /* glTexCoord2f( rect[0].s0, rect[0].t0 ); |
| 508 | glVertex4f( rect[0].x, rect[0].y, rect[0].z, 1.0f ); |
| 509 | |
| 510 | if (flip) |
| 511 | glTexCoord2f( rect[1].s0, rect[0].t0 ); |
| 512 | else |
| 513 | glTexCoord2f( rect[0].s0, rect[1].t0 ); |
| 514 | |
| 515 | glVertex4f( rect[1].x, rect[0].y, rect[0].z, 1.0f ); |
| 516 | |
| 517 | glTexCoord2f( rect[1].s0, rect[1].t0 ); |
| 518 | glVertex4f( rect[1].x, rect[1].y, rect[0].z, 1.0f ); |
| 519 | |
| 520 | if (flip) |
| 521 | glTexCoord2f( rect[1].s0, rect[0].t0 ); |
| 522 | else |
| 523 | glTexCoord2f( rect[1].s0, rect[0].t0 ); |
| 524 | glVertex4f( rect[0].x, rect[1].y, rect[0].z, 1.0f );*/ |
| 525 | } |
| 526 | glEnd(); |
| 527 | #endif |
| 528 | glLoadIdentity(); |
| 529 | //OGL_UpdateCullFace(); |
| 530 | //OGL_UpdateViewport(); |
| 531 | } |