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

Last change on this file since 2216 was 2216, checked in by touky, 7 years ago

New year copyright update.

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