~ubuntu-branches/debian/sid/astromenace/sid

« back to all changes in this revision

Viewing changes to AstroMenaceSource/Core/RendererInterface/OGL_Draw3D.cpp

  • Committer: Package Import Robot
  • Author(s): Boris Pek
  • Date: 2013-04-09 02:04:25 UTC
  • Revision ID: package-import@ubuntu.com-20130409020425-a7fl9xk4diamw6di
Tags: upstream-1.3.1+repack
Import upstream version 1.3.1+repack

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/************************************************************************************
 
2
 
 
3
        AstroMenace (Hardcore 3D space shooter with spaceship upgrade possibilities)
 
4
        Copyright © 2006-2012 Michael Kurinnoy, Viewizard
 
5
 
 
6
 
 
7
        AstroMenace 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 3 of the License, or
 
10
        (at your option) any later version.
 
11
 
 
12
        AstroMenace 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 AstroMenace. If not, see <http://www.gnu.org/licenses/>.
 
19
 
 
20
 
 
21
        Web Site: http://www.viewizard.com/
 
22
        Project: http://sourceforge.net/projects/openastromenace/
 
23
        E-mail: viewizard@viewizard.com
 
24
 
 
25
*************************************************************************************/
 
26
 
 
27
 
 
28
#include "RendererInterface.h"
 
29
 
 
30
 
 
31
 
 
32
extern  int tmpPrimCountGL;
 
33
extern  PFNGLCLIENTACTIVETEXTUREARBPROC glClientActiveTexture_ARB;
 
34
extern  eDevCaps OpenGL_DevCaps;
 
35
 
 
36
 
 
37
 
 
38
 
 
39
 
 
40
 
 
41
//------------------------------------------------------------------------------------
 
42
// данный для индекс буфера
 
43
//------------------------------------------------------------------------------------
 
44
int VertexIndexCount = 0;
 
45
GLuint *VertexIndex = 0;
 
46
GLuint *IndexVBO = 0;
 
47
 
 
48
//------------------------------------------------------------------------------------
 
49
// Инициализация данных индекс буфера
 
50
//------------------------------------------------------------------------------------
 
51
void vw_Internal_InitializationIndexBufferData()
 
52
{
 
53
        VertexIndexCount = 0;
 
54
        VertexIndex = 0;
 
55
        IndexVBO = 0;
 
56
}
 
57
//------------------------------------------------------------------------------------
 
58
// Чистка памяти данных индекс буфера
 
59
//------------------------------------------------------------------------------------
 
60
void vw_Internal_ReleaseIndexBufferData()
 
61
{
 
62
        if (VertexIndex != 0){delete [] VertexIndex; VertexIndex = 0;}
 
63
        VertexIndexCount = 0;
 
64
        if (IndexVBO != 0){vw_DeleteVBO(*IndexVBO); delete IndexVBO; IndexVBO=0;}
 
65
}
 
66
 
 
67
 
 
68
 
 
69
 
 
70
 
 
71
//------------------------------------------------------------------------------------
 
72
// устанавливаем указатели, готовимся к прорисовке
 
73
//------------------------------------------------------------------------------------
 
74
GLuint *vw_SendVertices_EnableStatesAndPointers(int NumVertices, int DataFormat, void *Data, int Stride, unsigned int *VBO, unsigned int RangeStart, unsigned int *DataIndex, unsigned int *DataIndexVBO)
 
75
{
 
76
        // если ничего не передали
 
77
        if (Data == 0 && VBO == 0) return 0;
 
78
 
 
79
        // флаг нужно ли с вбо делать
 
80
        bool NeedVBO = OpenGL_DevCaps.VBOSupported;
 
81
        if (VBO == 0) NeedVBO = false;
 
82
 
 
83
 
 
84
        // обязательно в байты, т.к. делаем смещение в байтах!
 
85
        BYTE *TMP = (BYTE *)Data;
 
86
 
 
87
        // чтобы знать сколько отступать, кол-во ед. элементов, в нашем случае float
 
88
        intptr_t AddStride = 0;
 
89
        // кол-во текстур
 
90
        int TextQ = DataFormat & 0x000000F;
 
91
        // длина блока
 
92
        int TextSize = 2;
 
93
        int TextCoordType = 1; // float
 
94
        switch (DataFormat & 0x0F00000)
 
95
        {
 
96
                case 0x0100000: TextSize = 1;   break;
 
97
                case 0x0200000: TextSize = 2;   break;
 
98
                case 0x0300000: TextSize = 3;   break;
 
99
                case 0x0400000: TextSize = 4;   break;
 
100
                // short
 
101
                case 0x0500000: TextSize = 1; TextCoordType = 2;        break;
 
102
                case 0x0600000: TextSize = 2; TextCoordType = 2;        break;
 
103
                case 0x0700000: TextSize = 3; TextCoordType = 2;        break;
 
104
                case 0x0800000: TextSize = 4; TextCoordType = 2;        break;
 
105
        }
 
106
 
 
107
        if (NeedVBO) vw_BindVBO(RI_ARRAY_BUFFER, *VBO);
 
108
 
 
109
 
 
110
        // делаем установку поинтеров + ставим смещения для прорисовки
 
111
        if ((DataFormat & 0x000F000) == RI_3f_XYZ)
 
112
        {
 
113
                glEnableClientState(GL_VERTEX_ARRAY);
 
114
                if (NeedVBO)
 
115
                        glVertexPointer(3, GL_FLOAT, Stride, (intptr_t *)(AddStride));
 
116
                else
 
117
                        glVertexPointer(3, GL_FLOAT, Stride, TMP + AddStride);
 
118
                AddStride += 3*sizeof(GLfloat);
 
119
        }
 
120
        if ((DataFormat & 0x000F000) == RI_3i_XYZ)
 
121
        {
 
122
                glEnableClientState(GL_VERTEX_ARRAY);
 
123
                if (NeedVBO)
 
124
                        glVertexPointer(3, GL_INT, Stride, (BYTE *)(AddStride));
 
125
                else
 
126
                        glVertexPointer(3, GL_INT, Stride, TMP + AddStride);
 
127
                AddStride += 3*sizeof(GLint);
 
128
        }
 
129
        if ((DataFormat & 0x000F000) == RI_3s_XYZ)
 
130
        {
 
131
                glEnableClientState(GL_VERTEX_ARRAY);
 
132
                if (NeedVBO)
 
133
                        glVertexPointer(3, GL_SHORT, Stride, (BYTE *)(AddStride));
 
134
                else
 
135
                        glVertexPointer(3, GL_SHORT, Stride, TMP + AddStride);
 
136
                AddStride += 3*sizeof(GLshort);
 
137
        }
 
138
 
 
139
        if ((DataFormat & 0x000F000) == RI_2f_XY)
 
140
        {
 
141
                glEnableClientState(GL_VERTEX_ARRAY);
 
142
                if (NeedVBO)
 
143
                        glVertexPointer(2, GL_FLOAT, Stride, (BYTE *)(AddStride));
 
144
                else
 
145
                        glVertexPointer(2, GL_FLOAT, Stride, TMP + AddStride);
 
146
                AddStride += 2*sizeof(GLfloat);
 
147
        }
 
148
        if ((DataFormat & 0x000F000) == RI_2s_XY)
 
149
        {
 
150
                glEnableClientState(GL_VERTEX_ARRAY);
 
151
                if (NeedVBO)
 
152
                        glVertexPointer(2, GL_SHORT, Stride, (BYTE *)(AddStride));
 
153
                else
 
154
                        glVertexPointer(2, GL_SHORT, Stride, TMP + AddStride);
 
155
                AddStride += 2*sizeof(GLshort);
 
156
        }
 
157
 
 
158
 
 
159
        if ((DataFormat & 0x0000F00) == RI_3f_NORMAL)
 
160
        {
 
161
                glEnableClientState(GL_NORMAL_ARRAY);
 
162
                if (NeedVBO)
 
163
                        glNormalPointer(GL_FLOAT, Stride, (BYTE *)(AddStride));
 
164
                else
 
165
                        glNormalPointer(GL_FLOAT, Stride, TMP + AddStride);
 
166
                AddStride += 3*sizeof(GLfloat);
 
167
        }
 
168
 
 
169
 
 
170
        if ((DataFormat & 0x00000F0) == RI_4f_COLOR)
 
171
        {
 
172
                glEnableClientState(GL_COLOR_ARRAY);
 
173
                if (NeedVBO)
 
174
                        glColorPointer(4, GL_FLOAT, Stride, (BYTE *)(AddStride));
 
175
                else
 
176
                        glColorPointer(4, GL_FLOAT, Stride, TMP + AddStride);
 
177
                AddStride += 4*sizeof(GLfloat);
 
178
        }
 
179
        if ((DataFormat & 0x00000F0) == RI_4ub_COLOR)
 
180
        {
 
181
                glEnableClientState(GL_COLOR_ARRAY);
 
182
                if (NeedVBO)
 
183
                        glColorPointer(4, GL_UNSIGNED_BYTE, Stride, (BYTE *)(AddStride));
 
184
                else
 
185
                        glColorPointer(4, GL_UNSIGNED_BYTE, Stride, TMP + AddStride);
 
186
                AddStride += 4*sizeof(GLubyte);
 
187
        }
 
188
 
 
189
 
 
190
        if (TextQ > 0)// текстурные коорд. есть...
 
191
        {
 
192
                for (int i=0; i<TextQ; i++)
 
193
                {
 
194
                        if (glClientActiveTexture_ARB != 0) glClientActiveTexture_ARB(GL_TEXTURE0+i);
 
195
                        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
196
 
 
197
                        switch (TextCoordType)
 
198
                        {
 
199
                                case 1:
 
200
                                {
 
201
                                        if (NeedVBO)
 
202
                                                glTexCoordPointer(TextSize, GL_FLOAT, Stride, (BYTE *)(AddStride));
 
203
                                        else
 
204
                                                glTexCoordPointer(TextSize, GL_FLOAT, Stride, TMP + AddStride);
 
205
                                        if ((DataFormat & 0xF000000) == RI_SEPARATE_TEX_COORD) AddStride += TextSize*sizeof(GLfloat);
 
206
                                }
 
207
                                break;
 
208
                                case 2:
 
209
                                {
 
210
                                        if (NeedVBO)
 
211
                                                glTexCoordPointer(TextSize, GL_SHORT, Stride, (BYTE *)(AddStride));
 
212
                                        else
 
213
                                                glTexCoordPointer(TextSize, GL_SHORT, Stride, TMP + AddStride);
 
214
                                        if ((DataFormat & 0xF000000) == RI_SEPARATE_TEX_COORD) AddStride += TextSize*sizeof(GLshort);
 
215
                                }
 
216
                                break;
 
217
                        }
 
218
                }
 
219
        }
 
220
 
 
221
 
 
222
 
 
223
        // указатель на смещение (в случае вбо) или на массив индексов
 
224
        GLuint *VertexIndexPointer = 0;
 
225
        // если нет своего, ставим общей массив индексов
 
226
        if (DataIndexVBO == 0 && DataIndex == 0)
 
227
        {
 
228
                // собираем если нужно массив индексов
 
229
                if ((unsigned int)VertexIndexCount < (unsigned int)(NumVertices+RangeStart))
 
230
                {
 
231
                        if (VertexIndex != 0){delete [] VertexIndex; VertexIndex = 0;}
 
232
                        VertexIndexCount = 0;
 
233
 
 
234
                        VertexIndex = new GLuint[NumVertices+RangeStart]; if (VertexIndex == 0) return 0;
 
235
 
 
236
                        VertexIndexCount = NumVertices+RangeStart;
 
237
                        for (unsigned int i=0; i<NumVertices+RangeStart; i++) VertexIndex[i] = i;
 
238
 
 
239
                        // если держим VBO, все это один раз сразу запихиваем в видео память
 
240
                        if (OpenGL_DevCaps.VBOSupported)
 
241
                        {
 
242
                                // прежде всего удаляем старый буфер, если он был
 
243
                                if (IndexVBO != 0){vw_DeleteVBO(*IndexVBO); delete IndexVBO; IndexVBO=0;}
 
244
                                // создаем новый
 
245
                                IndexVBO = new GLuint;
 
246
                                if (!vw_BuildIBO(VertexIndexCount, VertexIndex, IndexVBO))
 
247
                                {
 
248
                                        delete IndexVBO; IndexVBO=0;
 
249
                                }
 
250
                        }
 
251
                }
 
252
 
 
253
                VertexIndexPointer = VertexIndex+RangeStart;
 
254
 
 
255
                // собственно включаем индекс-вбо
 
256
                if (OpenGL_DevCaps.VBOSupported)
 
257
                if (IndexVBO != 0)
 
258
                {
 
259
                        vw_BindVBO(RI_ELEMENT_ARRAY_BUFFER, *IndexVBO);
 
260
                        VertexIndexPointer = NULL;
 
261
                        VertexIndexPointer = VertexIndexPointer+RangeStart;
 
262
                }
 
263
        }
 
264
        else
 
265
        {       // если массив или вбо индексов передали, просто подключаем их
 
266
                VertexIndexPointer = DataIndex+RangeStart;
 
267
 
 
268
                // собственно включаем индекс-вбо
 
269
                if (OpenGL_DevCaps.VBOSupported)
 
270
                if (DataIndexVBO != 0)
 
271
                {
 
272
                        vw_BindVBO(RI_ELEMENT_ARRAY_BUFFER, *DataIndexVBO);
 
273
                        VertexIndexPointer = NULL;
 
274
                        VertexIndexPointer = VertexIndexPointer+RangeStart;
 
275
                }
 
276
        }
 
277
 
 
278
        // возвращаем индексы основной программе
 
279
        return VertexIndexPointer;
 
280
}
 
281
 
 
282
 
 
283
 
 
284
 
 
285
 
 
286
//------------------------------------------------------------------------------------
 
287
// выключаем все после прорисовки
 
288
//------------------------------------------------------------------------------------
 
289
void vw_SendVertices_DisableStatesAndPointers(int DataFormat, unsigned int *VBO, unsigned int *VAO)
 
290
{
 
291
        // флаг нужно ли с вaо делать
 
292
        bool NeedVAO = OpenGL_DevCaps.VAOSupported;
 
293
        if (VAO == 0) NeedVAO = false;
 
294
 
 
295
        if (NeedVAO)
 
296
        {
 
297
                vw_BindVAO(0);
 
298
        }
 
299
        else
 
300
        {
 
301
                // флаг нужно ли с вбо делать
 
302
                bool NeedVBO = OpenGL_DevCaps.VBOSupported;
 
303
                if (VBO == 0) NeedVBO = false;
 
304
 
 
305
 
 
306
                if ((DataFormat & 0x0000F00) != 0) glDisableClientState(GL_NORMAL_ARRAY);
 
307
                if ((DataFormat & 0x00000F0) != 0) glDisableClientState(GL_COLOR_ARRAY);
 
308
                glDisableClientState(GL_VERTEX_ARRAY);
 
309
 
 
310
                // кол-во текстур
 
311
                int TextQ = DataFormat & 0x000000F;
 
312
                for (int i=TextQ-1; i>=0; i--)
 
313
                {
 
314
                        if (glClientActiveTexture_ARB != 0) glClientActiveTexture_ARB(GL_TEXTURE0+i);
 
315
                        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
316
                }
 
317
 
 
318
 
 
319
                // сбрасываем индексный и вертексный буфера, если они были установлены
 
320
                if (IndexVBO != 0) vw_BindVBO(RI_ELEMENT_ARRAY_BUFFER, 0);
 
321
                if (NeedVBO) vw_BindVBO(RI_ARRAY_BUFFER, 0);
 
322
        }
 
323
}
 
324
 
 
325
 
 
326
 
 
327
 
 
328
 
 
329
 
 
330
//------------------------------------------------------------------------------------
 
331
// Процедура передачи последовательности вертексов для прорисовки
 
332
//------------------------------------------------------------------------------------
 
333
void vw_SendVertices(int PrimitiveType, int NumVertices, int DataFormat, void *Data, int Stride, unsigned int *VBO, unsigned int RangeStart, unsigned int *DataIndex, unsigned int *DataIndexVBO, unsigned int *VAO)
 
334
{
 
335
        // если ничего не передали
 
336
        if (Data == 0 && VBO == 0 && VAO == 0) return;
 
337
        // флаг нужно ли с вбо делать
 
338
        bool NeedVBO = OpenGL_DevCaps.VBOSupported;
 
339
        if (VBO == 0) NeedVBO = false;
 
340
        // флаг нужно ли с вaо делать
 
341
        bool NeedVAO = OpenGL_DevCaps.VAOSupported;
 
342
        if (VAO == 0) NeedVAO = false;
 
343
 
 
344
 
 
345
        // устанавливаем все необходимые указатели для прорисовки и получаем индексы
 
346
        GLuint *VertexIndexPointer = 0;
 
347
        if (NeedVAO)
 
348
        {
 
349
                vw_BindVAO(*VAO);
 
350
        }
 
351
        else
 
352
        {
 
353
                VertexIndexPointer = vw_SendVertices_EnableStatesAndPointers(NumVertices, DataFormat, Data, Stride, VBO, RangeStart, DataIndex, DataIndexVBO);
 
354
        }
 
355
 
 
356
// 1) Нельзя использовать short индексы (глючит в линуксе на картах нвидия, проверял на 97.55 драйвере)
 
357
// 2) Нельзя рисовать через glBegin-glEnd и glDrawArray - проблемы в линуксе у ati драйверов (на glDrawArray вообще сегфолтит)
 
358
// 3) С glDrawRangeElements могут быть неприятные сюрпризы на маках (интел+интел видео), сегфолты даже если учесть все ограничения (вертекс и индекс)
 
359
 
 
360
 
 
361
        // рисуем
 
362
        switch(PrimitiveType)
 
363
        {
 
364
                case RI_POINTS:
 
365
                        glDrawElements(GL_POINTS,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer);
 
366
                        tmpPrimCountGL += NumVertices;
 
367
                        break;
 
368
 
 
369
                case RI_LINES:
 
370
                        glDrawElements(GL_LINES,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer);
 
371
                        tmpPrimCountGL += NumVertices/2;
 
372
                        break;
 
373
 
 
374
                case RI_TRIANGLES:
 
375
                        glDrawElements(GL_TRIANGLES,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer);
 
376
                        tmpPrimCountGL += NumVertices/3;
 
377
                        break;
 
378
 
 
379
                case RI_TRIANGLE_STRIP:
 
380
                        glDrawElements(GL_TRIANGLE_STRIP,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer);
 
381
                        tmpPrimCountGL += NumVertices-2;
 
382
                        break;
 
383
 
 
384
                case RI_TRIANGLE_FAN:
 
385
                        glDrawElements(GL_TRIANGLE_FAN,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer);
 
386
                        tmpPrimCountGL += NumVertices-2;
 
387
                        break;
 
388
 
 
389
                case RI_QUADS:
 
390
                        glDrawElements(GL_QUADS,NumVertices,GL_UNSIGNED_INT,VertexIndexPointer);
 
391
                        tmpPrimCountGL += NumVertices/4;
 
392
                        break;
 
393
        }
 
394
 
 
395
 
 
396
        // выключаем все что включали
 
397
        vw_SendVertices_DisableStatesAndPointers(DataFormat, VBO, VAO);
 
398
 
 
399
}