ultimatepp/uppsrc/GLDraw/VertexData.cpp
cxl 88d829fb77 GLDraw: Fixed GLVertex copy
git-svn-id: svn://ultimatepp.org/upp/trunk@13745 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2019-12-09 08:27:37 +00:00

116 lines
No EOL
2.9 KiB
C++

#include "GLDraw.h"
namespace Upp {
GLVertexData::GLVertexData(const GLVertexData& src)
{
if(src.data) {
data = src.data;
data->refcount++;
}
}
GLVertexData& GLVertexData::operator=(const GLVertexData& src)
{
if(data != src.data) {
if(data) Clear();
data = src.data;
data->refcount++;
}
return *this;
}
void GLVertexData::Clear()
{
if(data && --data->refcount == 0) {
glDeleteVertexArrays(1, &data->VAO);
glDeleteBuffers(1, &data->EBO);
for(auto h : data->VBO)
glDeleteBuffers(1, &h);
delete data;
}
data = NULL;
}
void GLVertexData::Do()
{
if(!data) {
data = new Data;
glGenVertexArrays(1, &data->VAO);
glGenBuffers(1, &data->EBO);
}
ASSERT(data->refcount == 1); // Changes are only allowed before copied
}
GLVertexData& GLVertexData::Add(const void *values, int type, int ntuple, int count)
{
Do();
glBindVertexArray(data->VAO);
int ii = data->VBO.GetCount();
GLuint& vbo = data->VBO.Add();
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
int sz = (int)decode(type, GL_FLOAT, sizeof(float),
GL_BYTE, sizeof(byte),
GL_UNSIGNED_BYTE, sizeof(byte),
GL_SHORT, sizeof(int16),
GL_UNSIGNED_SHORT, sizeof(uint16),
GL_INT, sizeof(int32),
GL_UNSIGNED_INT, sizeof(uint32),
sizeof(double));
glBufferData(GL_ARRAY_BUFFER, sz * ntuple * count, values, GL_STATIC_DRAW);
if(type == GL_FLOAT)
glVertexAttribPointer(ii, ntuple, type, GL_FALSE, ntuple * sz, (void*)0);
else
glVertexAttribIPointer(ii, ntuple, type, ntuple * sz, (void*)0);
glEnableVertexAttribArray(ii);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
return *this;
}
GLVertexData& GLVertexData::Index(const int *indices, int count)
{
Do();
glBindVertexArray(data->VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data->EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int) * count, indices, GL_STATIC_DRAW);
glBindVertexArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
data->elements = count;
return *this;
}
extern int sDrawCounter;
extern int sElementCounter;
void GLVertexData::Draw(int mode) const
{
if(data) {
GL_TIMING("GLVertexData::Draw");
glBindVertexArray(data->VAO);
glDrawElements(mode, data->elements, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
sDrawCounter++;
sElementCounter += data->elements;
}
}
void GLVertexData::Draw(GLCode& shaders, int mode) const
{
shaders.Use();
Draw(mode);
}
GLVertexData& GLVertexData::Add(const Vector<Pointf>& pt)
{
Buffer<float> f(2 * pt.GetCount());
float *t = f;
for(const Pointf& p : pt) {
*t++ = (float)p.x;
*t++ = (float)p.y;
}
return Add(f, GL_FLOAT, 2, pt.GetCount());
}
};