more eol-style
[xonotic/netradiant.git] / plugins / spritemodel / spritemodel.cpp
1 /*
2 Copyright (C) 1999-2007 id Software, Inc. and contributors.
3 For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 //
23 // Sprite Model Plugin
24 //
25 // Code by Hydra aka Dominic Clifton
26 //
27 // Based on MD3Model source code by SPoG
28 //
29
30 #include "spritemodel.h"
31
32 void LoadSpriteModel(entity_interfaces_t *interfaces, const char *name)
33 {
34   IShader *pShader;
35
36   pShader = QERApp_Shader_ForName(name);
37
38   if (!pShader)
39   {
40     Sys_Printf("ERROR: can't find shader (or image) for: %s\n", name );
41     return;
42   }
43
44   CSpriteModel *model = new CSpriteModel();
45   model->Construct(pShader);
46   interfaces->pRender = (IRender*)model;
47   interfaces->pRender->IncRef();
48   //interfaces->pSelect = (ISelect*)model;
49   //interfaces->pSelect->IncRef();
50   interfaces->pSelect = NULL;
51   interfaces->pEdit = NULL;
52   model->DecRef();
53
54 }
55
56 void CSpriteModel::Construct(IShader *pShader)
57 {
58   m_pShader = pShader;
59   aabb_clear(&m_BBox);
60   /*
61         md3Surface_t *pSurface = (md3Surface_t *)(((unsigned char *)pHeader) + pHeader->ofsSurfaces);
62   m_nSurfaces = pHeader->numSurfaces;
63   CMD3Surface* surfaces = new CMD3Surface[m_nSurfaces];
64   for (int i = 0; i < m_nSurfaces; i++ )
65         {
66     surfaces[i].Construct(pSurface);
67                 pSurface = (md3Surface_t *) ((( char * ) pSurface) + pSurface->ofsEnd);
68   }
69   m_children = surfaces;
70   AccumulateBBox();
71   */
72 }
73
74 CSpriteModel::CSpriteModel()
75 {
76   refCount = 1;
77   //m_nSurfaces = 0;
78   //m_children = NULL;
79   m_pShader = NULL;
80 }
81
82 CSpriteModel::~CSpriteModel()
83 {
84   // if(m_children) delete[] m_children;
85   if (m_pShader)
86     m_pShader->DecRef();
87 }
88
89 void CSpriteModel::Draw(int state, int rflags) const
90 {
91
92 /*
93   // Draw a point in the middle of the bbox
94   vec3_t middle = {0,0,0};
95   g_QglTable.m_pfn_qglPointSize (4);
96   g_QglTable.m_pfn_qglColor3f (0,1,0);
97   g_QglTable.m_pfn_qglBegin (GL_POINTS);
98   g_QglTable.m_pfn_qglVertex3fv (middle);
99   g_QglTable.m_pfn_qglEnd ();
100 */
101
102   qtexture_t    *q = m_pShader->getTexture();
103
104   // convert pixels to units and divide in half again so we draw in the middle
105   // of the bbox.
106   int h = q->height / 8;
107   int w = q->width / 8;
108
109   // setup opengl stuff
110
111   g_QglTable.m_pfn_qglPushAttrib (GL_ALL_ATTRIB_BITS);  // GL_ENABLE_BIT
112   //g_QglTable.m_pfn_qglColor3f (1,1,1);   //testing
113   //g_QglTable.m_pfn_qglColor4f (1,1,1,1); //testing
114   g_QglTable.m_pfn_qglBindTexture (GL_TEXTURE_2D, q->texture_number);
115
116   //g_QglTable.m_pfn_qglEnable (GL_TEXTURE_2D); // FIXME: ? this forces textures, even in wireframe mode, bad... ?
117
118   g_QglTable.m_pfn_qglAlphaFunc (GL_LESS, 1);
119   g_QglTable.m_pfn_qglEnable (GL_ALPHA_TEST);
120
121   // get rid of this when sprite always faces camera
122   g_QglTable.m_pfn_qglDisable(GL_CULL_FACE);
123   g_QglTable.m_pfn_qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
124
125   // draw the sprite
126
127 #if 0
128   // using x/y axis, it appears FLAT without the proper transform and rotation.
129
130   g_QglTable.m_pfn_qglBegin(GL_QUADS);
131   g_QglTable.m_pfn_qglTexCoord2f (0,0);
132   g_QglTable.m_pfn_qglVertex3f (0-w,0-h, 0);
133   g_QglTable.m_pfn_qglTexCoord2f (1,0);
134   g_QglTable.m_pfn_qglVertex3f ( w,0-h, 0);
135   g_QglTable.m_pfn_qglTexCoord2f (1,1);
136   g_QglTable.m_pfn_qglVertex3f ( w, h, 0);
137   g_QglTable.m_pfn_qglTexCoord2f (0,1);
138   g_QglTable.m_pfn_qglVertex3f (0-w, h, 0);
139   g_QglTable.m_pfn_qglEnd ();
140 #else
141
142   // so draw it using y/z instead.
143   g_QglTable.m_pfn_qglBegin(GL_QUADS);
144   g_QglTable.m_pfn_qglTexCoord2f (0,0);
145   g_QglTable.m_pfn_qglVertex3f (0,w,h);
146   g_QglTable.m_pfn_qglTexCoord2f (1,0);
147   g_QglTable.m_pfn_qglVertex3f (0,0-w,h);
148   g_QglTable.m_pfn_qglTexCoord2f (1,1);
149   g_QglTable.m_pfn_qglVertex3f (0,0-w,0-h);
150   g_QglTable.m_pfn_qglTexCoord2f (0,1);
151   g_QglTable.m_pfn_qglVertex3f (0,w,0-h);
152   g_QglTable.m_pfn_qglEnd ();
153 #endif
154
155   g_QglTable.m_pfn_qglBindTexture (GL_TEXTURE_2D, 0);
156   g_QglTable.m_pfn_qglPopAttrib();
157 }
158
159 /*
160 bool CSpriteModel::TestRay(const ray_t *ray, vec_t *dist) const
161 {
162   vec_t depth_start = *dist;
163   vec_t depth_local = *dist;
164
165   if (aabb_test_ray(&m_BBox, ray) == 0)
166     return false;
167
168   for(int i=0; i<m_nSurfaces; i++)
169   {
170     if(m_children[i].TestRay(ray, &depth_local))
171     {
172       if (depth_local < *dist) *dist = depth_local;
173     }
174   }
175
176   return *dist < depth_start;
177 }
178 */