1
\$\begingroup\$

So ive (tried to) implement a batch rendering system, and at the for loop the error pops up and I'm not shure what ive done wrong. Any suggestions to improve the system would be much appreciated. (It's my first time trying to implement this)

#include "masterRenderer.h"

masterRenderer::masterRenderer() {
    quad = vector<Quad>(1000);
    numOf = 0;
} 

void masterRenderer::addQuad(Quad quad) {
    masterRenderer::quad[numOf] = quad;
    numOf++;
}

void masterRenderer::init(GLuint shader, string texPath) {
    vector<GLfloat> vertex((3 * 4) * (numOf + 1));
    vector<GLfloat> normals((3 * 4) * (numOf + 1));
    vector<GLfloat> color((3 * 4) * (numOf + 1));
    vector<GLfloat> uv((2 * 4) * (numOf + 1));

    int nv = 0, nn = 0, nc = 0, nu = 0;

    GLfloat sizeV = 0, sizeN = 0, sizeC = 0, sizeUv = 0;

    for (int i = 0; i < numOf; i++) {      // The error seems to pop up over here.
        for (int j = 0; j < 3 * 4; j++) {
            vertex[nv] = quad[i].g_vertex_buffer_data[j];
            sizeV += quad[i].g_vertex_buffer_data[j];
            nv++;
            normals[nn] = quad[i].g_normal_buffer_bata[j];
            sizeN += quad[i].g_normal_buffer_bata[j];
            nn++;
            color[nc] = quad[i].g_color_buffer_data[j];
            sizeC += quad[i].g_color_buffer_data[j];
            nc++;
        }

        for (int j = 0; j < 2 * 4; j++) {
            uv[nc] = quad[i].g_uv_buffer_data[j];
            sizeUv += quad[i].g_uv_buffer_data[j];
            nc++;
        }
    }

    TextureID = glGetUniformLocation(shader, "textureSampler");
    texture_handle = Util::loadTexture("test.png");

    glGenBuffers(1, &normalbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(sizeN), &normals[0], GL_STATIC_DRAW);

    glGenBuffers(1, &colorbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(sizeC), &color[0], GL_STATIC_DRAW);

    glGenBuffers(1, &uvbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(sizeUv), &uv[0], GL_STATIC_DRAW);

    glGenBuffers(1, &vertexbuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(sizeV), &vertex[0], GL_STATIC_DRAW);
}

void masterRenderer::draw(glm::mat4 Model, glm::mat4 View, glm::mat4 Projection, GLuint MatrixID) {
    glPushMatrix();
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture_handle);
    glUniform1i(TextureID, 0);
    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glEnableVertexAttribArray(3);
    glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
    glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    for (int i = 0; i < numOf + 1; i++) {
        Model = glm::translate(glm::mat4(1.0f), glm::vec3(quad[i - 1].pos.x, quad[i - 1].pos.y, quad[i - 1].pos.z));
        Model = glm::rotate(Model, glm::radians(quad[i-1].yrot), glm::vec3(0.0f, 1.0f, 0.0f));

        glm::mat4 mvp = Projection * View * Model;
        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);
        glDrawArrays(GL_QUADS, 4 * i - 1, 4 * i);
    }
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
    glDisableVertexAttribArray(3);
    glPopMatrix();
}

masterRenderer::~masterRenderer() { }
\$\endgroup\$
3
  • \$\begingroup\$ where and how do you call masterRenderer::AddQuad()? Is it before calling init or after? \$\endgroup\$ Dec 6, 2015 at 10:35
  • \$\begingroup\$ Add quad after the quads are initialized then init. \$\endgroup\$
    – user68817
    Dec 6, 2015 at 10:46
  • \$\begingroup\$ probably not related, but what for do you do sums like sizeV += quad[i].g_vertex_buffer_data[j];? Also, is sizeV ever used? \$\endgroup\$
    – wondra
    Dec 6, 2015 at 13:30

1 Answer 1

2
\$\begingroup\$

There is an error in lines copying data to buffers, you give it incorrect size - not taking in account actual size of data. The second parameter should be size of data in bytes, the sizeof(sizeN) will always return 4 (=the size of GLfloat). For example, instead of

glBufferData(GL_ARRAY_BUFFER, sizeof(sizeN), &normals[0], GL_STATIC_DRAW);

you probably meant

glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * sizeN, &normals[0], GL_STATIC_DRAW);

the size of one GLfloat times number of GLfloats. Moreover, there is no need to keep incrementing the sizeN(also it should not be floating point type if you count integer number of elements) because you can get the element count directly from vector:

glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * normals.size(), &normals[0], GL_STATIC_DRAW);

same applies to all buffers.
For the out of range problem I suggest you use push_back() and reserve() instead, this should avoid any of these problems completely. Summing it up:

void masterRenderer::init(GLuint shader, string texPath) {
vector<GLfloat> vertex;
vector<GLfloat> normals;
vector<GLfloat> color;
vector<GLfloat> uv;

vertex.reserve((3 * 4) * (numOf + 1));
normals.reserve((3 * 4) * (numOf + 1));
color.reserve((3 * 4) * (numOf + 1));
uv.reserve((2 * 4) * (numOf + 1));

for (int i = 0; i < numOf; i++) { 
    for (int j = 0; j < 3 * 4; j++) {
        vertex.push_back(quad[i].g_vertex_buffer_data[j]);
        normals.push_back(quad[i].g_normal_buffer_bata[j]);
        color.push_back(quad[i].g_color_buffer_data[j]);
    }

    for (int j = 0; j < 2 * 4; j++)
        uv.push_back(quad[i].g_uv_buffer_data[j]);
}

TextureID = glGetUniformLocation(shader, "textureSampler");
texture_handle = Util::loadTexture("test.png");

glGenBuffers(1, &normalbuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * normals.size(), &normals[0], GL_STATIC_DRAW);

glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * color.size(), &color[0], GL_STATIC_DRAW);

glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * uv.size(), &uv[0], GL_STATIC_DRAW);

glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * vertex.size(), &vertex[0], GL_STATIC_DRAW);
}
\$\endgroup\$
1
  • \$\begingroup\$ ...I am not sure if this is the only error in you code but hope it helps, be sure to comment/expand your question. \$\endgroup\$
    – wondra
    Dec 6, 2015 at 13:42

You must log in to answer this question.