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

Last change on this file since 2082 was 2082, checked in by sam, 8 years ago

gpu: remove some crap from vertexbuffer.cpp and allow for
empty vertex declarations even though many video card
drivers do not support them — and they should.

File size: 20.8 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-2012 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://sam.zoy.org/projects/COPYING.WTFPL 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        /* Now compute the stride and offset up to this stream index */
378        int stride = 0, offset = 0;
379        for (int i = 0; i < m_count; i++)
380            if (m_streams[i].index == m_streams[attr_index].index)
381            {
382                /* Remember the register used for this stream */
383                m_streams[i].reg = reg;
384
385                stride += m_streams[i].size;
386                if (i < attr_index)
387                    offset += m_streams[i].size;
388            }
389
390        /* Finally, we need to retrieve the type of the data */
391#   if !defined GL_DOUBLE
392#       define GL_DOUBLE 0
393#   endif
394        static struct { GLint size; GLenum type; } const tlut[] =
395        {
396            { 0, 0 },
397            { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* half */
398            { 1, GL_FLOAT }, { 2, GL_FLOAT }, { 3, GL_FLOAT },
399                { 4, GL_FLOAT }, /* float */
400            { 1, GL_DOUBLE }, { 2, GL_DOUBLE }, { 3, GL_DOUBLE },
401                { 4, GL_DOUBLE }, /* double */
402            { 1, GL_BYTE }, { 2, GL_BYTE }, { 3, GL_BYTE },
403                { 4, GL_BYTE }, /* int8_t */
404            { 1, GL_UNSIGNED_BYTE }, { 2, GL_UNSIGNED_BYTE },
405                { 3, GL_UNSIGNED_BYTE }, { 4, GL_UNSIGNED_BYTE }, /* uint8_t */
406            { 1, GL_SHORT }, { 2, GL_SHORT }, { 3, GL_SHORT },
407                { 4, GL_SHORT }, /* int16_t */
408            { 1, GL_UNSIGNED_SHORT }, { 2, GL_UNSIGNED_SHORT }, { 3,
409                GL_UNSIGNED_SHORT }, { 4, GL_UNSIGNED_SHORT }, /* uint16_t */
410            { 1, GL_INT }, { 2, GL_INT }, { 3, GL_INT },
411                { 4, GL_INT }, /* int32_t */
412            { 1, GL_UNSIGNED_INT }, { 2, GL_UNSIGNED_INT },
413                { 3, GL_UNSIGNED_INT }, { 4, GL_UNSIGNED_INT }, /* uint32_t */
414        };
415
416        int type_index = m_streams[attr_index].stream_type;
417        if (type_index < 0 || type_index >= (int)(sizeof(tlut) / sizeof(*tlut)))
418            type_index = 0;
419
420
421#   if !defined __CELLOS_LV2__
422        if (tlut[type_index].type == GL_FLOAT
423             || tlut[type_index].type == GL_DOUBLE
424             || tlut[type_index].type == GL_BYTE
425             || tlut[type_index].type == GL_UNSIGNED_BYTE
426#       if defined USE_GLEW && !defined __APPLE__
427             /* If this is not available, don't use it */
428             || !glVertexAttribIPointer
429#       endif
430             || false)
431        {
432            /* Normalize unsigned bytes by default, because it's usually
433             * some color information. */
434            GLboolean normalize = (tlut[type_index].type == GL_UNSIGNED_BYTE)
435                               || (tlut[type_index].type == GL_BYTE);
436            glVertexAttribPointer((GLint)reg, tlut[type_index].size,
437                                  tlut[type_index].type, normalize,
438                                  stride, (GLvoid const *)(uintptr_t)offset);
439        }
440#       if defined GL_VERSION_3_0
441        else
442        {
443            glVertexAttribIPointer((GLint)reg, tlut[type_index].size,
444                                   tlut[type_index].type,
445                                   stride, (GLvoid const *)(uintptr_t)offset);
446        }
447#       endif
448#   else
449        switch (usage)
450        {
451        case VertexUsage::Position:
452            glVertexPointer(tlut[type_index].size, tlut[type_index].type,
453                            stride, (GLvoid const *)(uintptr_t)offset);
454            break;
455        case VertexUsage::TexCoord:
456            glTexCoordPointer(tlut[type_index].size, tlut[type_index].type,
457                              stride, (GLvoid const *)(uintptr_t)offset);
458            break;
459        case VertexUsage::Normal:
460            glNormalPointer(tlut[type_index].type,
461                            stride, (GLvoid const *)(uintptr_t)offset);
462            break;
463        case VertexUsage::Color:
464            glColorPointer(tlut[type_index].size, tlut[type_index].type,
465                           stride, (GLvoid const *)(uintptr_t)offset);
466            break;
467        default:
468            Log::Error("vertex usage %d is not supported yet\n", usage);
469            break;
470        }
471#   endif
472    }
473#endif
474}
475
476void VertexDeclaration::Initialize()
477{
478#if defined _XBOX || defined USE_D3D9
479    static D3DVERTEXELEMENT9 const end_element[] = { D3DDECL_END() };
480    static D3DDECLTYPE const X = D3DDECLTYPE_UNUSED;
481    static D3DDECLTYPE const tlut[] =
482    {
483        D3DDECLTYPE_UNUSED,
484        X, D3DDECLTYPE_FLOAT16_2, X, D3DDECLTYPE_FLOAT16_4, /* half */
485        D3DDECLTYPE_FLOAT1, D3DDECLTYPE_FLOAT2, D3DDECLTYPE_FLOAT3,
486            D3DDECLTYPE_FLOAT4, /* float */
487        X, X, X, X, /* double */
488        X, X, X, X, /* int8_t */
489        X, X, X, D3DDECLTYPE_UBYTE4N, /* uint8_t */
490        X, D3DDECLTYPE_SHORT2N, X, D3DDECLTYPE_SHORT4N, /* int16_t */
491        X, D3DDECLTYPE_USHORT2N, X, D3DDECLTYPE_USHORT4N, /* uint16_t */
492        X, X, X, X, /* int32_t */
493        X, X, X, X, /* uint32_t */
494    };
495    static D3DDECLUSAGE const ulut[] =
496    {
497        D3DDECLUSAGE_POSITION,
498        D3DDECLUSAGE_BLENDWEIGHT,
499        D3DDECLUSAGE_BLENDINDICES,
500        D3DDECLUSAGE_NORMAL,
501        D3DDECLUSAGE_PSIZE,
502        D3DDECLUSAGE_TEXCOORD,
503        D3DDECLUSAGE_TANGENT,
504        D3DDECLUSAGE_BINORMAL,
505        D3DDECLUSAGE_TESSFACTOR,
506#if defined _XBOX
507        D3DDECLUSAGE_TEXCOORD, /* FIXME: nonexistent */
508#else
509        D3DDECLUSAGE_POSITIONT,
510#endif
511        D3DDECLUSAGE_COLOR,
512        D3DDECLUSAGE_FOG,
513        D3DDECLUSAGE_DEPTH,
514        D3DDECLUSAGE_SAMPLE,
515    };
516
517    D3DVERTEXELEMENT9 elements[12 + 1];
518    for (int n = 0; n < m_count; n++)
519    {
520        elements[n].Stream = m_streams[n].index;
521        elements[n].Offset = 0;
522        for (int i = 0; i < n; i++)
523            if (m_streams[i].index == m_streams[n].index)
524                elements[n].Offset += m_streams[i].size;
525
526        if (m_streams[n].stream_type >= 0
527             && m_streams[n].stream_type < sizeof(tlut) / sizeof(*tlut))
528            elements[n].Type = tlut[m_streams[n].stream_type];
529        else
530            elements[n].Type = D3DDECLTYPE_UNUSED;
531
532        elements[n].Method = D3DDECLMETHOD_DEFAULT;
533
534        if (m_streams[n].usage >= 0
535             && m_streams[n].usage < sizeof(ulut) / sizeof(*ulut))
536            elements[n].Usage = ulut[m_streams[n].usage];
537        else
538            elements[n].Usage = D3DDECLUSAGE_POSITION;
539
540        elements[n].UsageIndex = 0;
541        for (int i = 0; i < n; i++)
542            if (elements[i].Stream == elements[n].Stream
543                 && elements[i].Usage == elements[n].Usage)
544                elements[n].UsageIndex++;
545    }
546    elements[m_count] = end_element[0];
547
548#   if defined USE_D3D9
549    IDirect3DVertexDeclaration9 *vdecl;
550#   elif defined _XBOX
551    D3DVertexDeclaration *vdecl;
552#   endif
553
554    if (FAILED(g_d3ddevice->CreateVertexDeclaration(elements, &vdecl)))
555        Abort();
556
557    m_data = vdecl;
558#else
559
560#endif
561}
562
563void VertexDeclaration::AddStream(VertexStreamBase const &s)
564{
565    int index = m_count ? m_streams[m_count - 1].index + 1 : 0;
566
567    for (int i = 0; s.m_streams[i].size; i++)
568    {
569        m_streams[m_count].stream_type = s.m_streams[i].stream_type;
570        m_streams[m_count].usage = s.m_streams[i].usage;
571        m_streams[m_count].size = s.m_streams[i].size;
572        m_streams[m_count].index = index;
573        m_streams[m_count].reg = -1;
574        m_count++;
575    }
576}
577
578//
579// The VertexBuffer class
580// ----------------------
581//
582
583VertexBuffer::VertexBuffer(size_t size)
584  : m_data(new VertexBufferData)
585{
586    m_data->m_size = size;
587    if (!size)
588        return;
589#if defined USE_D3D9 || defined _XBOX
590    if (FAILED(g_d3ddevice->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, NULL,
591                                               D3DPOOL_MANAGED, &m_data->m_vbo, NULL)))
592        Abort();
593#else
594    glGenBuffers(1, &m_data->m_vbo);
595    m_data->m_memory = new uint8_t[size];
596#endif
597}
598
599VertexBuffer::~VertexBuffer()
600{
601    if (m_data->m_size)
602    {
603#if defined USE_D3D9 || defined _XBOX
604        if (FAILED(m_data->m_vbo->Release()))
605            Abort();
606#else
607        glDeleteBuffers(1, &m_data->m_vbo);
608        delete[] m_data->m_memory;
609#endif
610    }
611    delete m_data;
612}
613
614void *VertexBuffer::Lock(size_t offset, size_t size)
615{
616    if (!m_data->m_size)
617        return NULL;
618#if defined USE_D3D9 || defined _XBOX
619    void *ret;
620    if (FAILED(m_data->m_vbo->Lock(offset, size, (void **)&ret, 0)))
621        Abort();
622    return ret;
623#else
624    /* FIXME: is there a way to use "size"? */
625    (void)size;
626    return m_data->m_memory + offset;
627#endif
628}
629
630void VertexBuffer::Unlock()
631{
632    if (!m_data->m_size)
633        return;
634#if defined USE_D3D9 || defined _XBOX
635    if (FAILED(m_data->m_vbo->Unlock()))
636        Abort();
637#else
638    glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
639    glBufferData(GL_ARRAY_BUFFER, m_data->m_size, m_data->m_memory,
640                 GL_STATIC_DRAW);
641    glBindBuffer(GL_ARRAY_BUFFER, 0);
642#endif
643}
644
645} /* namespace lol */
646
Note: See TracBrowser for help on using the repository browser.