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
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#endif
23
24using namespace std;
25
26#if defined USE_D3D9
27extern IDirect3DDevice9 *g_d3ddevice;
28#elif defined _XBOX
29extern D3DDevice *g_d3ddevice;
30#endif
31
32namespace lol
33{
34
35//
36// The VertexBufferData class
37// --------------------------
38//
39
40class VertexBufferData
41{
42    friend class VertexBuffer;
43    friend class VertexDeclaration;
44
45    size_t m_size;
46
47#if defined USE_D3D9
48    IDirect3DVertexBuffer9 *m_vbo;
49#elif defined _XBOX
50    D3DVertexBuffer *m_vbo;
51#else
52    GLuint m_vbo;
53    uint8_t *m_memory;
54#endif
55};
56
57//
58// The VertexDeclaration class
59// ---------------------------
60//
61
62VertexStreamBase const VertexStreamBase::Empty;
63
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
101    if (FAILED(vdecl->Release()))
102        Abort();
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
117    if (FAILED(g_d3ddevice->SetVertexDeclaration(vdecl)))
118        Abort();
119#else
120    /* FIXME: Nothing to do? */
121#endif
122}
123
124void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count)
125{
126    if (count <= 0)
127        return;
128
129#if defined _XBOX || defined USE_D3D9
130    g_d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
131    g_d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
132    g_d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
133    if (FAILED(g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)))
134        Abort();
135    switch (type)
136    {
137    case MeshPrimitive::Triangles:
138        if (FAILED(g_d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST,
139                                              skip, count)))
140            Abort();
141        break;
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;
152    case MeshPrimitive::Points:
153        if (FAILED(g_d3ddevice->DrawPrimitive(D3DPT_POINTLIST,
154                                              skip, count)))
155            Abort();
156        break;
157    }
158#else
159    /* FIXME: this has nothing to do here! */
160    glFrontFace(GL_CCW);
161    glEnable(GL_CULL_FACE);
162    glEnable(GL_BLEND);
163    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
164
165    switch (type)
166    {
167    case MeshPrimitive::Triangles:
168        glDrawArrays(GL_TRIANGLES, skip, count);
169        break;
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;
176    case MeshPrimitive::Points:
177        glDrawArrays(GL_POINTS, skip, count);
178        break;
179    }
180#endif
181}
182
183void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase,
184                                            int vskip, int vcount,
185                                            int skip, int count)
186{
187    if (count <= 0)
188        return;
189
190#if defined _XBOX || defined USE_D3D9
191    g_d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
192    g_d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
193    g_d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
194    if (FAILED(g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)))
195        Abort();
196    switch (type)
197    {
198    case MeshPrimitive::Triangles:
199        count = count / 3;
200        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
201                                           vbase, vskip, vcount, skip, count)))
202            Abort();
203        break;
204    case MeshPrimitive::TriangleStrips:
205        count = count - 2;
206        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,
207                                           vbase, vskip, vcount, skip, count)))
208            Abort();
209        break;
210    case MeshPrimitive::TriangleFans:
211        count = count - 2;
212        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN,
213                                           vbase, vskip, vcount, skip, count)))
214            Abort();
215        break;
216    case MeshPrimitive::Points:
217        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_POINTLIST,
218                                           vbase, vskip, vcount, skip, count)))
219            Abort();
220        break;
221    }
222#else
223    /* FIXME: this has nothing to do here! */
224    glFrontFace(GL_CCW);
225    glEnable(GL_CULL_FACE);
226    glEnable(GL_BLEND);
227    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
228
229    switch (type)
230    {
231    case MeshPrimitive::Triangles:
232        /* FIXME: ignores most of the arguments! */
233        (void)vbase; (void)vskip; (void)vcount; (void)skip;
234        glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, 0);
235        break;
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;
246    case MeshPrimitive::Points:
247        /* FIXME: ignores most of the arguments! */
248        (void)vbase; (void)vskip; (void)vcount; (void)skip;
249        glDrawElements(GL_POINTS, count, GL_UNSIGNED_SHORT, 0);
250        break;
251    }
252#endif
253}
254
255void VertexDeclaration::Unbind()
256{
257#if defined _XBOX || defined USE_D3D9
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        }
266    /* "NULL is an invalid input to SetVertexDeclaration" (DX9 guide), so
267     * we just don't touch the current vertex declaration. */
268#elif !defined __CELLOS_LV2__
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    }
280    glBindBuffer(GL_ARRAY_BUFFER, 0);
281#else
282    /* Or even: */
283    glDisableClientState(GL_VERTEX_ARRAY);
284    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
285    glDisableClientState(GL_NORMAL_ARRAY);
286    glDisableClientState(GL_COLOR_ARRAY);
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{
303    if (!vb->m_data->m_size)
304        return;
305
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. */
310    uint32_t usage = (attr1.m_flags >> 16) & 0xffff;
311    uint32_t index = attr1.m_flags & 0xffff;
312
313    /* Find the stream number */
314    uint32_t usage_index = 0;
315    int stream = -1;
316    for (int i = 0; i < m_count; i++)
317        if (m_streams[i].usage == usage)
318            if (usage_index++ == index)
319            {
320                stream = m_streams[i].index;
321                break;
322            }
323
324    /* Compute this stream's stride */
325    int stride = 0;
326    for (int i = 0; i < m_count; i++)
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)
333    {
334        if (FAILED(g_d3ddevice->SetStreamSource(stream, vb->m_data->m_vbo, 0, stride)))
335            Abort();
336    }
337#else
338    glBindBuffer(GL_ARRAY_BUFFER, vb->m_data->m_vbo);
339    ShaderAttrib l[12] = { attr1, attr2, attr3, attr4, attr5, attr6,
340                           attr7, attr8, attr9, attr10, attr11, attr12 };
341    for (int n = 0; n < 12 && l[n].m_flags != (uint64_t)0 - 1; n++)
342    {
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
347#   if !defined __CELLOS_LV2__
348        glEnableVertexAttribArray((GLint)reg);
349#   else
350        switch (usage)
351        {
352        case VertexUsage::Position:
353            glEnableClientState(GL_VERTEX_ARRAY);
354            break;
355        case VertexUsage::TexCoord:
356            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
357            break;
358        case VertexUsage::Normal:
359            glEnableClientState(GL_NORMAL_ARRAY);
360            break;
361        case VertexUsage::Color:
362            glEnableClientState(GL_COLOR_ARRAY);
363            break;
364        }
365#   endif
366
367        /* We need to parse the whole vertex declaration to retrieve
368         * the information. It sucks. */
369
370        int attr_index = 0;
371        /* First, find the stream index */
372        for (uint32_t usage_index = 0; attr_index < m_count; attr_index++)
373            if (m_streams[attr_index].usage == usage)
374                if (usage_index++ == index)
375                    break;
376
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
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            {
389                /* Remember the register used for this stream */
390                m_streams[i].reg = reg;
391
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 */
398#   if !defined GL_DOUBLE
399#       define GL_DOUBLE 0
400#   endif
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;
424        if (type_index < 0 || type_index >= (int)(sizeof(tlut) / sizeof(*tlut)))
425            type_index = 0;
426
427
428#   if !defined __CELLOS_LV2__
429        if (tlut[type_index].type == GL_FLOAT
430             || tlut[type_index].type == GL_DOUBLE
431             || tlut[type_index].type == GL_BYTE
432             || tlut[type_index].type == GL_UNSIGNED_BYTE
433#       if defined USE_GLEW && !defined __APPLE__
434             /* If this is not available, don't use it */
435             || !glVertexAttribIPointer
436#       endif
437             || false)
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        }
447#       if defined GL_VERSION_3_0
448        else
449        {
450            glVertexAttribIPointer((GLint)reg, tlut[type_index].size,
451                                   tlut[type_index].type,
452                                   stride, (GLvoid const *)(uintptr_t)offset);
453        }
454#       endif
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;
462        case VertexUsage::TexCoord:
463            glTexCoordPointer(tlut[type_index].size, tlut[type_index].type,
464                              stride, (GLvoid const *)(uintptr_t)offset);
465            break;
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;
474        default:
475            Log::Error("vertex usage %d is not supported yet\n", usage);
476            break;
477        }
478#   endif
479    }
480#endif
481}
482
483void VertexDeclaration::Initialize()
484{
485#if defined _XBOX || defined USE_D3D9
486    static D3DVERTEXELEMENT9 const end_element[] = { D3DDECL_END() };
487    static D3DDECLTYPE const X = D3DDECLTYPE_UNUSED;
488    static D3DDECLTYPE const tlut[] =
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 */
496        X, X, X, D3DDECLTYPE_UBYTE4N, /* uint8_t */
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 */
500        X, X, X, X, /* uint32_t */
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,
513#if defined _XBOX
514        D3DDECLUSAGE_TEXCOORD, /* FIXME: nonexistent */
515#else
516        D3DDECLUSAGE_POSITIONT,
517#endif
518        D3DDECLUSAGE_COLOR,
519        D3DDECLUSAGE_FOG,
520        D3DDECLUSAGE_DEPTH,
521        D3DDECLUSAGE_SAMPLE,
522    };
523
524    D3DVERTEXELEMENT9 elements[12 + 1];
525    for (int n = 0; n < m_count; n++)
526    {
527        elements[n].Stream = m_streams[n].index;
528        elements[n].Offset = 0;
529        for (int i = 0; i < n; i++)
530            if (m_streams[i].index == m_streams[n].index)
531                elements[n].Offset += m_streams[i].size;
532
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];
536        else
537            elements[n].Type = D3DDECLTYPE_UNUSED;
538
539        elements[n].Method = D3DDECLMETHOD_DEFAULT;
540
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];
544        else
545            elements[n].Usage = D3DDECLUSAGE_POSITION;
546
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++;
552    }
553    elements[m_count] = end_element[0];
554
555#   if defined USE_D3D9
556    IDirect3DVertexDeclaration9 *vdecl;
557#   elif defined _XBOX
558    D3DVertexDeclaration *vdecl;
559#   endif
560
561    if (FAILED(g_d3ddevice->CreateVertexDeclaration(elements, &vdecl)))
562        Abort();
563
564    m_data = vdecl;
565#else
566
567#endif
568}
569
570void VertexDeclaration::AddStream(VertexStreamBase const &s)
571{
572    int index = m_count ? m_streams[m_count - 1].index + 1 : 0;
573
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;
580        m_streams[m_count].reg = -1;
581        m_count++;
582    }
583}
584
585//
586// The VertexBuffer class
587// ----------------------
588//
589
590VertexBuffer::VertexBuffer(size_t size)
591  : m_data(new VertexBufferData)
592{
593    m_data->m_size = size;
594    if (!size)
595        return;
596#if defined USE_D3D9 || defined _XBOX
597    if (FAILED(g_d3ddevice->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, NULL,
598                                               D3DPOOL_MANAGED, &m_data->m_vbo, NULL)))
599        Abort();
600#else
601    glGenBuffers(1, &m_data->m_vbo);
602    m_data->m_memory = new uint8_t[size];
603#endif
604}
605
606VertexBuffer::~VertexBuffer()
607{
608    if (m_data->m_size)
609    {
610#if defined USE_D3D9 || defined _XBOX
611        if (FAILED(m_data->m_vbo->Release()))
612            Abort();
613#else
614        glDeleteBuffers(1, &m_data->m_vbo);
615        delete[] m_data->m_memory;
616#endif
617    }
618    delete m_data;
619}
620
621void *VertexBuffer::Lock(size_t offset, size_t size)
622{
623    if (!m_data->m_size)
624        return NULL;
625#if defined USE_D3D9 || defined _XBOX
626    void *ret;
627    if (FAILED(m_data->m_vbo->Lock(offset, size, (void **)&ret, 0)))
628        Abort();
629    return ret;
630#else
631    /* FIXME: is there a way to use "size"? */
632    (void)size;
633    return m_data->m_memory + offset;
634#endif
635}
636
637void VertexBuffer::Unlock()
638{
639    if (!m_data->m_size)
640        return;
641#if defined USE_D3D9 || defined _XBOX
642    if (FAILED(m_data->m_vbo->Unlock()))
643        Abort();
644#else
645    glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
646    glBufferData(GL_ARRAY_BUFFER, m_data->m_size, m_data->m_memory,
647                 GL_STATIC_DRAW);
648    glBindBuffer(GL_ARRAY_BUFFER, 0);
649#endif
650}
651
652} /* namespace lol */
653
Note: See TracBrowser for help on using the repository browser.