transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / plugins / model / cpicosurface.cpp
1 /*\r
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.\r
3 For a list of contributors, see the accompanying CONTRIBUTORS file.\r
4 \r
5 This file is part of GtkRadiant.\r
6 \r
7 GtkRadiant is free software; you can redistribute it and/or modify\r
8 it under the terms of the GNU General Public License as published by\r
9 the Free Software Foundation; either version 2 of the License, or\r
10 (at your option) any later version.\r
11 \r
12 GtkRadiant is distributed in the hope that it will be useful,\r
13 but WITHOUT ANY WARRANTY; without even the implied warranty of\r
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
15 GNU General Public License for more details.\r
16 \r
17 You should have received a copy of the GNU General Public License\r
18 along with GtkRadiant; if not, write to the Free Software\r
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA\r
20 */\r
21 \r
22 #include "cpicosurface.h"\r
23 \r
24 // public\r
25 \r
26 CPicoSurface::CPicoSurface(picoSurface_t *pSurface)\r
27 {\r
28   refCount = 1;\r
29 \r
30   m_pSurface = pSurface;\r
31 \r
32   // PicoFixSurfaceNormals( pSurface );\r
33         \r
34   AccumulateBBox();\r
35 \r
36   m_shader = QERApp_Shader_ForName(GetShaderName());\r
37 }\r
38 \r
39 CPicoSurface::~CPicoSurface()\r
40 {\r
41   m_shader->DecRef();\r
42 }\r
43 \r
44 void CPicoSurface::Draw(int state, int rflags)\r
45 {\r
46   Draw(state, m_shader, rflags);\r
47 }\r
48 \r
49 void CPicoSurface::Draw(int state, IShader *pShader, int rflags)\r
50 {\r
51   int j;\r
52 \r
53   if( !(rflags & (DRAW_RF_SEL_OUTLINE|DRAW_RF_SEL_FILL|DRAW_RF_XY)) )\r
54   {\r
55     if(state & DRAW_GL_TEXTURE_2D)\r
56     {\r
57       g_QglTable.m_pfn_qglBindTexture(GL_TEXTURE_2D, pShader->getTexture()->texture_number);\r
58       if( (rflags & DRAW_RF_CAM) && (pShader->getFlags() & QER_ALPHAFUNC) ) {\r
59         int nFunc = 0;\r
60         float fRef = 0.f;\r
61 \r
62         g_QglTable.m_pfn_qglColor4f( 1.f, 1.f, 1.f, 1.f ); // identity\r
63 \r
64         g_QglTable.m_pfn_qglEnable( GL_ALPHA_TEST );\r
65 \r
66         pShader->getAlphaFunc( &nFunc, &fRef );\r
67               g_QglTable.m_pfn_qglAlphaFunc( nFunc, fRef );\r
68       }\r
69     }\r
70     else\r
71     {\r
72       //g_QglTable.m_pfn_qglColor3fv( pShader->getTexture()->color );\r
73 /*      g_QglTable.m_pfn_qglEnableClientState(GL_COLOR_ARRAY);*/\r
74     }\r
75 \r
76     if( !(state & DRAW_GL_WIRE) && (pShader->getFlags() & QER_CULL) )\r
77     {\r
78       if( pShader->getCull() == 2 )\r
79       {\r
80         g_QglTable.m_pfn_qglDisable( GL_CULL_FACE );\r
81         g_QglTable.m_pfn_qglPolygonMode (GL_FRONT, GL_FILL);\r
82       }\r
83       else // is 1\r
84       {\r
85         g_QglTable.m_pfn_qglCullFace( GL_BACK );\r
86       }\r
87     }\r
88   }\r
89 \r
90   switch( PicoGetSurfaceType(m_pSurface) )\r
91   {\r
92   case PICO_TRIANGLES:  g_QglTable.m_pfn_qglBegin(GL_TRIANGLES);\r
93                         for (j=0; j<PicoGetSurfaceNumIndexes(m_pSurface); j++)\r
94                         {\r
95                               g_QglTable.m_pfn_qglNormal3fv(PicoGetSurfaceNormal(m_pSurface,PicoGetSurfaceIndex(m_pSurface,j)));\r
96                                                         \r
97                                                   if( !(rflags & (DRAW_RF_SEL_OUTLINE|DRAW_RF_SEL_FILL|DRAW_RF_XY)) ) {\r
98                             if(state & DRAW_GL_TEXTURE_2D) {\r
99                               g_QglTable.m_pfn_qglTexCoord2fv(PicoGetSurfaceST(m_pSurface,0,PicoGetSurfaceIndex(m_pSurface,j)));\r
100                                                         } else {\r
101                               picoByte_t *vertexColor = PicoGetSurfaceColor(m_pSurface,0,PicoGetSurfaceIndex(m_pSurface,j));\r
102                               //% g_QglTable.m_pfn_qglColor4f( vertexColor[ 0 ] / 255.f,\r
103                               //%                              vertexColor[ 1 ] / 255.f,\r
104                               //%                              vertexColor[ 2 ] / 255.f,\r
105                               //%                              vertexColor[ 3 ] / 255.f );\r
106                               g_QglTable.m_pfn_qglColor4ubv( vertexColor );\r
107                             }\r
108                                                   }\r
109                           g_QglTable.m_pfn_qglVertex3fv( PicoGetSurfaceXYZ( m_pSurface, PicoGetSurfaceIndex( m_pSurface, j ) ) );\r
110                         }\r
111                         g_QglTable.m_pfn_qglEnd();\r
112                         /*g_QglTable.m_pfn_qglVertexPointer( 3, GL_FLOAT, 0, PicoGetSurfaceXYZ( m_pSurface, 0 ) );\r
113                                                 g_QglTable.m_pfn_qglNormalPointer( GL_FLOAT, 0, PicoGetSurfaceNormal( m_pSurface, 0 ) );\r
114                                                 if( !(rflags & (DRAW_RF_SEL_OUTLINE|DRAW_RF_SEL_FILL|DRAW_RF_XY)) ) {\r
115                           if( state & DRAW_GL_TEXTURE_2D ) {\r
116                                                     g_QglTable.m_pfn_qglTexCoordPointer( 2, GL_FLOAT, 0, PicoGetSurfaceST( m_pSurface, 0, 0 ) );                            \r
117                                                   } else {\r
118                             g_QglTable.m_pfn_qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, PicoGetSurfaceColor( m_pSurface, 0, 0 ) );\r
119                                                   }\r
120                                                 }\r
121                                                 g_QglTable.m_pfn_qglDrawElements( GL_TRIANGLES, PicoGetSurfaceNumIndexes( m_pSurface ), GL_UNSIGNED_INT, PicoGetSurfaceIndexes( m_pSurface, 0 ) );*/\r
122 \r
123                         /*g_QglTable.m_pfn_qglColor3f( 0.f, .5f, 1.f );\r
124                                                 g_QglTable.m_pfn_qglBegin( GL_LINES );\r
125                                                 for( int i = 0; i < PicoGetSurfaceNumIndexes( m_pSurface ); i++ ) {\r
126                                                   vec3_t outerpoint;\r
127                                                   VectorMA( PicoGetSurfaceXYZ( m_pSurface, PicoGetSurfaceIndex( m_pSurface, i ) ), .3f, PicoGetSurfaceNormal( m_pSurface, PicoGetSurfaceIndex( m_pSurface, i ) ), outerpoint );\r
128                                                   g_QglTable.m_pfn_qglVertex3fv( PicoGetSurfaceXYZ( m_pSurface, PicoGetSurfaceIndex( m_pSurface, i ) ) );\r
129                                                   g_QglTable.m_pfn_qglVertex3fv( outerpoint );\r
130                                                 }\r
131                                                 g_QglTable.m_pfn_qglEnd();*/\r
132 \r
133                         break;\r
134   default:              Sys_Printf( "ERROR: Unsupported Pico Surface Type: %i", PicoGetSurfaceType(m_pSurface) );\r
135                         break;\r
136   }\r
137 \r
138   if( !(rflags & (DRAW_RF_SEL_OUTLINE|DRAW_RF_SEL_FILL|DRAW_RF_XY)) )\r
139   {\r
140     if( (state & DRAW_GL_TEXTURE_2D) && (rflags & DRAW_RF_CAM) && (pShader->getFlags() & QER_ALPHAFUNC) ) {\r
141       g_QglTable.m_pfn_qglDisable( GL_ALPHA_TEST );\r
142     }\r
143 \r
144 /*      if(!(state & DRAW_GL_TEXTURE_2D)) {\r
145       g_QglTable.m_pfn_qglDisableClientState(GL_COLOR_ARRAY);\r
146         }*/\r
147 \r
148     if( !(state & DRAW_GL_WIRE) && (pShader->getFlags() & QER_CULL) )\r
149     {\r
150       if( pShader->getCull() == 2 )\r
151       {\r
152         g_QglTable.m_pfn_qglPolygonMode (GL_FRONT, GL_LINE);\r
153         g_QglTable.m_pfn_qglEnable( GL_CULL_FACE );\r
154       }\r
155       else // is 1\r
156       {\r
157         g_QglTable.m_pfn_qglCullFace( GL_FRONT );\r
158       }\r
159     }\r
160   }\r
161 }\r
162 \r
163 // private\r
164 \r
165 void CPicoSurface::AccumulateBBox()\r
166 {\r
167   int i;\r
168   picoVec_t *p;\r
169   aabb_clear(&m_BBox);\r
170   for (i=0; i<PicoGetSurfaceNumVertexes(m_pSurface); i++)\r
171   {\r
172     p=PicoGetSurfaceXYZ(m_pSurface,i);\r
173     aabb_extend_by_point(&m_BBox, p);\r
174   }\r
175   aabb_update_radius(&m_BBox);\r
176 }\r
177 \r
178 bool CPicoSurface::TestRay (const ray_t *ray, vec_t *dist) const\r
179 {\r
180   int i;\r
181   vec_t start_dist = *dist;\r
182   vec_t local_dist = *dist;\r
183   if (aabb_intersect_ray(&m_BBox, ray, &local_dist))\r
184   {\r
185     switch( PicoGetSurfaceType(m_pSurface) )\r
186     {\r
187     case PICO_TRIANGLES:\r
188       for (i=0; i<PicoGetSurfaceNumIndexes(m_pSurface); i+=3)\r
189       {\r
190                     local_dist = ray_intersect_triangle(ray, true, PicoGetSurfaceXYZ(m_pSurface,PicoGetSurfaceIndex(m_pSurface,i+2)),\r
191                                               PicoGetSurfaceXYZ(m_pSurface,PicoGetSurfaceIndex(m_pSurface,i+1)),\r
192                                               PicoGetSurfaceXYZ(m_pSurface,PicoGetSurfaceIndex(m_pSurface,i)));\r
193                     if (local_dist < *dist)\r
194           *dist = local_dist;\r
195       }\r
196       break;\r
197     default:\r
198       Sys_Printf( "ERROR: Unsupported Pico Surface Type: %i", PicoGetSurfaceType(m_pSurface) );\r
199       break;\r
200     }\r
201   }\r
202         return (*dist < start_dist);\r
203 }\r