43143d63e8a03d1a8a84b84dfaca4590d973c08b
[ipdf/code.git] / src / graphicsbuffer.cpp
1 #include "graphicsbuffer.h"
2 #define GL_GLEXT_PROTOTYPES
3 #include <SDL_opengl.h>
4 #include <GL/glext.h>
5
6 using namespace IPDF;
7
8 static GLenum BufferUsageToGLUsage(GraphicsBuffer::BufferUsage buffer_usage)
9 {
10         GLenum usage;
11         switch (buffer_usage)
12         {
13         case GraphicsBuffer::BufferUsageStaticDraw:
14                 usage = GL_STATIC_DRAW;
15                 break;
16         case GraphicsBuffer::BufferUsageStaticRead:
17                 usage = GL_STATIC_READ;
18                 break;
19         case GraphicsBuffer::BufferUsageStaticCopy:
20                 usage = GL_STATIC_COPY;
21                 break;
22         case GraphicsBuffer::BufferUsageDynamicDraw:
23                 usage = GL_DYNAMIC_DRAW;
24                 break;
25         case GraphicsBuffer::BufferUsageDynamicRead:
26                 usage = GL_DYNAMIC_READ;
27                 break;
28         case GraphicsBuffer::BufferUsageDynamicCopy:
29                 usage = GL_DYNAMIC_COPY;
30                 break;
31         case GraphicsBuffer::BufferUsageStreamDraw:
32                 usage = GL_STREAM_DRAW;
33                 break;
34         case GraphicsBuffer::BufferUsageStreamRead:
35                 usage = GL_STREAM_READ;
36                 break;
37         case GraphicsBuffer::BufferUsageStreamCopy:
38                 usage = GL_STREAM_COPY;
39                 break;
40         default:
41                 SDL_assert(false && "Unknown buffer usage type.");
42                 usage = GL_DYNAMIC_DRAW;
43         }
44         return usage;
45 }
46
47 static GLenum BufferTypeToGLType(GraphicsBuffer::BufferType buffer_type)
48 {
49         switch (buffer_type)
50         {
51         case GraphicsBuffer::BufferTypeVertex:
52                 return GL_ARRAY_BUFFER;
53         case GraphicsBuffer::BufferTypeIndex:
54                 return GL_ELEMENT_ARRAY_BUFFER;
55         case GraphicsBuffer::BufferTypePixelPack:
56                 return GL_PIXEL_PACK_BUFFER;
57         case GraphicsBuffer::BufferTypePixelUnpack:
58                 return GL_PIXEL_UNPACK_BUFFER;
59         case GraphicsBuffer::BufferTypeUniform:
60                 return GL_UNIFORM_BUFFER;
61         case GraphicsBuffer::BufferTypeDrawIndirect:
62                 return GL_DRAW_INDIRECT_BUFFER;
63         default:
64                 return GL_COPY_READ_BUFFER;
65         }
66 }
67
68 GraphicsBuffer::GraphicsBuffer()
69 {
70         SetUsage(BufferUsageStaticDraw);
71 }
72
73 GraphicsBuffer::~GraphicsBuffer()
74 {
75         if (m_map_pointer)
76         {
77                 UnMap();
78         }
79         glDeleteBuffers(1, &m_buffer_handle);
80 }
81
82 void GraphicsBuffer::SetType(GraphicsBuffer::BufferType bufType)
83 {
84         glGenBuffers(1, &m_buffer_handle);
85         m_buffer_type = bufType;
86 }
87
88 void GraphicsBuffer::SetUsage(GraphicsBuffer::BufferUsage bufUsage)
89 {
90         m_buffer_usage = bufUsage;
91 }
92
93 void* GraphicsBuffer::Map(bool read, bool write, bool invalidate)
94 {
95         GLbitfield access = ((read)?GL_MAP_READ_BIT:0) | ((write)?GL_MAP_WRITE_BIT:0) | ((invalidate)?GL_MAP_INVALIDATE_BUFFER_BIT:0);
96         GLenum target = BufferTypeToGLType(m_buffer_type);
97
98         Bind();
99         
100         return glMapBufferRange(target, 0, m_buffer_size, access);
101         
102         //TODO: Emulate DSA
103         //return glMapNamedBufferEXT(m_bufferHandle, access);
104 }
105
106 void* GraphicsBuffer::MapRange(int offset, int length, bool read, bool write, bool invalidate)
107 {
108         GLbitfield access = ((read)?GL_MAP_READ_BIT:0) | ((write)?GL_MAP_WRITE_BIT:0) | ((invalidate)?GL_MAP_INVALIDATE_RANGE_BIT:0);
109         GLenum target = BufferTypeToGLType(m_buffer_type);
110         
111         Bind();
112         
113         return glMapBufferRange(target, offset, length, access);
114
115         //TODO: Emulate DSA
116         //return glMapNamedBufferRangeEXT(m_bufferHandle, offset, length, access);
117 }
118
119 void GraphicsBuffer::UnMap()
120 {
121         GLenum target = BufferTypeToGLType(m_buffer_type);
122         
123         Bind();
124         glUnmapBuffer(target);
125         //glUnmapNamedBufferEXT(m_bufferHandle);
126 }
127
128 void GraphicsBuffer::Upload(size_t length, const void* data)
129 {
130         GLenum target = BufferTypeToGLType(m_buffer_type);
131         
132         GLenum usage = BufferUsageToGLUsage(m_buffer_usage);
133         
134         Bind();
135         glBufferData(target, length, data, usage);
136         m_buffer_size = length;
137         //glNamedBufferDataEXT(m_bufferHandle, length, data, usage);
138 }
139
140 void GraphicsBuffer::UploadRange(size_t length, intptr_t offset, const void* data)
141 {
142         GLenum target = BufferTypeToGLType(m_buffer_type);
143         
144         Bind();
145         glBufferSubData(target, offset, length, data);
146         //glNamedBufferSubDataEXT(m_bufferHandle, offset, length, data);
147 }
148
149 void GraphicsBuffer::Resize(size_t length)
150 {
151         if (m_invalidated)
152         {
153                 Upload(length, nullptr);
154         }
155         else
156         {
157                 // Create a new buffer and copy the old data into it.
158                 UnMap();
159                 GLuint old_buffer = m_buffer_handle;    
160                 glGenBuffers(1, &m_buffer_handle);
161                 Upload(length, nullptr);
162                 glBindBuffer(GL_COPY_READ_BUFFER, old_buffer);
163                 glBindBuffer(GL_COPY_WRITE_BUFFER, m_buffer_handle);
164                 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, m_buffer_size);
165                 glDeleteBuffers(1, &old_buffer);
166         }
167
168 }
169
170 void GraphicsBuffer::Bind()
171 {
172         if (m_buffer_type == BufferTypeUniform)
173                 glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_buffer_handle);
174         else
175                 glBindBuffer(BufferTypeToGLType(m_buffer_type), m_buffer_handle);
176 }
177

UCC git Repository :: git.ucc.asn.au