source: trunk/src/gpu/vertexbuffer.cpp @ 2816

Last change on this file since 2816 was 2816, checked in by lolbot, 7 years ago

fixed 542 files out of 2754:

  • removed 0 CR characters
  • removed 0 trailing whitespaces
  • replaced 0 tabs with spaces
  • fixed 542 svn:eol-style properties
  • Property svn:eol-style set to LF
File size: 22.8 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
5//   This program is free software; you can redistribute it and/or
6//   modify it under the terms of the Do What The Fuck You Want To
7//   Public License, Version 2, as published by Sam Hocevar. See
8//   http://www.wtfpl.net/ for more details.
9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include "core.h"
16#include "lolgl.h"
17
18#if defined _WIN32 && defined USE_D3D9
19#   define FAR
20#   define NEAR
21#   include <d3d9.h>
22#elif defined _XBOX
23#   include <xtl.h>
24#   undef near /* Fuck Microsoft */
25#   undef far /* Fuck Microsoft again */
26#endif
27
28using namespace std;
29
30namespace lol
31{
32
33//
34// The VertexBufferData class
35// --------------------------
36//
37
38class VertexBufferData
39{
40    friend class VertexBuffer;
41    friend class VertexDeclaration;
42
43    size_t m_size;
44
45#if defined USE_D3D9
46    IDirect3DDevice9 *m_dev;
47    IDirect3DVertexBuffer9 *m_vbo;
48#elif defined _XBOX
49    D3DDevice *m_dev;
50    D3DVertexBuffer *m_vbo;
51#else
52    GLuint m_vbo;
53    uint8_t *m_memory;
54#endif
55};
56
57//
58// The VertexDeclarationData class
59// -------------------------------
60//
61
62class VertexDeclarationData
63{
64    friend class VertexBuffer;
65    friend class VertexDeclaration;
66
67#if defined USE_D3D9
68    IDirect3DDevice9 *m_dev;
69    IDirect3DVertexDeclaration9 *m_vdecl;
70#elif defined _XBOX
71    D3DDevice *m_dev;
72    D3DVertexDeclaration *m_vdecl;
73#else
74#endif
75};
76
77//
78// The VertexDeclaration class
79// ---------------------------
80//
81
82VertexStreamBase const VertexStreamBase::Empty;
83
84VertexDeclaration::VertexDeclaration(VertexStreamBase const &s1,
85                                     VertexStreamBase const &s2,
86                                     VertexStreamBase const &s3,
87                                     VertexStreamBase const &s4,
88                                     VertexStreamBase const &s5,
89                                     VertexStreamBase const &s6,
90                                     VertexStreamBase const &s7,
91                                     VertexStreamBase const &s8,
92                                     VertexStreamBase const &s9,
93                                     VertexStreamBase const &s10,
94                                     VertexStreamBase const &s11,
95                                     VertexStreamBase const &s12)
96  : m_count(0),
97    m_data(new VertexDeclarationData())
98{
99    if (&s1 != &VertexStreamBase::Empty) AddStream(s1);
100    if (&s2 != &VertexStreamBase::Empty) AddStream(s2);
101    if (&s3 != &VertexStreamBase::Empty) AddStream(s3);
102    if (&s4 != &VertexStreamBase::Empty) AddStream(s4);
103    if (&s5 != &VertexStreamBase::Empty) AddStream(s5);
104    if (&s6 != &VertexStreamBase::Empty) AddStream(s6);
105    if (&s7 != &VertexStreamBase::Empty) AddStream(s7);
106    if (&s8 != &VertexStreamBase::Empty) AddStream(s8);
107    if (&s9 != &VertexStreamBase::Empty) AddStream(s9);
108    if (&s10 != &VertexStreamBase::Empty) AddStream(s10);
109    if (&s11 != &VertexStreamBase::Empty) AddStream(s11);
110    if (&s12 != &VertexStreamBase::Empty) AddStream(s12);
111    Initialize();
112}
113
114VertexDeclaration::~VertexDeclaration()
115{
116#if defined _XBOX || defined USE_D3D9
117    if (FAILED(m_data->m_vdecl->Release()))
118        Abort();
119#else
120
121#endif
122
123    delete m_data;
124}
125
126void VertexDeclaration::Bind()
127{
128#if defined _XBOX || defined USE_D3D9
129    if (FAILED(m_data->m_dev->SetVertexDeclaration(m_data->m_vdecl)))
130        Abort();
131#else
132    /* FIXME: Nothing to do? */
133#endif
134}
135
136void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count)
137{
138    if (count <= 0)
139        return;
140
141#if defined _XBOX || defined USE_D3D9
142    switch (type)
143    {
144    case MeshPrimitive::Triangles:
145        if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_TRIANGLELIST,
146                                                skip, count)))
147            Abort();
148        break;
149    case MeshPrimitive::TriangleStrips:
150        if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_TRIANGLESTRIP,
151                                                skip, count)))
152            Abort();
153        break;
154    case MeshPrimitive::TriangleFans:
155        if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_TRIANGLEFAN,
156                                                skip, count)))
157            Abort();
158        break;
159    case MeshPrimitive::Points:
160        if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_POINTLIST,
161                                                skip, count)))
162            Abort();
163        break;
164    case MeshPrimitive::Lines:
165        if (FAILED(m_data->m_dev->DrawPrimitive(D3DPT_LINELIST,
166                                                skip, count)))
167            Abort();
168        break;
169    }
170#else
171    /* FIXME: this has nothing to do here! */
172    switch (type)
173    {
174    case MeshPrimitive::Triangles:
175        glDrawArrays(GL_TRIANGLES, skip, count);
176        break;
177    case MeshPrimitive::TriangleStrips:
178        glDrawArrays(GL_TRIANGLE_STRIP, skip, count);
179        break;
180    case MeshPrimitive::TriangleFans:
181        glDrawArrays(GL_TRIANGLE_FAN, skip, count);
182        break;
183    case MeshPrimitive::Points:
184        glDrawArrays(GL_POINTS, skip, count);
185        break;
186    case MeshPrimitive::Lines:
187        glDrawArrays(GL_LINES, skip, count);
188        break;
189    }
190#endif
191}
192
193void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase,
194                                            int vskip, int vcount,
195                                            int skip, int count)
196{
197    if (count <= 0)
198        return;
199
200#if defined _XBOX || defined USE_D3D9
201    switch (type)
202    {
203    case MeshPrimitive::Triangles:
204        count = count / 3;
205        if (FAILED(m_data->m_dev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
206                                           vbase, vskip, vcount, skip, count)))
207            Abort();
208        break;
209    case MeshPrimitive::TriangleStrips:
210        count = count - 2;
211        if (FAILED(m_data->m_dev->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,
212                                           vbase, vskip, vcount, skip, count)))
213            Abort();
214        break;
215    case MeshPrimitive::TriangleFans:
216        count = count - 2;
217        if (FAILED(m_data->m_dev->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN,
218                                           vbase, vskip, vcount, skip, count)))
219            Abort();
220        break;
221    case MeshPrimitive::Points:
222        if (FAILED(m_data->m_dev->DrawIndexedPrimitive(D3DPT_POINTLIST,
223                                           vbase, vskip, vcount, skip, count)))
224            Abort();
225        break;
226    case MeshPrimitive::Lines:
227        if (FAILED(m_data->m_dev->DrawIndexedPrimitive(D3DPT_LINELIST,
228                                           vbase, vskip, vcount, skip, count)))
229            Abort();
230        break;
231    }
232#else
233    /* FIXME: this has nothing to do here! */
234    switch (type)
235    {
236    case MeshPrimitive::Triangles:
237        /* FIXME: ignores most of the arguments! */
238        UNUSED(vbase, vskip, vcount, skip);
239        glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, 0);
240        break;
241    case MeshPrimitive::TriangleStrips:
242        /* FIXME: ignores most of the arguments! */
243        UNUSED(vbase, vskip, vcount, skip);
244        glDrawElements(GL_TRIANGLE_STRIP, count, GL_UNSIGNED_SHORT, 0);
245        break;
246    case MeshPrimitive::TriangleFans:
247        /* FIXME: ignores most of the arguments! */
248        UNUSED(vbase, vskip, vcount, skip);
249        glDrawElements(GL_TRIANGLE_FAN, count, GL_UNSIGNED_SHORT, 0);
250        break;
251    case MeshPrimitive::Points:
252        /* FIXME: ignores most of the arguments! */
253        UNUSED(vbase, vskip, vcount, skip);
254        glDrawElements(GL_POINTS, count, GL_UNSIGNED_SHORT, 0);
255        break;
256    case MeshPrimitive::Lines:
257        /* FIXME: ignores most of the arguments! */
258        UNUSED(vbase, vskip, vcount, skip);
259        glDrawElements(GL_LINES, count, GL_UNSIGNED_SHORT, 0);
260        break;
261    }
262#endif
263}
264
265void VertexDeclaration::Unbind()
266{
267#if defined _XBOX || defined USE_D3D9
268    int stream = -1;
269    for (int i = 0; i < m_count; i++)
270        if (m_streams[i].index != stream)
271        {
272            stream = m_streams[i].index;
273            if (FAILED(m_data->m_dev->SetStreamSource(stream, 0, 0, 0)))
274                Abort();
275        }
276    /* "NULL is an invalid input to SetVertexDeclaration" (DX9 guide), so
277     * we just don't touch the current vertex declaration. */
278#elif !defined __CELLOS_LV2__
279    for (int i = 0; i < m_count; i++)
280    {
281        if (m_streams[i].reg >= 0)
282        {
283            for (int j = i + 1; j < m_count; j++)
284                if (m_streams[j].reg == m_streams[i].reg)
285                    m_streams[j].reg = -1;
286
287            glDisableVertexAttribArray(m_streams[i].reg);
288        }
289    }
290    glBindBuffer(GL_ARRAY_BUFFER, 0);
291#else
292    /* Or even: */
293    glDisableClientState(GL_VERTEX_ARRAY);
294    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
295    glDisableClientState(GL_NORMAL_ARRAY);
296    glDisableClientState(GL_COLOR_ARRAY);
297#endif
298}
299
300void VertexDeclaration::SetStream(VertexBuffer *vb, ShaderAttrib attr1,
301                                                    ShaderAttrib attr2,
302                                                    ShaderAttrib attr3,
303                                                    ShaderAttrib attr4,
304                                                    ShaderAttrib attr5,
305                                                    ShaderAttrib attr6,
306                                                    ShaderAttrib attr7,
307                                                    ShaderAttrib attr8,
308                                                    ShaderAttrib attr9,
309                                                    ShaderAttrib attr10,
310                                                    ShaderAttrib attr11,
311                                                    ShaderAttrib attr12)
312{
313    if (!vb->m_data->m_size)
314        return;
315
316#if defined _XBOX || defined USE_D3D9
317    /* Only the first item is required to know which stream this
318     * is about; the rest of the information is stored in the
319     * vertex declaration already. */
320    uint32_t usage = (attr1.m_flags >> 16) & 0xffff;
321    uint32_t index = attr1.m_flags & 0xffff;
322
323    /* Find the stream number */
324    uint32_t usage_index = 0;
325    int stream = -1;
326    for (int i = 0; i < m_count; i++)
327        if (m_streams[i].usage == usage)
328            if (usage_index++ == index)
329            {
330                stream = m_streams[i].index;
331                break;
332            }
333
334    /* Compute this stream's stride */
335    int stride = 0;
336    for (int i = 0; i < m_count; i++)
337        if (stream == m_streams[i].index)
338            stride += m_streams[i].size;
339
340    /* Now we know the stream index and the element stride */
341    /* FIXME: precompute most of the crap above! */
342    if (stream >= 0)
343    {
344        if (FAILED(m_data->m_dev->SetStreamSource(stream, vb->m_data->m_vbo,
345                                                  0, stride)))
346            Abort();
347    }
348#else
349    glBindBuffer(GL_ARRAY_BUFFER, vb->m_data->m_vbo);
350    ShaderAttrib l[12] = { attr1, attr2, attr3, attr4, attr5, attr6,
351                           attr7, attr8, attr9, attr10, attr11, attr12 };
352    for (int n = 0; n < 12 && l[n].m_flags != (uint64_t)0 - 1; n++)
353    {
354        uint32_t reg = l[n].m_flags >> 32;
355        uint32_t usage = (l[n].m_flags >> 16) & 0xffff;
356        uint32_t index = l[n].m_flags & 0xffff;
357
358#   if !defined __CELLOS_LV2__
359        glEnableVertexAttribArray((GLint)reg);
360#   else
361        switch (usage)
362        {
363        case VertexUsage::Position:
364            glEnableClientState(GL_VERTEX_ARRAY);
365            break;
366        case VertexUsage::TexCoord:
367        case VertexUsage::TexCoordExt:
368            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
369            break;
370        case VertexUsage::Normal:
371            glEnableClientState(GL_NORMAL_ARRAY);
372            break;
373        case VertexUsage::Color:
374            glEnableClientState(GL_COLOR_ARRAY);
375            break;
376        }
377#   endif
378
379        /* We need to parse the whole vertex declaration to retrieve
380         * the information. It sucks. */
381
382        int attr_index = 0;
383        /* First, find the stream index */
384        for (uint32_t usage_index = 0; attr_index < m_count; attr_index++)
385            if (m_streams[attr_index].usage == usage)
386                if (usage_index++ == index)
387                    break;
388
389        if (attr_index == m_count)
390        {
391            Log::Error("stream #%d with usage %x not found in declaration\n",
392                       index, usage);
393            attr_index = 0;
394        }
395
396        /* Now compute the stride and offset up to this stream index */
397        int stride = 0, offset = 0;
398        for (int i = 0; i < m_count; i++)
399            if (m_streams[i].index == m_streams[attr_index].index)
400            {
401                /* Remember the register used for this stream */
402                m_streams[i].reg = reg;
403
404                stride += m_streams[i].size;
405                if (i < attr_index)
406                    offset += m_streams[i].size;
407            }
408
409        /* Finally, we need to retrieve the type of the data */
410#   if !defined GL_DOUBLE
411#       define GL_DOUBLE 0
412#   endif
413        static struct { GLint size; GLenum type; } const tlut[] =
414        {
415            { 0, 0 },
416            { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* half */
417            { 1, GL_FLOAT }, { 2, GL_FLOAT }, { 3, GL_FLOAT },
418                { 4, GL_FLOAT }, /* float */
419            { 1, GL_DOUBLE }, { 2, GL_DOUBLE }, { 3, GL_DOUBLE },
420                { 4, GL_DOUBLE }, /* double */
421            { 1, GL_BYTE }, { 2, GL_BYTE }, { 3, GL_BYTE },
422                { 4, GL_BYTE }, /* int8_t */
423            { 1, GL_UNSIGNED_BYTE }, { 2, GL_UNSIGNED_BYTE },
424                { 3, GL_UNSIGNED_BYTE }, { 4, GL_UNSIGNED_BYTE }, /* uint8_t */
425            { 1, GL_SHORT }, { 2, GL_SHORT }, { 3, GL_SHORT },
426                { 4, GL_SHORT }, /* int16_t */
427            { 1, GL_UNSIGNED_SHORT }, { 2, GL_UNSIGNED_SHORT }, { 3,
428                GL_UNSIGNED_SHORT }, { 4, GL_UNSIGNED_SHORT }, /* uint16_t */
429            { 1, GL_INT }, { 2, GL_INT }, { 3, GL_INT },
430                { 4, GL_INT }, /* int32_t */
431            { 1, GL_UNSIGNED_INT }, { 2, GL_UNSIGNED_INT },
432                { 3, GL_UNSIGNED_INT }, { 4, GL_UNSIGNED_INT }, /* uint32_t */
433        };
434
435        int type_index = m_streams[attr_index].stream_type;
436        if (type_index < 0 || type_index >= (int)(sizeof(tlut) / sizeof(*tlut)))
437            type_index = 0;
438
439
440#   if !defined __CELLOS_LV2__
441        if (tlut[type_index].type == GL_FLOAT
442             || tlut[type_index].type == GL_DOUBLE
443             || tlut[type_index].type == GL_BYTE
444             || tlut[type_index].type == GL_UNSIGNED_BYTE
445#       if defined USE_GLEW && !defined __APPLE__
446             /* If this is not available, don't use it */
447             || !glVertexAttribIPointer
448#       endif
449             || false)
450        {
451            /* Normalize unsigned bytes by default, because it's usually
452             * some color information. */
453            GLboolean normalize = (tlut[type_index].type == GL_UNSIGNED_BYTE)
454                               || (tlut[type_index].type == GL_BYTE);
455            glVertexAttribPointer((GLint)reg, tlut[type_index].size,
456                                  tlut[type_index].type, normalize,
457                                  stride, (GLvoid const *)(uintptr_t)offset);
458        }
459#       if defined GL_VERSION_3_0
460        else
461        {
462            glVertexAttribIPointer((GLint)reg, tlut[type_index].size,
463                                   tlut[type_index].type,
464                                   stride, (GLvoid const *)(uintptr_t)offset);
465        }
466#       endif
467#   else
468        switch (usage)
469        {
470        case VertexUsage::Position:
471            glVertexPointer(tlut[type_index].size, tlut[type_index].type,
472                            stride, (GLvoid const *)(uintptr_t)offset);
473            break;
474        case VertexUsage::TexCoord:
475        case VertexUsage::TexCoordExt:
476            glTexCoordPointer(tlut[type_index].size, tlut[type_index].type,
477                              stride, (GLvoid const *)(uintptr_t)offset);
478            break;
479        case VertexUsage::Normal:
480            glNormalPointer(tlut[type_index].type,
481                            stride, (GLvoid const *)(uintptr_t)offset);
482            break;
483        case VertexUsage::Color:
484            glColorPointer(tlut[type_index].size, tlut[type_index].type,
485                           stride, (GLvoid const *)(uintptr_t)offset);
486            break;
487        default:
488            Log::Error("vertex usage %d is not supported yet\n", usage);
489            break;
490        }
491#   endif
492    }
493#endif
494}
495
496void VertexDeclaration::Initialize()
497{
498#if defined _XBOX || defined USE_D3D9
499    static D3DVERTEXELEMENT9 const end_element[] = { D3DDECL_END() };
500    static D3DDECLTYPE const X = D3DDECLTYPE_UNUSED;
501    static D3DDECLTYPE const tlut[] =
502    {
503        D3DDECLTYPE_UNUSED,
504        X, D3DDECLTYPE_FLOAT16_2, X, D3DDECLTYPE_FLOAT16_4, /* half */
505        D3DDECLTYPE_FLOAT1, D3DDECLTYPE_FLOAT2, D3DDECLTYPE_FLOAT3,
506            D3DDECLTYPE_FLOAT4, /* float */
507        X, X, X, X, /* double */
508        X, X, X, X, /* int8_t */
509        X, X, X, D3DDECLTYPE_UBYTE4N, /* uint8_t */
510        X, D3DDECLTYPE_SHORT2N, X, D3DDECLTYPE_SHORT4N, /* int16_t */
511        X, D3DDECLTYPE_USHORT2N, X, D3DDECLTYPE_USHORT4N, /* uint16_t */
512        X, X, X, X, /* int32_t */
513        X, X, X, X, /* uint32_t */
514    };
515    static D3DDECLUSAGE const ulut[] =
516    {
517        D3DDECLUSAGE_POSITION,
518        D3DDECLUSAGE_BLENDWEIGHT,
519        D3DDECLUSAGE_BLENDINDICES,
520        D3DDECLUSAGE_NORMAL,
521        D3DDECLUSAGE_PSIZE,
522        D3DDECLUSAGE_TEXCOORD,
523        D3DDECLUSAGE_TANGENT,
524        D3DDECLUSAGE_BINORMAL,
525        D3DDECLUSAGE_TESSFACTOR,
526#if defined _XBOX
527        D3DDECLUSAGE_TEXCOORD, /* FIXME: nonexistent */
528#else
529        D3DDECLUSAGE_POSITIONT,
530#endif
531        D3DDECLUSAGE_COLOR,
532        D3DDECLUSAGE_FOG,
533        D3DDECLUSAGE_DEPTH,
534        D3DDECLUSAGE_SAMPLE,
535    };
536
537    D3DVERTEXELEMENT9 elements[12 + 1];
538    for (int n = 0; n < m_count; n++)
539    {
540        elements[n].Stream = m_streams[n].index;
541        elements[n].Offset = 0;
542        for (int i = 0; i < n; i++)
543            if (m_streams[i].index == m_streams[n].index)
544                elements[n].Offset += m_streams[i].size;
545
546        if (m_streams[n].stream_type >= 0
547             && m_streams[n].stream_type < sizeof(tlut) / sizeof(*tlut))
548            elements[n].Type = tlut[m_streams[n].stream_type];
549        else
550            elements[n].Type = D3DDECLTYPE_UNUSED;
551
552        elements[n].Method = D3DDECLMETHOD_DEFAULT;
553
554        if (m_streams[n].usage >= 0
555             && m_streams[n].usage < sizeof(ulut) / sizeof(*ulut))
556            elements[n].Usage = ulut[m_streams[n].usage];
557        else
558            elements[n].Usage = D3DDECLUSAGE_POSITION;
559
560        elements[n].UsageIndex = 0;
561        for (int i = 0; i < n; i++)
562            if (elements[i].Stream == elements[n].Stream
563                 && elements[i].Usage == elements[n].Usage)
564                elements[n].UsageIndex++;
565    }
566    elements[m_count] = end_element[0];
567
568#   if defined USE_D3D9
569    m_data->m_dev = (IDirect3DDevice9 *)g_renderer->GetDevice();
570#   elif defined _XBOX
571    m_data->m_dev = (D3DDevice *)g_renderer->GetDevice();
572#   endif
573
574    if (FAILED(m_data->m_dev->CreateVertexDeclaration(elements,
575                                                      &m_data->m_vdecl)))
576        Abort();
577#else
578
579#endif
580}
581
582void VertexDeclaration::AddStream(VertexStreamBase const &s)
583{
584    int index = m_count ? m_streams[m_count - 1].index + 1 : 0;
585
586    for (int i = 0; s.m_streams[i].size; i++)
587    {
588        m_streams[m_count].stream_type = s.m_streams[i].stream_type;
589        m_streams[m_count].usage = s.m_streams[i].usage;
590        m_streams[m_count].size = s.m_streams[i].size;
591        m_streams[m_count].index = index;
592        m_streams[m_count].reg = -1;
593        m_count++;
594    }
595}
596
597int VertexDeclaration::GetStreamCount() const
598{
599    return m_count ? m_streams[m_count - 1].index + 1 : 0;
600}
601
602VertexStreamBase VertexDeclaration::GetStream(int index) const
603{
604    VertexStreamBase stream;
605    int n = 0;
606    int count = 0;
607
608    for (int i = 0; i < m_count; ++i)
609    {
610        if (m_streams[i].index != index)
611            continue;
612
613        switch (m_streams[i].stream_type)
614        {
615#define LOL_TYPE(T) \
616            case VertexStreamBase::Type##T: stream.AddStream<T>(n++, m_streams[i].usage); break;
617
618            LOL_TYPE(void)
619            LOL_TYPE(half)     LOL_TYPE(f16vec2) LOL_TYPE(f16vec3) LOL_TYPE(f16vec4)
620            LOL_TYPE(float)    LOL_TYPE(vec2)    LOL_TYPE(vec3)    LOL_TYPE(vec4)
621            LOL_TYPE(double)   LOL_TYPE(dvec2)   LOL_TYPE(dvec3)   LOL_TYPE(dvec4)
622            LOL_TYPE(int8_t)   LOL_TYPE(i8vec2)  LOL_TYPE(i8vec3)  LOL_TYPE(i8vec4)
623            LOL_TYPE(uint8_t)  LOL_TYPE(u8vec2)  LOL_TYPE(u8vec3)  LOL_TYPE(u8vec4)
624            LOL_TYPE(int16_t)  LOL_TYPE(i16vec2) LOL_TYPE(i16vec3) LOL_TYPE(i16vec4)
625            LOL_TYPE(uint16_t) LOL_TYPE(u16vec2) LOL_TYPE(u16vec3) LOL_TYPE(u16vec4)
626            LOL_TYPE(int32_t)  LOL_TYPE(ivec2)   LOL_TYPE(ivec3)   LOL_TYPE(ivec4)
627            LOL_TYPE(uint32_t) LOL_TYPE(uvec2)   LOL_TYPE(uvec3)   LOL_TYPE(uvec4)
628#undef LOL_TYPE
629        }
630        ++count;
631    }
632
633    while (count < 12)
634        stream.AddStream<void>(count++, VertexStreamBase::Typevoid);
635
636    return stream;
637}
638
639//
640// The VertexBuffer class
641// ----------------------
642//
643
644VertexBuffer::VertexBuffer(size_t size)
645  : m_data(new VertexBufferData)
646{
647    m_data->m_size = size;
648    if (!size)
649        return;
650#if defined USE_D3D9 || defined _XBOX
651#   if defined USE_D3D9
652    m_data->m_dev = (IDirect3DDevice9 *)g_renderer->GetDevice();
653#   elif defined _XBOX
654    m_data->m_dev = (D3DDevice *)g_renderer->GetDevice();
655#   endif
656
657    if (FAILED(m_data->m_dev->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, nullptr,
658                                               D3DPOOL_MANAGED, &m_data->m_vbo, nullptr)))
659        Abort();
660#else
661    glGenBuffers(1, &m_data->m_vbo);
662    m_data->m_memory = new uint8_t[size];
663#endif
664}
665
666VertexBuffer::~VertexBuffer()
667{
668    if (m_data->m_size)
669    {
670#if defined USE_D3D9 || defined _XBOX
671        if (FAILED(m_data->m_vbo->Release()))
672            Abort();
673#else
674        glDeleteBuffers(1, &m_data->m_vbo);
675        delete[] m_data->m_memory;
676#endif
677    }
678    delete m_data;
679}
680
681size_t VertexBuffer::GetSize()
682{
683    return m_data->m_size;
684}
685
686void *VertexBuffer::Lock(size_t offset, size_t size)
687{
688    if (!m_data->m_size)
689        return nullptr;
690#if defined USE_D3D9 || defined _XBOX
691    void *ret;
692    if (FAILED(m_data->m_vbo->Lock(offset, size, (void **)&ret, 0)))
693        Abort();
694    return ret;
695#else
696    /* FIXME: is there a way to use "size"? */
697    UNUSED(size);
698    return m_data->m_memory + offset;
699#endif
700}
701
702void VertexBuffer::Unlock()
703{
704    if (!m_data->m_size)
705        return;
706#if defined USE_D3D9 || defined _XBOX
707    if (FAILED(m_data->m_vbo->Unlock()))
708        Abort();
709#else
710    glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
711    glBufferData(GL_ARRAY_BUFFER, m_data->m_size, m_data->m_memory,
712                 GL_STATIC_DRAW);
713    glBindBuffer(GL_ARRAY_BUFFER, 0);
714#endif
715}
716
717} /* namespace lol */
718
Note: See TracBrowser for help on using the repository browser.