Add "Apply transformations" feature (no connectors or frames done yet)
[wmit:wmit.git] / src / widgets / QWZM.cpp
1 /*
2         Copyright 2010 Warzone 2100 Project
3
4         This file is part of WMIT.
5
6         WMIT is free software: you can redistribute it and/or modify
7         it under the terms of the GNU General Public License as published by
8         the Free Software Foundation, either version 3 of the License, or
9         (at your option) any later version.
10
11         WMIT is distributed in the hope that it will be useful,
12         but WITHOUT ANY WARRANTY; without even the implied warranty of
13         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14         GNU General Public License for more details.
15
16         You should have received a copy of the GNU General Public License
17         along with WMIT.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "QWZM.hpp"
21
22 #include <QString>
23
24 #include "IGLTextureManager.hpp"
25
26 QWZM::QWZM()
27 {
28         defaultConstructor();
29 }
30
31 QWZM::QWZM(const Pie3Model& p3)
32         : WZM(p3)
33 {
34         defaultConstructor();
35 }
36
37 void QWZM::operator =(const WZM& wzm)
38 {
39         if (m_texture != 0)
40         {
41                 deleteTexture(m_texture);
42         }
43         if (m_tcm != 0)
44         {
45                 deleteTexture(m_texture);
46         }
47         WZM::operator=(wzm);
48 }
49
50 void QWZM::render()
51 {
52         const GLfloat tcColour[4] = {160/255.f,32/255.f,240/255.f,255/255.f}; // temporary...
53         const bool tcmask = currentTCMaskMode() != None && m_tcm != 0;
54
55         std::vector<Mesh>::iterator it;
56
57         GLint frontFace;
58         glGetIntegerv(GL_FRONT_FACE, &frontFace);
59
60
61         glPushAttrib(GL_TEXTURE_BIT);
62         glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
63
64         glActiveTexture(GL_TEXTURE0);
65         glEnable(GL_TEXTURE_2D);
66         glBindTexture(GL_TEXTURE_2D, m_texture);
67
68         glClientActiveTexture(GL_TEXTURE0);
69         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
70
71         glEnableClientState(GL_VERTEX_ARRAY);
72
73         glPushMatrix();
74
75         if (frontFace != winding)
76         {
77                 glFrontFace(winding);
78         }
79         glScalef(-1/128.f, 1/128.f, 1/128.f); // Scale from warzone to fit in our scene. possibly a FIXME
80
81         glScalef(scale_all * scale_xyz[0], scale_all * scale_xyz[1], scale_all * scale_xyz[2]);
82
83         if (tcmask)
84         {
85                 setTCMaskEnvironment(tcColour);
86
87                 if (currentTCMaskMode() == FixedPipeline)
88                 {
89                         glClientActiveTexture(GL_TEXTURE1);
90                         glEnableClientState(GL_TEXTURE_COORD_ARRAY);
91                 }
92                 else
93                 {
94                         glActiveTexture(GL_TEXTURE1);
95                         glEnable(GL_TEXTURE_2D);
96                 }
97                 glBindTexture(GL_TEXTURE_2D, m_tcm);
98         }
99
100         for (it = m_meshes.begin(); it != m_meshes.end(); ++it)
101         {
102                 static_assert(sizeof(WZMUV) == sizeof(GLfloat)*2, "WZMUV has become fat.");
103                 glTexCoordPointer(2, GL_FLOAT, 0, &it->m_textureArrays[0][0]);
104
105                 if (currentTCMaskMode() == FixedPipeline)
106                 {
107                         glClientActiveTexture(GL_TEXTURE0);
108                         glTexCoordPointer(2, GL_FLOAT, 0, &it->m_textureArrays[0][0]);
109                         glClientActiveTexture(GL_TEXTURE1);
110                 }
111
112                 static_assert(sizeof(WZMVertex) == sizeof(GLfloat)*3, "WZMVertex has become fat.");
113                 glVertexPointer(3, GL_FLOAT, 0, &it->m_vertexArray[0]);
114
115                 static_assert(sizeof(IndexedTri) == sizeof(GLushort)*3, "IndexedTri has become fat.");
116                 glDrawElements(GL_TRIANGLES, it->m_indexArray.size() * 3, GL_UNSIGNED_SHORT, &it->m_indexArray[0]);
117         }
118
119         resetTCMaskEnvironment();
120
121         if (frontFace != winding)
122         {
123                 glFrontFace(GL_CCW);
124         }
125
126         glPopMatrix();
127         glPopClientAttrib();
128         glPopAttrib();
129 }
130
131 void QWZM::animate()
132 {
133
134 }
135
136 void QWZM::setRenderTexture(QString fileName)
137 {
138         if (m_texture != 0)
139         {
140                 deleteTexture(m_texture);
141         }
142         m_texture = createTexture(fileName).id();
143 }
144
145 void QWZM::setTextureManager(IGLTextureManager * manager)
146 {
147         QString tex_fileName, tcm_fileName;
148
149         if (m_texture != 0)
150         {
151                 tex_fileName = idToFilePath(m_texture);
152                 deleteTexture(m_texture);
153         }
154         if (m_tcm != 0)
155         {
156                 tcm_fileName = idToFilePath(m_tcm);
157                 deleteTexture(m_tcm);
158         }
159
160         ATexturedRenderable::setTextureManager(manager);
161
162         if (m_texture != 0)
163         {
164                 m_texture = createTexture(tex_fileName).id();
165         }
166         if (m_tcm != 0)
167         {
168                 m_texture = createTexture(tcm_fileName).id();
169         }
170 }
171
172 void QWZM::setTCMaskTexture(QString fileName)
173 {
174         if (m_tcm != 0)
175         {
176                 deleteTexture(m_tcm);
177         }
178         m_tcm = createTexture(fileName).id();
179 }
180
181 inline void QWZM::defaultConstructor()
182 {
183         m_texture = 0;
184         m_tcm = 0;
185         scale_all = 1.f;
186         scale_xyz[0] = 1.f;
187         scale_xyz[1] = 1.f;
188         scale_xyz[2] = 1.f;
189         winding = GL_CW;
190 }
191
192 QWZM::~QWZM()
193 {
194         if (m_texture != 0)
195         {
196                 deleteTexture(m_texture);
197         }
198         if (m_tcm != 0)
199         {
200                 deleteTexture(m_texture);
201         }
202 }
203
204 void QWZM::setScaleXYZ(GLfloat xyz)
205 {
206         scale_all = xyz;
207 }
208
209 void QWZM::setScaleX(GLfloat x)
210 {
211         scale_xyz[0] = x;
212 }
213
214 void QWZM::setScaleY(GLfloat y)
215 {
216         scale_xyz[1] = y;
217 }
218
219 void QWZM::setScaleZ(GLfloat z)
220 {
221         scale_xyz[2] = z;
222 }
223
224 void QWZM::reverseWindings()
225 {
226         if (winding == GL_CCW)
227         {
228                 winding = GL_CW;
229         }
230         else
231         {
232                 winding = GL_CCW;
233         }
234 }
235
236 void QWZM::applyTransformations()
237 {
238         scale(scale_all * scale_xyz[0], scale_all * scale_xyz[1], scale_all * scale_xyz[2]);
239 }