I tried many different ways of VAO/VBO but it did not work so well. When attempted to two rendered objects with own separated VAOs, vertex buffers went garbage (overwritten). Here are my codes about vertex buffer calls. I will update this for multi-buffer handling later.
It only use one buffer at all time for now. I can only render one rendered object at this time and it worked fine. It displays constellation lines or varying-size star points clearly. When I attempted to display rendered star objects and rendered constellation line objects, display garbage like colorful lines and oversized star points instead.
class VertexBuffer
{
public:
enum BufferType {
VAO, VBO, EBO
};
VertexBuffer(const Context &gl, int nArrays = 1);
~VertexBuffer();
inline void bind() const { glBindVertexArray(vao); };
inline void unbind() const { glBindVertexArray(0); };
void createBuffer(BufferType type, uint32_t nBuffers);
void assign(BufferType type, void *data, uint32_t size);
private:
const Context ≷
GLuint vao, vbo, ebo;
};
VertexBuffer::VertexBuffer(const Context &gl, int nArrays)
: gl(gl), vao(0), vbo(0), ebo(0)
{
glGenVertexArrays(nArrays, &vao);
}
VertexBuffer::~VertexBuffer()
{
if (vbo > 0)
glDeleteBuffers(1, &vbo);
if (ebo > 0)
glDeleteBuffers(1, &ebo);
if (vao > 0)
glDeleteVertexArrays(1, &vao);
}
void VertexBuffer::createBuffer(BufferType type, uint32_t nBuffers)
{
bind();
switch (type) {
case VBO:
glGenBuffers(nBuffers, &vbo);
break;
case EBO:
glGenBuffers(nBuffers, &ebo);
break;
}
}
void VertexBuffer::assign(BufferType type, void *data, uint32_t size)
{
bind();
switch (type) {
case VBO:
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
break;
case EBO:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_DYNAMIC_DRAW);
break;
}
// glBindBuffer(GL_ARRAY_BUFFER, 0);
// unbind();
}
Here is one of rendered objects - constellation lines rendering.
void Scene::initConstellations(const Universe &universe)
{
const Constellations &constellations = universe.getAsterism();
const StarCatalogue &starlib = *universe.getStarCatalogue();
const vector<Asterism *> &asterisms = constellations.getAsterisms();
pgmAsterism = smgr.createShader("line");
pgmAsterism->use();
vbufAsterism = new VertexBuffer(gl, 1);
vbufAsterism->createBuffer(VertexBuffer::VBO, 1);
int cLines = 0;
for (int idx = 0; idx < asterisms.size(); idx++) {
Asterism *aster = asterisms[idx];
cLines += aster->hip.size();
}
bufAsterism = new VertexLine[cLines];
cout << "VertexLine Size: " << sizeof(VertexLine) << endl;
}
void Scene::renderConstellations(const Universe &universe, const Player &player)
{
const Constellations &constellations = universe.getAsterism();
const StarCatalogue &starlib = *universe.getStarCatalogue();
const vector<Asterism *> &asterisms = constellations.getAsterisms();
Camera *cam = player.getCamera(0);
vec3d_t cpos = cam->getPosition();
int cLines = 0;
pgmAsterism->use();
vbufAsterism->bind();
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexLine), (void *)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(VertexLine), (void *)(3 * sizeof(float)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
int rLines = 0;
for (int idx = 0; idx < asterisms.size(); idx++) {
Asterism *aster = asterisms[idx];
for (int sidx = 0; sidx < aster->hip.size(); sidx += 2) {
CelestialStar *star1 = starlib.getHIPStar(aster->hip[sidx]);
CelestialStar *star2 = starlib.getHIPStar(aster->hip[sidx+1]);
if (star1 == nullptr)
std::cout << "HIP " << aster->hip[sidx] << " Missing" << std::endl;
if (star2 == nullptr)
std::cout << "HIP " << aster->hip[sidx+1] << " Missing" << std::endl;
if (star1 == nullptr || star2 == nullptr)
continue;
bufAsterism[rLines].lpos = vec3f_t(star1->getPosition(0) * KM_PER_PC);
bufAsterism[rLines].color = Color(0.2, 0.2, 0.2, 1.0);
rLines++;
bufAsterism[rLines].lpos = vec3f_t(star2->getPosition(0) * KM_PER_PC);
bufAsterism[rLines].color = Color(0.2, 0.2, 0.2, 1.0);
rLines++;
// std::cout << "HIP: " << aster->hip[sidx]
// << " Name: " << star->name(0) << std::endl;
}
// std::cout << std::endl;
}
vbufAsterism->assign(VertexBuffer::VBO, bufAsterism, sizeof(VertexLine)*rLines);
mat4f_t mvp = mat4f_t (prm.dmProj * prm.dmView * mat4d_t(1.0));
uint32_t mvpLoc = glGetUniformLocation(pgmAsterism->getID(), "mvp");
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, glm::value_ptr(mvp));
glDrawArrays(GL_LINES, 0, rLines);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
vbufAsterism->unbind();
glUseProgram(0);
}