/* Copyright (C) 1999-2007 id Software, Inc. and contributors. For a list of contributors, see the accompanying CONTRIBUTORS file. This file is part of GtkRadiant. GtkRadiant is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. GtkRadiant is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GtkRadiant; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ // // Try to sort the faces by texture and make rendering faster // // Leonardo Zide (leo@lokigames.com) // #include "stdafx.h" typedef struct { qtexture_t* texture; GPtrArray* faces; } windingsort_t; static windingsort_t* sort; static guint32 alloc, len; static GPtrArray* notex_faces; void QueueClear () { len = 0; if (notex_faces == NULL) notex_faces = g_ptr_array_new (); g_ptr_array_set_size (notex_faces, 0); } void QueueFace (face_t *face) { guint32 i; if (face->d_texture->name[0] == '(') { g_ptr_array_add (notex_faces, face); return; } for (i = 0; i < len; i++) if (sort[i].texture == face->d_texture) { g_ptr_array_add (sort[i].faces, face); return; } if (len == alloc) { alloc += 8; sort = (windingsort_t*)realloc (sort, alloc*sizeof(windingsort_t)); for (i = len; i < alloc; i++) sort[i].faces = g_ptr_array_new (); } g_ptr_array_set_size (sort[len].faces, 0); g_ptr_array_add (sort[len].faces, face); sort[len].texture = face->d_texture; len++; } void QueueDraw () { guint32 i, k; face_t *face; winding_t *w; int j, nDrawMode = g_pParentWnd->GetCamera().draw_mode; if (notex_faces->len) { qglDisable (GL_TEXTURE_2D); for (i = 0; i < notex_faces->len; i++) { face = (face_t*)notex_faces->pdata[i]; w = face->face_winding; qglBegin (GL_POLYGON); /* if (b->patchBrush) //++timo FIXME: find a use case for this?? qglColor4f (face->d_color[0], face->d_color[1], face->d_color[2], 0.13); else */ qglColor4f (face->d_color[0], face->d_color[1], face->d_color[2], face->pShader->getTrans ()); if (g_PrefsDlg.m_bGLLighting) qglNormal3fv (face->plane.normal); for (j = 0; j < w->numpoints; j++) { if (nDrawMode == cd_texture || nDrawMode == cd_light) qglTexCoord2fv( &w->points[j][3] ); qglVertex3fv(w->points[j]); } qglEnd (); } } if (!len) return; if (nDrawMode == cd_texture || nDrawMode == cd_light) qglEnable (GL_TEXTURE_2D); for (k = 0; k < len; k++) { qglBindTexture (GL_TEXTURE_2D, sort[k].texture->texture_number); for (i = 0; i < sort[k].faces->len; i++) { face = (face_t*)sort[k].faces->pdata[i]; w = face->face_winding; qglBegin (GL_POLYGON); /* if (b->patchBrush) //++timo FIXME: find a use case for this?? qglColor4f (face->d_color[0], face->d_color[1], face->d_color[2], 0.13); else */ qglColor4f (face->d_color[0], face->d_color[1], face->d_color[2], face->pShader->getTrans ()); if (g_PrefsDlg.m_bGLLighting) qglNormal3fv (face->plane.normal); for (j = 0; j < w->numpoints; j++) { if (nDrawMode == cd_texture || nDrawMode == cd_light) qglTexCoord2fv( &w->points[j][3] ); qglVertex3fv(w->points[j]); } qglEnd (); } } qglBindTexture (GL_TEXTURE_2D, 0); }