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

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

gpu: add support for triangle strips and fans, and change the DrawElement
calls so that they take a number of vertices or indexes, not elements.

File size: 21.2 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    glFrontFace(GL_CCW);
160    glEnable(GL_CULL_FACE);
161#   if defined HAVE_GL_2X && !defined __APPLE__
162    /* FIXME: this has nothing to do here! */
163    glEnable(GL_ALPHA_TEST);
164    glAlphaFunc(GL_GEQUAL, 0.01f);
165#   endif
166    glEnable(GL_BLEND);
167    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
168
169    switch (type)
170    {
171    case MeshPrimitive::Triangles:
172        glDrawArrays(GL_TRIANGLES, skip, count);
173        break;
174    case MeshPrimitive::TriangleStrips:
175        glDrawArrays(GL_TRIANGLE_STRIP, skip, count);
176        break;
177    case MeshPrimitive::TriangleFans:
178        glDrawArrays(GL_TRIANGLE_FAN, skip, count);
179        break;
180    case MeshPrimitive::Points:
181        glDrawArrays(GL_POINTS, skip, count);
182        break;
183    }
184#   if defined HAVE_GL_2X && !defined __APPLE__
185    /* FIXME: this has nothing to do here! */
186    glDisable(GL_ALPHA_TEST);
187#   endif
188#endif
189}
190
191void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase,
192                                            int vskip, int vcount,
193                                            int skip, int count)
194{
195    if (count <= 0)
196        return;
197
198#if defined _XBOX || defined USE_D3D9
199    g_d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
200    g_d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
201    g_d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
202    g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
203    switch (type)
204    {
205    case MeshPrimitive::Triangles:
206        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
207                                           vbase, vskip, vcount, skip, count)))
208            Abort();
209        break;
210    case MeshPrimitive::TriangleStrips:
211        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,
212                                           vbase, vskip, vcount, skip, count)))
213            Abort();
214        break;
215    case MeshPrimitive::TriangleFans:
216        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN,
217                                           vbase, vskip, vcount, skip, count)))
218            Abort();
219        break;
220    case MeshPrimitive::Points:
221        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_POINTLIST,
222                                           vbase, vskip, vcount, skip, count)))
223            Abort();
224        break;
225    }
226#else
227    glFrontFace(GL_CCW);
228    glEnable(GL_CULL_FACE);
229#   if defined HAVE_GL_2X && !defined __APPLE__
230    /* FIXME: this has nothing to do here! */
231    glEnable(GL_ALPHA_TEST);
232    glAlphaFunc(GL_GEQUAL, 0.01f);
233#   endif
234    glEnable(GL_BLEND);
235    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
236
237    switch (type)
238    {
239    case MeshPrimitive::Triangles:
240        /* FIXME: ignores most of the arguments! */
241        (void)vbase; (void)vskip; (void)vcount; (void)skip;
242        glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, 0);
243        break;
244    case MeshPrimitive::TriangleStrips:
245        /* FIXME: ignores most of the arguments! */
246        (void)vbase; (void)vskip; (void)vcount; (void)skip;
247        glDrawElements(GL_TRIANGLE_STRIP, count, GL_UNSIGNED_SHORT, 0);
248        break;
249    case MeshPrimitive::TriangleFans:
250        /* FIXME: ignores most of the arguments! */
251        (void)vbase; (void)vskip; (void)vcount; (void)skip;
252        glDrawElements(GL_TRIANGLE_FAN, count, GL_UNSIGNED_SHORT, 0);
253        break;
254    case MeshPrimitive::Points:
255        /* FIXME: ignores most of the arguments! */
256        (void)vbase; (void)vskip; (void)vcount; (void)skip;
257        glDrawElements(GL_POINTS, count, GL_UNSIGNED_SHORT, 0);
258        break;
259    }
260#   if defined HAVE_GL_2X && !defined __APPLE__
261    /* FIXME: this has nothing to do here! */
262    glDisable(GL_ALPHA_TEST);
263#   endif
264#endif
265}
266
267void VertexDeclaration::Unbind()
268{
269#if defined _XBOX || defined USE_D3D9
270    int stream = -1;
271    for (int i = 0; i < m_count; i++)
272        if (m_streams[i].index != stream)
273        {
274            stream = m_streams[i].index;
275            if (FAILED(g_d3ddevice->SetStreamSource(stream, 0, 0, 0)))
276                Abort();
277        }
278    if (FAILED(g_d3ddevice->SetVertexDeclaration(NULL)))
279        Abort();
280#elif !defined __CELLOS_LV2__
281    for (int i = 0; i < m_count; i++)
282    {
283        if (m_streams[i].reg >= 0)
284        {
285            for (int j = i + 1; j < m_count; j++)
286                if (m_streams[j].reg == m_streams[i].reg)
287                    m_streams[j].reg = -1;
288
289            glDisableVertexAttribArray(m_streams[i].reg);
290        }
291    }
292    glBindBuffer(GL_ARRAY_BUFFER, 0);
293    /* FIXME: only useful for VAOs? */
294    //glBindBuffer(GL_ARRAY_BUFFER, 0);
295#else
296    /* Or even: */
297    glDisableClientState(GL_VERTEX_ARRAY);
298    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
299    glDisableClientState(GL_NORMAL_ARRAY);
300    glDisableClientState(GL_COLOR_ARRAY);
301#endif
302}
303
304void VertexDeclaration::SetStream(VertexBuffer *vb, ShaderAttrib attr1,
305                                                    ShaderAttrib attr2,
306                                                    ShaderAttrib attr3,
307                                                    ShaderAttrib attr4,
308                                                    ShaderAttrib attr5,
309                                                    ShaderAttrib attr6,
310                                                    ShaderAttrib attr7,
311                                                    ShaderAttrib attr8,
312                                                    ShaderAttrib attr9,
313                                                    ShaderAttrib attr10,
314                                                    ShaderAttrib attr11,
315                                                    ShaderAttrib attr12)
316{
317    if (!vb->m_data->m_size)
318        return;
319
320#if defined _XBOX || defined USE_D3D9
321    /* Only the first item is required to know which stream this
322     * is about; the rest of the information is stored in the
323     * vertex declaration already. */
324    uint32_t usage = (attr1.m_flags >> 16) & 0xffff;
325    uint32_t index = attr1.m_flags & 0xffff;
326
327    /* Find the stream number */
328    uint32_t usage_index = 0;
329    int stream = -1;
330    for (int i = 0; i < m_count; i++)
331        if (m_streams[i].usage == usage)
332            if (usage_index++ == index)
333            {
334                stream = m_streams[i].index;
335                break;
336            }
337
338    /* Compute this stream's stride */
339    int stride = 0;
340    for (int i = 0; i < m_count; i++)
341        if (stream == m_streams[i].index)
342            stride += m_streams[i].size;
343
344    /* Now we know the stream index and the element stride */
345    /* FIXME: precompute most of the crap above! */
346    if (stream >= 0)
347    {
348        if (FAILED(g_d3ddevice->SetStreamSource(stream, vb->m_data->m_vbo, 0, stride)))
349            Abort();
350    }
351#else
352    glBindBuffer(GL_ARRAY_BUFFER, vb->m_data->m_vbo);
353    ShaderAttrib l[12] = { attr1, attr2, attr3, attr4, attr5, attr6,
354                           attr7, attr8, attr9, attr10, attr11, attr12 };
355    for (int n = 0; n < 12 && l[n].m_flags != (uint64_t)0 - 1; n++)
356    {
357        uint32_t reg = l[n].m_flags >> 32;
358        uint32_t usage = (l[n].m_flags >> 16) & 0xffff;
359        uint32_t index = l[n].m_flags & 0xffff;
360
361#   if !defined __CELLOS_LV2__
362        glEnableVertexAttribArray((GLint)reg);
363#   else
364        switch (usage)
365        {
366        case VertexUsage::Position:
367            glEnableClientState(GL_VERTEX_ARRAY);
368            break;
369        case VertexUsage::TexCoord:
370            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
371            break;
372        case VertexUsage::Normal:
373            glEnableClientState(GL_NORMAL_ARRAY);
374            break;
375        case VertexUsage::Color:
376            glEnableClientState(GL_COLOR_ARRAY);
377            break;
378        }
379#   endif
380
381        /* We need to parse the whole vertex declaration to retrieve
382         * the information. It sucks. */
383
384        int attr_index = 0;
385        /* First, find the stream index */
386        for (uint32_t usage_index = 0; attr_index < m_count; attr_index++)
387            if (m_streams[attr_index].usage == usage)
388                if (usage_index++ == index)
389                    break;
390
391        /* Now compute the stride and offset up to this stream index */
392        int stride = 0, offset = 0;
393        for (int i = 0; i < m_count; i++)
394            if (m_streams[i].index == m_streams[attr_index].index)
395            {
396                /* Remember the register used for this stream */
397                m_streams[i].reg = reg;
398
399                stride += m_streams[i].size;
400                if (i < attr_index)
401                    offset += m_streams[i].size;
402            }
403
404        /* Finally, we need to retrieve the type of the data */
405#   if !defined GL_DOUBLE
406#       define GL_DOUBLE 0
407#   endif
408        static struct { GLint size; GLenum type; } const tlut[] =
409        {
410            { 0, 0 },
411            { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* half */
412            { 1, GL_FLOAT }, { 2, GL_FLOAT }, { 3, GL_FLOAT },
413                { 4, GL_FLOAT }, /* float */
414            { 1, GL_DOUBLE }, { 2, GL_DOUBLE }, { 3, GL_DOUBLE },
415                { 4, GL_DOUBLE }, /* double */
416            { 1, GL_BYTE }, { 2, GL_BYTE }, { 3, GL_BYTE },
417                { 4, GL_BYTE }, /* int8_t */
418            { 1, GL_UNSIGNED_BYTE }, { 2, GL_UNSIGNED_BYTE },
419                { 3, GL_UNSIGNED_BYTE }, { 4, GL_UNSIGNED_BYTE }, /* uint8_t */
420            { 1, GL_SHORT }, { 2, GL_SHORT }, { 3, GL_SHORT },
421                { 4, GL_SHORT }, /* int16_t */
422            { 1, GL_UNSIGNED_SHORT }, { 2, GL_UNSIGNED_SHORT }, { 3,
423                GL_UNSIGNED_SHORT }, { 4, GL_UNSIGNED_SHORT }, /* uint16_t */
424            { 1, GL_INT }, { 2, GL_INT }, { 3, GL_INT },
425                { 4, GL_INT }, /* int32_t */
426            { 1, GL_UNSIGNED_INT }, { 2, GL_UNSIGNED_INT },
427                { 3, GL_UNSIGNED_INT }, { 4, GL_UNSIGNED_INT }, /* uint32_t */
428        };
429
430        int type_index = m_streams[attr_index].stream_type;
431        if (type_index < 0 || type_index >= (int)(sizeof(tlut) / sizeof(*tlut)))
432            type_index = 0;
433
434
435#   if !defined __CELLOS_LV2__
436        if (tlut[type_index].type == GL_FLOAT
437             || tlut[type_index].type == GL_DOUBLE
438             || tlut[type_index].type == GL_BYTE
439             || tlut[type_index].type == GL_UNSIGNED_BYTE
440#       if defined USE_GLEW && !defined __APPLE__
441             /* If this is not available, don't use it */
442             || !glVertexAttribIPointer
443#       endif
444             || false)
445        {
446            /* Normalize unsigned bytes by default, because it's usually
447             * some color information. */
448            GLboolean normalize = (tlut[type_index].type == GL_UNSIGNED_BYTE)
449                               || (tlut[type_index].type == GL_BYTE);
450            glVertexAttribPointer((GLint)reg, tlut[type_index].size,
451                                  tlut[type_index].type, normalize,
452                                  stride, (GLvoid const *)(uintptr_t)offset);
453        }
454#       if defined GL_VERSION_3_0
455        else
456        {
457            glVertexAttribIPointer((GLint)reg, tlut[type_index].size,
458                                   tlut[type_index].type,
459                                   stride, (GLvoid const *)(uintptr_t)offset);
460        }
461#       endif
462#   else
463        switch (usage)
464        {
465        case VertexUsage::Position:
466            glVertexPointer(tlut[type_index].size, tlut[type_index].type,
467                            stride, (GLvoid const *)(uintptr_t)offset);
468            break;
469        case VertexUsage::TexCoord:
470            glTexCoordPointer(tlut[type_index].size, tlut[type_index].type,
471                              stride, (GLvoid const *)(uintptr_t)offset);
472            break;
473        case VertexUsage::Normal:
474            glNormalPointer(tlut[type_index].type,
475                            stride, (GLvoid const *)(uintptr_t)offset);
476            break;
477        case VertexUsage::Color:
478            glColorPointer(tlut[type_index].size, tlut[type_index].type,
479                           stride, (GLvoid const *)(uintptr_t)offset);
480            break;
481        default:
482            Log::Error("vertex usage %d is not supported yet\n", usage);
483            break;
484        }
485#   endif
486    }
487#endif
488}
489
490void VertexDeclaration::Initialize()
491{
492#if defined _XBOX || defined USE_D3D9
493    static D3DVERTEXELEMENT9 const end_element[] = { D3DDECL_END() };
494    static D3DDECLTYPE const X = D3DDECLTYPE_UNUSED;
495    static D3DDECLTYPE const tlut[] =
496    {
497        D3DDECLTYPE_UNUSED,
498        X, D3DDECLTYPE_FLOAT16_2, X, D3DDECLTYPE_FLOAT16_4, /* half */
499        D3DDECLTYPE_FLOAT1, D3DDECLTYPE_FLOAT2, D3DDECLTYPE_FLOAT3,
500            D3DDECLTYPE_FLOAT4, /* float */
501        X, X, X, X, /* double */
502        X, X, X, X, /* int8_t */
503        X, X, X, D3DDECLTYPE_UBYTE4N, /* uint8_t */
504        X, D3DDECLTYPE_SHORT2N, X, D3DDECLTYPE_SHORT4N, /* int16_t */
505        X, D3DDECLTYPE_USHORT2N, X, D3DDECLTYPE_USHORT4N, /* uint16_t */
506        X, X, X, X, /* int32_t */
507        X, X, X, X, /* uint32_t */
508    };
509    static D3DDECLUSAGE const ulut[] =
510    {
511        D3DDECLUSAGE_POSITION,
512        D3DDECLUSAGE_BLENDWEIGHT,
513        D3DDECLUSAGE_BLENDINDICES,
514        D3DDECLUSAGE_NORMAL,
515        D3DDECLUSAGE_PSIZE,
516        D3DDECLUSAGE_TEXCOORD,
517        D3DDECLUSAGE_TANGENT,
518        D3DDECLUSAGE_BINORMAL,
519        D3DDECLUSAGE_TESSFACTOR,
520#if defined _XBOX
521        D3DDECLUSAGE_TEXCOORD, /* FIXME: nonexistent */
522#else
523        D3DDECLUSAGE_POSITIONT,
524#endif
525        D3DDECLUSAGE_COLOR,
526        D3DDECLUSAGE_FOG,
527        D3DDECLUSAGE_DEPTH,
528        D3DDECLUSAGE_SAMPLE,
529    };
530
531    D3DVERTEXELEMENT9 elements[12 + 1];
532    for (int n = 0; n < m_count; n++)
533    {
534        elements[n].Stream = m_streams[n].index;
535        elements[n].Offset = 0;
536        for (int i = 0; i < n; i++)
537            if (m_streams[i].index == m_streams[n].index)
538                elements[n].Offset += m_streams[i].size;
539
540        if (m_streams[n].stream_type >= 0
541             && m_streams[n].stream_type < sizeof(tlut) / sizeof(*tlut))
542            elements[n].Type = tlut[m_streams[n].stream_type];
543        else
544            elements[n].Type = D3DDECLTYPE_UNUSED;
545
546        elements[n].Method = D3DDECLMETHOD_DEFAULT;
547
548        if (m_streams[n].usage >= 0
549             && m_streams[n].usage < sizeof(ulut) / sizeof(*ulut))
550            elements[n].Usage = ulut[m_streams[n].usage];
551        else
552            elements[n].Usage = D3DDECLUSAGE_POSITION;
553
554        elements[n].UsageIndex = 0;
555        for (int i = 0; i < n; i++)
556            if (elements[i].Stream == elements[n].Stream
557                 && elements[i].Usage == elements[n].Usage)
558                elements[n].UsageIndex++;
559    }
560    elements[m_count] = end_element[0];
561
562#   if defined USE_D3D9
563    IDirect3DVertexDeclaration9 *vdecl;
564#   elif defined _XBOX
565    D3DVertexDeclaration *vdecl;
566#   endif
567
568    if (FAILED(g_d3ddevice->CreateVertexDeclaration(elements, &vdecl)))
569        Abort();
570
571    m_data = vdecl;
572#else
573
574#endif
575}
576
577void VertexDeclaration::AddStream(VertexStreamBase const &s)
578{
579    int index = m_count ? m_streams[m_count - 1].index + 1 : 0;
580
581    for (int i = 0; s.m_streams[i].size; i++)
582    {
583        m_streams[m_count].stream_type = s.m_streams[i].stream_type;
584        m_streams[m_count].usage = s.m_streams[i].usage;
585        m_streams[m_count].size = s.m_streams[i].size;
586        m_streams[m_count].index = index;
587        m_streams[m_count].reg = -1;
588        m_count++;
589    }
590}
591
592//
593// The VertexBuffer class
594// ----------------------
595//
596
597VertexBuffer::VertexBuffer(size_t size)
598  : m_data(new VertexBufferData)
599{
600    m_data->m_size = size;
601    if (!size)
602        return;
603#if defined USE_D3D9 || defined _XBOX
604    if (FAILED(g_d3ddevice->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, NULL,
605                                               D3DPOOL_MANAGED, &m_data->m_vbo, NULL)))
606        Abort();
607#else
608    glGenBuffers(1, &m_data->m_vbo);
609    m_data->m_memory = new uint8_t[size];
610#endif
611}
612
613VertexBuffer::~VertexBuffer()
614{
615    if (m_data->m_size)
616    {
617#if defined USE_D3D9 || defined _XBOX
618        if (FAILED(m_data->m_vbo->Release()))
619            Abort();
620#else
621        glDeleteBuffers(1, &m_data->m_vbo);
622        delete[] m_data->m_memory;
623#endif
624    }
625    delete m_data;
626}
627
628void *VertexBuffer::Lock(size_t offset, size_t size)
629{
630    if (!m_data->m_size)
631        return NULL;
632#if defined USE_D3D9 || defined _XBOX
633    void *ret;
634    if (FAILED(m_data->m_vbo->Lock(offset, size, (void **)&ret, 0)))
635        Abort();
636    return ret;
637#else
638    /* FIXME: is there a way to use "size"? */
639    (void)size;
640    return m_data->m_memory + offset;
641#endif
642}
643
644void VertexBuffer::Unlock()
645{
646    if (!m_data->m_size)
647        return;
648#if defined USE_D3D9 || defined _XBOX
649    if (FAILED(m_data->m_vbo->Unlock()))
650        Abort();
651#else
652    glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
653    glBufferData(GL_ARRAY_BUFFER, m_data->m_size, m_data->m_memory,
654                 GL_STATIC_DRAW);
655    glBindBuffer(GL_ARRAY_BUFFER, 0);
656#endif
657}
658
659} /* namespace lol */
660
Note: See TracBrowser for help on using the repository browser.