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

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

easymesh : vertices datas are now stored in a very user-friendly struct. Heavier on datas, though.
vertexbuffer : added TexCoordExt, which is the same as TexCoord but means "use vec4 for TexCoord"

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_BLEND);
162    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
163
164    switch (type)
165    {
166    case MeshPrimitive::Triangles:
167        glDrawArrays(GL_TRIANGLES, skip, count);
168        break;
169    case MeshPrimitive::TriangleStrips:
170        glDrawArrays(GL_TRIANGLE_STRIP, skip, count);
171        break;
172    case MeshPrimitive::TriangleFans:
173        glDrawArrays(GL_TRIANGLE_FAN, skip, count);
174        break;
175    case MeshPrimitive::Points:
176        glDrawArrays(GL_POINTS, skip, count);
177        break;
178    }
179#endif
180}
181
182void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase,
183                                            int vskip, int vcount,
184                                            int skip, int count)
185{
186    if (count <= 0)
187        return;
188
189#if defined _XBOX || defined USE_D3D9
190    g_d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
191    g_d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
192    g_d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
193    if (FAILED(g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)))
194        Abort();
195    switch (type)
196    {
197    case MeshPrimitive::Triangles:
198        count = count / 3;
199        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
200                                           vbase, vskip, vcount, skip, count)))
201            Abort();
202        break;
203    case MeshPrimitive::TriangleStrips:
204        count = count - 2;
205        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,
206                                           vbase, vskip, vcount, skip, count)))
207            Abort();
208        break;
209    case MeshPrimitive::TriangleFans:
210        count = count - 2;
211        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN,
212                                           vbase, vskip, vcount, skip, count)))
213            Abort();
214        break;
215    case MeshPrimitive::Points:
216        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_POINTLIST,
217                                           vbase, vskip, vcount, skip, count)))
218            Abort();
219        break;
220    }
221#else
222    /* FIXME: this has nothing to do here! */
223    glFrontFace(GL_CCW);
224    glEnable(GL_BLEND);
225    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
226
227    switch (type)
228    {
229    case MeshPrimitive::Triangles:
230        /* FIXME: ignores most of the arguments! */
231        (void)vbase; (void)vskip; (void)vcount; (void)skip;
232        glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, 0);
233        break;
234    case MeshPrimitive::TriangleStrips:
235        /* FIXME: ignores most of the arguments! */
236        (void)vbase; (void)vskip; (void)vcount; (void)skip;
237        glDrawElements(GL_TRIANGLE_STRIP, count, GL_UNSIGNED_SHORT, 0);
238        break;
239    case MeshPrimitive::TriangleFans:
240        /* FIXME: ignores most of the arguments! */
241        (void)vbase; (void)vskip; (void)vcount; (void)skip;
242        glDrawElements(GL_TRIANGLE_FAN, count, GL_UNSIGNED_SHORT, 0);
243        break;
244    case MeshPrimitive::Points:
245        /* FIXME: ignores most of the arguments! */
246        (void)vbase; (void)vskip; (void)vcount; (void)skip;
247        glDrawElements(GL_POINTS, count, GL_UNSIGNED_SHORT, 0);
248        break;
249    }
250#endif
251}
252
253void VertexDeclaration::Unbind()
254{
255#if defined _XBOX || defined USE_D3D9
256    int stream = -1;
257    for (int i = 0; i < m_count; i++)
258        if (m_streams[i].index != stream)
259        {
260            stream = m_streams[i].index;
261            if (FAILED(g_d3ddevice->SetStreamSource(stream, 0, 0, 0)))
262                Abort();
263        }
264    /* "NULL is an invalid input to SetVertexDeclaration" (DX9 guide), so
265     * we just don't touch the current vertex declaration. */
266#elif !defined __CELLOS_LV2__
267    for (int i = 0; i < m_count; i++)
268    {
269        if (m_streams[i].reg >= 0)
270        {
271            for (int j = i + 1; j < m_count; j++)
272                if (m_streams[j].reg == m_streams[i].reg)
273                    m_streams[j].reg = -1;
274
275            glDisableVertexAttribArray(m_streams[i].reg);
276        }
277    }
278    glBindBuffer(GL_ARRAY_BUFFER, 0);
279#else
280    /* Or even: */
281    glDisableClientState(GL_VERTEX_ARRAY);
282    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
283    glDisableClientState(GL_NORMAL_ARRAY);
284    glDisableClientState(GL_COLOR_ARRAY);
285#endif
286}
287
288void VertexDeclaration::SetStream(VertexBuffer *vb, ShaderAttrib attr1,
289                                                    ShaderAttrib attr2,
290                                                    ShaderAttrib attr3,
291                                                    ShaderAttrib attr4,
292                                                    ShaderAttrib attr5,
293                                                    ShaderAttrib attr6,
294                                                    ShaderAttrib attr7,
295                                                    ShaderAttrib attr8,
296                                                    ShaderAttrib attr9,
297                                                    ShaderAttrib attr10,
298                                                    ShaderAttrib attr11,
299                                                    ShaderAttrib attr12)
300{
301    if (!vb->m_data->m_size)
302        return;
303
304#if defined _XBOX || defined USE_D3D9
305    /* Only the first item is required to know which stream this
306     * is about; the rest of the information is stored in the
307     * vertex declaration already. */
308    uint32_t usage = (attr1.m_flags >> 16) & 0xffff;
309    uint32_t index = attr1.m_flags & 0xffff;
310
311    /* Find the stream number */
312    uint32_t usage_index = 0;
313    int stream = -1;
314    for (int i = 0; i < m_count; i++)
315        if (m_streams[i].usage == usage)
316            if (usage_index++ == index)
317            {
318                stream = m_streams[i].index;
319                break;
320            }
321
322    /* Compute this stream's stride */
323    int stride = 0;
324    for (int i = 0; i < m_count; i++)
325        if (stream == m_streams[i].index)
326            stride += m_streams[i].size;
327
328    /* Now we know the stream index and the element stride */
329    /* FIXME: precompute most of the crap above! */
330    if (stream >= 0)
331    {
332        if (FAILED(g_d3ddevice->SetStreamSource(stream, vb->m_data->m_vbo, 0, stride)))
333            Abort();
334    }
335#else
336    glBindBuffer(GL_ARRAY_BUFFER, vb->m_data->m_vbo);
337    ShaderAttrib l[12] = { attr1, attr2, attr3, attr4, attr5, attr6,
338                           attr7, attr8, attr9, attr10, attr11, attr12 };
339    for (int n = 0; n < 12 && l[n].m_flags != (uint64_t)0 - 1; n++)
340    {
341        uint32_t reg = l[n].m_flags >> 32;
342        uint32_t usage = (l[n].m_flags >> 16) & 0xffff;
343        uint32_t index = l[n].m_flags & 0xffff;
344
345#   if !defined __CELLOS_LV2__
346        glEnableVertexAttribArray((GLint)reg);
347#   else
348        switch (usage)
349        {
350        case VertexUsage::Position:
351            glEnableClientState(GL_VERTEX_ARRAY);
352            break;
353        case VertexUsage::TexCoord:
354        case VertexUsage::TexCoordExt:
355            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
356            break;
357        case VertexUsage::Normal:
358            glEnableClientState(GL_NORMAL_ARRAY);
359            break;
360        case VertexUsage::Color:
361            glEnableClientState(GL_COLOR_ARRAY);
362            break;
363        }
364#   endif
365
366        /* We need to parse the whole vertex declaration to retrieve
367         * the information. It sucks. */
368
369        int attr_index = 0;
370        /* First, find the stream index */
371        for (uint32_t usage_index = 0; attr_index < m_count; attr_index++)
372            if (m_streams[attr_index].usage == usage)
373                if (usage_index++ == index)
374                    break;
375
376        if (attr_index == m_count)
377        {
378            Log::Error("stream #%d with usage %x not found in declaration\n",
379                       index, usage);
380            attr_index = 0;
381        }
382
383        /* Now compute the stride and offset up to this stream index */
384        int stride = 0, offset = 0;
385        for (int i = 0; i < m_count; i++)
386            if (m_streams[i].index == m_streams[attr_index].index)
387            {
388                /* Remember the register used for this stream */
389                m_streams[i].reg = reg;
390
391                stride += m_streams[i].size;
392                if (i < attr_index)
393                    offset += m_streams[i].size;
394            }
395
396        /* Finally, we need to retrieve the type of the data */
397#   if !defined GL_DOUBLE
398#       define GL_DOUBLE 0
399#   endif
400        static struct { GLint size; GLenum type; } const tlut[] =
401        {
402            { 0, 0 },
403            { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* half */
404            { 1, GL_FLOAT }, { 2, GL_FLOAT }, { 3, GL_FLOAT },
405                { 4, GL_FLOAT }, /* float */
406            { 1, GL_DOUBLE }, { 2, GL_DOUBLE }, { 3, GL_DOUBLE },
407                { 4, GL_DOUBLE }, /* double */
408            { 1, GL_BYTE }, { 2, GL_BYTE }, { 3, GL_BYTE },
409                { 4, GL_BYTE }, /* int8_t */
410            { 1, GL_UNSIGNED_BYTE }, { 2, GL_UNSIGNED_BYTE },
411                { 3, GL_UNSIGNED_BYTE }, { 4, GL_UNSIGNED_BYTE }, /* uint8_t */
412            { 1, GL_SHORT }, { 2, GL_SHORT }, { 3, GL_SHORT },
413                { 4, GL_SHORT }, /* int16_t */
414            { 1, GL_UNSIGNED_SHORT }, { 2, GL_UNSIGNED_SHORT }, { 3,
415                GL_UNSIGNED_SHORT }, { 4, GL_UNSIGNED_SHORT }, /* uint16_t */
416            { 1, GL_INT }, { 2, GL_INT }, { 3, GL_INT },
417                { 4, GL_INT }, /* int32_t */
418            { 1, GL_UNSIGNED_INT }, { 2, GL_UNSIGNED_INT },
419                { 3, GL_UNSIGNED_INT }, { 4, GL_UNSIGNED_INT }, /* uint32_t */
420        };
421
422        int type_index = m_streams[attr_index].stream_type;
423        if (type_index < 0 || type_index >= (int)(sizeof(tlut) / sizeof(*tlut)))
424            type_index = 0;
425
426
427#   if !defined __CELLOS_LV2__
428        if (tlut[type_index].type == GL_FLOAT
429             || tlut[type_index].type == GL_DOUBLE
430             || tlut[type_index].type == GL_BYTE
431             || tlut[type_index].type == GL_UNSIGNED_BYTE
432#       if defined USE_GLEW && !defined __APPLE__
433             /* If this is not available, don't use it */
434             || !glVertexAttribIPointer
435#       endif
436             || false)
437        {
438            /* Normalize unsigned bytes by default, because it's usually
439             * some color information. */
440            GLboolean normalize = (tlut[type_index].type == GL_UNSIGNED_BYTE)
441                               || (tlut[type_index].type == GL_BYTE);
442            glVertexAttribPointer((GLint)reg, tlut[type_index].size,
443                                  tlut[type_index].type, normalize,
444                                  stride, (GLvoid const *)(uintptr_t)offset);
445        }
446#       if defined GL_VERSION_3_0
447        else
448        {
449            glVertexAttribIPointer((GLint)reg, tlut[type_index].size,
450                                   tlut[type_index].type,
451                                   stride, (GLvoid const *)(uintptr_t)offset);
452        }
453#       endif
454#   else
455        switch (usage)
456        {
457        case VertexUsage::Position:
458            glVertexPointer(tlut[type_index].size, tlut[type_index].type,
459                            stride, (GLvoid const *)(uintptr_t)offset);
460            break;
461        case VertexUsage::TexCoord:
462        case VertexUsage::TexCoordExt:
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.