summaryrefslogtreecommitdiff
path: root/Runtime/Graphics/VertexBuffer.cpp
blob: 29ecc57cc021ae6fcf57908eb2c7efec7439d740 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include "VertexBuffer.h"
#include "../Profiling/FrameStats.h"

VertexBuffer::VertexBuffer(int vbSize, int ibSize, VertexBufferType type)
{
	m_VB = GPU::ClaimBuffer(vbSize, GL_STATIC_DRAW);
	m_IB = GPU::ClaimBuffer(ibSize, GL_STATIC_DRAW);
}

VertexBuffer::~VertexBuffer()
{
	GPU::ReleaseBuffer(m_VB);
	GPU::ReleaseBuffer(m_IB);
}
// GetChunk
// <fill>
// FlushChunk 
// DrawChunk
void VertexBuffer::GetChunk(uint sizePerVert, uint sizePerIndex, int maxVerts, int maxIndices, EPrimitive primitive, void **out_vb, void **out_ib)
{
    m_SizePerVertex = sizePerVert;

    uint vbufferSize = sizePerVert * maxVerts;
    uint ibufferSize = sizePerIndex * maxIndices;

    GLenum usage = GL_STATIC_DRAW;
    m_VB->Restore(vbufferSize, usage);
    m_IB->Restore(ibufferSize, usage);

    const GLenum access = GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;

    *out_vb = m_VB->MapRange(0, vbufferSize, access);
    *out_ib = m_IB->MapRange(0, ibufferSize, access);

    m_Primitive = primitive;

    WipeGLError();
}

void VertexBuffer::FlushChunk(int actualVerts, int actualIndices)
{
    int actualVBufferSize = m_SizePerVertex * actualVerts;
    int actualIBufferSize = VertexLayout::GetDefaultIndexSize() * actualIndices;

    m_CurIndexCount = actualIndices;

    m_VB->FlushMapedRange(0, actualVBufferSize);
    m_IB->FlushMapedRange(0, actualIBufferSize);

    m_VB->UnMap();
    m_IB->UnMap();

    WipeGLError();
}

void VertexBuffer::Draw(CustomVertexLayout& layout)
{
    const byte* basepointer = 0;
    const GLuint buffer = m_VB->GetHandle();

    FillCustomVertexLayout(layout);

    VertexLayout::SetupCustomVertexLayout(layout);

    layout.RestorePointer();

    const void* indexPtr = 0;

    CheckGLError(
        throw GLException(error);
    );
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_IB->GetHandle());

    CheckGLError(
        throw GLException(error);
    );
    GLenum indexFormat = VertexLayout::GetDefaultIndexFormat();

    switch (m_Primitive)
    {
    case Primitive_Triangle:
        glDrawElements(GL_TRIANGLES, m_CurIndexCount, indexFormat, indexPtr);
        g_FrameStats.AddDrawCall();
        g_FrameStats.AddTrianglesCount(m_CurIndexCount / 3);
        break;
    case Primitive_Line:
        glDrawElements(GL_LINE, m_CurIndexCount, indexFormat, indexPtr);
        g_FrameStats.AddDrawCall();
        break;
    case Primitive_Point:
        glDrawElements(GL_POINT, m_CurIndexCount, indexFormat, indexPtr);
        g_FrameStats.AddDrawCall();
        break;
    }

    CheckGLError(
        throw GLException(error);
    );
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

void VertexBuffer::FillCustomVertexLayout(CustomVertexLayout& dst)
{
    const byte* basepointer = 0;
    const GLuint buffer = m_VB->GetHandle();

    dst.buffer = buffer;

    for (int i = 0; i < dst.attributes.size(); ++i)
    {
        int offset = dst.attributes[i].startOffset;
        dst.attributes[i].pointer = basepointer + offset;
    }
}