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

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

render : Added DebugRenderMode & corresponding shaders. naive (VERY) implementation in MeshViewer.

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