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

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

base: a few minor style tweaks.

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