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
RevLine 
[1224]1//
2// Lol Engine
3//
[2216]4// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
[1224]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
[2183]8//   http://www.wtfpl.net/ for more details.
[1224]9//
10
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include "core.h"
16#include "lolgl.h"
17
[1226]18#if defined _WIN32 && defined USE_D3D9
19#   define FAR
20#   define NEAR
21#   include <d3d9.h>
22#endif
23
[1224]24using namespace std;
25
[1226]26#if defined USE_D3D9
27extern IDirect3DDevice9 *g_d3ddevice;
28#elif defined _XBOX
29extern D3DDevice *g_d3ddevice;
30#endif
31
[1224]32namespace lol
33{
34
[1227]35//
36// The VertexBufferData class
37// --------------------------
38//
39
40class VertexBufferData
41{
42    friend class VertexBuffer;
43    friend class VertexDeclaration;
44
[1443]45    size_t m_size;
46
[1227]47#if defined USE_D3D9
48    IDirect3DVertexBuffer9 *m_vbo;
49#elif defined _XBOX
50    D3DVertexBuffer *m_vbo;
[1401]51#else
[1227]52    GLuint m_vbo;
53    uint8_t *m_memory;
54#endif
55};
56
57//
58// The VertexDeclaration class
59// ---------------------------
60//
61
[1226]62VertexStreamBase const VertexStreamBase::Empty;
63
[1227]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
[1236]101    if (FAILED(vdecl->Release()))
102        Abort();
[1227]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
[1236]117    if (FAILED(g_d3ddevice->SetVertexDeclaration(vdecl)))
118        Abort();
[1227]119#else
[1228]120    /* FIXME: Nothing to do? */
121#endif
122}
[1227]123
[1231]124void VertexDeclaration::DrawElements(MeshPrimitive type, int skip, int count)
125{
[1443]126    if (count <= 0)
127        return;
128
[1231]129#if defined _XBOX || defined USE_D3D9
[1303]130    g_d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
131    g_d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
132    g_d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
[1236]133    if (FAILED(g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)))
134        Abort();
[1231]135    switch (type)
136    {
137    case MeshPrimitive::Triangles:
[1963]138        if (FAILED(g_d3ddevice->DrawPrimitive(D3DPT_TRIANGLELIST,
139                                              skip, count)))
[1236]140            Abort();
[1231]141        break;
[1963]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;
[1466]152    case MeshPrimitive::Points:
[1963]153        if (FAILED(g_d3ddevice->DrawPrimitive(D3DPT_POINTLIST,
154                                              skip, count)))
[1466]155            Abort();
156        break;
[1231]157    }
158#else
[2082]159    /* FIXME: this has nothing to do here! */
[1337]160    glFrontFace(GL_CCW);
[1303]161    glEnable(GL_BLEND);
162    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
163
[1231]164    switch (type)
165    {
166    case MeshPrimitive::Triangles:
[1963]167        glDrawArrays(GL_TRIANGLES, skip, count);
[1231]168        break;
[1963]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;
[1466]175    case MeshPrimitive::Points:
176        glDrawArrays(GL_POINTS, skip, count);
177        break;
[1231]178    }
179#endif
180}
181
[1247]182void VertexDeclaration::DrawIndexedElements(MeshPrimitive type, int vbase,
183                                            int vskip, int vcount,
184                                            int skip, int count)
185{
[1443]186    if (count <= 0)
187        return;
188
[1247]189#if defined _XBOX || defined USE_D3D9
[1303]190    g_d3ddevice->SetRenderState(D3DRS_ALPHABLENDENABLE, 1);
191    g_d3ddevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
192    g_d3ddevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
[2030]193    if (FAILED(g_d3ddevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW)))
194        Abort();
[1247]195    switch (type)
196    {
197    case MeshPrimitive::Triangles:
[2030]198        count = count / 3;
[1963]199        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,
200                                           vbase, vskip, vcount, skip, count)))
[1247]201            Abort();
202        break;
[1963]203    case MeshPrimitive::TriangleStrips:
[2030]204        count = count - 2;
[1963]205        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLESTRIP,
206                                           vbase, vskip, vcount, skip, count)))
207            Abort();
208        break;
209    case MeshPrimitive::TriangleFans:
[2030]210        count = count - 2;
[1963]211        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_TRIANGLEFAN,
212                                           vbase, vskip, vcount, skip, count)))
213            Abort();
214        break;
[1466]215    case MeshPrimitive::Points:
[1963]216        if (FAILED(g_d3ddevice->DrawIndexedPrimitive(D3DPT_POINTLIST,
217                                           vbase, vskip, vcount, skip, count)))
[1466]218            Abort();
219        break;
[1247]220    }
221#else
[2082]222    /* FIXME: this has nothing to do here! */
[1603]223    glFrontFace(GL_CCW);
[1303]224    glEnable(GL_BLEND);
225    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
226
[1247]227    switch (type)
228    {
229    case MeshPrimitive::Triangles:
230        /* FIXME: ignores most of the arguments! */
[1881]231        (void)vbase; (void)vskip; (void)vcount; (void)skip;
[1963]232        glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_SHORT, 0);
[1247]233        break;
[1963]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;
[1466]244    case MeshPrimitive::Points:
245        /* FIXME: ignores most of the arguments! */
[1881]246        (void)vbase; (void)vskip; (void)vcount; (void)skip;
[1466]247        glDrawElements(GL_POINTS, count, GL_UNSIGNED_SHORT, 0);
248        break;
[1247]249    }
250#endif
251}
252
[1228]253void VertexDeclaration::Unbind()
254{
255#if defined _XBOX || defined USE_D3D9
[1241]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        }
[1989]264    /* "NULL is an invalid input to SetVertexDeclaration" (DX9 guide), so
265     * we just don't touch the current vertex declaration. */
[1512]266#elif !defined __CELLOS_LV2__
[1688]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    }
[1480]278    glBindBuffer(GL_ARRAY_BUFFER, 0);
[1512]279#else
[1231]280    /* Or even: */
[1532]281    glDisableClientState(GL_VERTEX_ARRAY);
282    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
283    glDisableClientState(GL_NORMAL_ARRAY);
284    glDisableClientState(GL_COLOR_ARRAY);
[1227]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{
[1443]301    if (!vb->m_data->m_size)
302        return;
303
[1227]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. */
[1228]308    uint32_t usage = (attr1.m_flags >> 16) & 0xffff;
[1227]309    uint32_t index = attr1.m_flags & 0xffff;
[1228]310
311    /* Find the stream number */
[1881]312    uint32_t usage_index = 0;
313    int stream = -1;
[1227]314    for (int i = 0; i < m_count; i++)
315        if (m_streams[i].usage == usage)
316            if (usage_index++ == index)
[1228]317            {
[1227]318                stream = m_streams[i].index;
[1228]319                break;
320            }
321
322    /* Compute this stream's stride */
323    int stride = 0;
324    for (int i = 0; i < m_count; i++)
[1227]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)
[1236]331    {
332        if (FAILED(g_d3ddevice->SetStreamSource(stream, vb->m_data->m_vbo, 0, stride)))
333            Abort();
334    }
[1227]335#else
[1228]336    glBindBuffer(GL_ARRAY_BUFFER, vb->m_data->m_vbo);
[1227]337    ShaderAttrib l[12] = { attr1, attr2, attr3, attr4, attr5, attr6,
338                           attr7, attr8, attr9, attr10, attr11, attr12 };
[1228]339    for (int n = 0; n < 12 && l[n].m_flags != (uint64_t)0 - 1; n++)
[1227]340    {
[1228]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
[1292]345#   if !defined __CELLOS_LV2__
[1228]346        glEnableVertexAttribArray((GLint)reg);
[1292]347#   else
348        switch (usage)
349        {
350        case VertexUsage::Position:
351            glEnableClientState(GL_VERTEX_ARRAY);
352            break;
[1532]353        case VertexUsage::TexCoord:
354            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
355            break;
356        case VertexUsage::Normal:
357            glEnableClientState(GL_NORMAL_ARRAY);
358            break;
[1292]359        case VertexUsage::Color:
360            glEnableClientState(GL_COLOR_ARRAY);
361            break;
362        }
363#   endif
[1228]364
365        /* We need to parse the whole vertex declaration to retrieve
366         * the information. It sucks. */
367
[1881]368        int attr_index = 0;
[1228]369        /* First, find the stream index */
[1881]370        for (uint32_t usage_index = 0; attr_index < m_count; attr_index++)
[1228]371            if (m_streams[attr_index].usage == usage)
372                if (usage_index++ == index)
373                    break;
374
[2156]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
[1228]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            {
[1688]387                /* Remember the register used for this stream */
388                m_streams[i].reg = reg;
389
[1228]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 */
[1292]396#   if !defined GL_DOUBLE
397#       define GL_DOUBLE 0
398#   endif
[1228]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;
[1881]422        if (type_index < 0 || type_index >= (int)(sizeof(tlut) / sizeof(*tlut)))
[1228]423            type_index = 0;
424
[1266]425
[1292]426#   if !defined __CELLOS_LV2__
[1478]427        if (tlut[type_index].type == GL_FLOAT
428             || tlut[type_index].type == GL_DOUBLE
429             || tlut[type_index].type == GL_BYTE
[1864]430             || tlut[type_index].type == GL_UNSIGNED_BYTE
[1926]431#       if defined USE_GLEW && !defined __APPLE__
[1864]432             /* If this is not available, don't use it */
433             || !glVertexAttribIPointer
434#       endif
435             || false)
[1475]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        }
[1517]445#       if defined GL_VERSION_3_0
[1475]446        else
447        {
448            glVertexAttribIPointer((GLint)reg, tlut[type_index].size,
449                                   tlut[type_index].type,
450                                   stride, (GLvoid const *)(uintptr_t)offset);
451        }
[1517]452#       endif
[1292]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;
[1961]460        case VertexUsage::TexCoord:
461            glTexCoordPointer(tlut[type_index].size, tlut[type_index].type,
462                              stride, (GLvoid const *)(uintptr_t)offset);
463            break;
[1292]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;
[1864]472        default:
[1958]473            Log::Error("vertex usage %d is not supported yet\n", usage);
[1864]474            break;
[1292]475        }
476#   endif
[1228]477    }
[1227]478#endif
479}
480
[1226]481void VertexDeclaration::Initialize()
[1225]482{
[1226]483#if defined _XBOX || defined USE_D3D9
484    static D3DVERTEXELEMENT9 const end_element[] = { D3DDECL_END() };
[1227]485    static D3DDECLTYPE const X = D3DDECLTYPE_UNUSED;
486    static D3DDECLTYPE const tlut[] =
[1226]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 */
[1253]494        X, X, X, D3DDECLTYPE_UBYTE4N, /* uint8_t */
[1226]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 */
[1251]498        X, X, X, X, /* uint32_t */
[1226]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,
[1241]511#if defined _XBOX
512        D3DDECLUSAGE_TEXCOORD, /* FIXME: nonexistent */
513#else
[1226]514        D3DDECLUSAGE_POSITIONT,
[1241]515#endif
[1226]516        D3DDECLUSAGE_COLOR,
517        D3DDECLUSAGE_FOG,
518        D3DDECLUSAGE_DEPTH,
519        D3DDECLUSAGE_SAMPLE,
520    };
521
522    D3DVERTEXELEMENT9 elements[12 + 1];
[1227]523    for (int n = 0; n < m_count; n++)
[1226]524    {
[1227]525        elements[n].Stream = m_streams[n].index;
526        elements[n].Offset = 0;
527        for (int i = 0; i < n; i++)
[1234]528            if (m_streams[i].index == m_streams[n].index)
529                elements[n].Offset += m_streams[i].size;
[1226]530
[1227]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];
[1226]534        else
[1227]535            elements[n].Type = D3DDECLTYPE_UNUSED;
[1226]536
[1227]537        elements[n].Method = D3DDECLMETHOD_DEFAULT;
[1226]538
[1227]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];
[1226]542        else
[1227]543            elements[n].Usage = D3DDECLUSAGE_POSITION;
[1226]544
[1227]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++;
[1226]550    }
[1227]551    elements[m_count] = end_element[0];
[1226]552
553#   if defined USE_D3D9
554    IDirect3DVertexDeclaration9 *vdecl;
555#   elif defined _XBOX
556    D3DVertexDeclaration *vdecl;
557#   endif
558
[1236]559    if (FAILED(g_d3ddevice->CreateVertexDeclaration(elements, &vdecl)))
560        Abort();
[1226]561
562    m_data = vdecl;
563#else
564
565#endif
[1225]566}
567
[1227]568void VertexDeclaration::AddStream(VertexStreamBase const &s)
[1224]569{
[1227]570    int index = m_count ? m_streams[m_count - 1].index + 1 : 0;
[1226]571
[1227]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;
[1688]578        m_streams[m_count].reg = -1;
[1227]579        m_count++;
580    }
581}
[1226]582
[1227]583//
584// The VertexBuffer class
585// ----------------------
586//
587
588VertexBuffer::VertexBuffer(size_t size)
589  : m_data(new VertexBufferData)
590{
[1443]591    m_data->m_size = size;
592    if (!size)
593        return;
[1227]594#if defined USE_D3D9 || defined _XBOX
[1236]595    if (FAILED(g_d3ddevice->CreateVertexBuffer(size, D3DUSAGE_WRITEONLY, NULL,
596                                               D3DPOOL_MANAGED, &m_data->m_vbo, NULL)))
597        Abort();
[1532]598#else
[1227]599    glGenBuffers(1, &m_data->m_vbo);
600    m_data->m_memory = new uint8_t[size];
[1225]601#endif
[1224]602}
603
[1227]604VertexBuffer::~VertexBuffer()
[1226]605{
[1443]606    if (m_data->m_size)
607    {
[1227]608#if defined USE_D3D9 || defined _XBOX
[1443]609        if (FAILED(m_data->m_vbo->Release()))
610            Abort();
[1532]611#else
[1443]612        glDeleteBuffers(1, &m_data->m_vbo);
613        delete[] m_data->m_memory;
[1226]614#endif
[1443]615    }
[1324]616    delete m_data;
[1226]617}
618
[1227]619void *VertexBuffer::Lock(size_t offset, size_t size)
[1226]620{
[1443]621    if (!m_data->m_size)
622        return NULL;
[1227]623#if defined USE_D3D9 || defined _XBOX
624    void *ret;
625    if (FAILED(m_data->m_vbo->Lock(offset, size, (void **)&ret, 0)))
[1236]626        Abort();
[1227]627    return ret;
[1532]628#else
[1881]629    /* FIXME: is there a way to use "size"? */
630    (void)size;
[1227]631    return m_data->m_memory + offset;
632#endif
[1226]633}
634
[1227]635void VertexBuffer::Unlock()
[1226]636{
[1443]637    if (!m_data->m_size)
638        return;
[1227]639#if defined USE_D3D9 || defined _XBOX
[1236]640    if (FAILED(m_data->m_vbo->Unlock()))
641        Abort();
[1532]642#else
[1228]643    glBindBuffer(GL_ARRAY_BUFFER, m_data->m_vbo);
[1227]644    glBufferData(GL_ARRAY_BUFFER, m_data->m_size, m_data->m_memory,
645                 GL_STATIC_DRAW);
[1466]646    glBindBuffer(GL_ARRAY_BUFFER, 0);
[1227]647#endif
[1226]648}
649
[1224]650} /* namespace lol */
651
Note: See TracBrowser for help on using the repository browser.