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

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