1

My idea and requirement are to allow creating atmost 'n' buffers (where is n<7) during the program execution. So, ideally, I am looking for a way, where I can draw different things to different buffers and render each buffer as and when needed.

Like:

Buffer1 - Draw a rectangle

Buffer2 - Draw some texture (font/text) "Welcome"

Buffer3 - Draw some polygon

Buffer4 - Draw some texture (font/text) "Supporter of Stack overflow"

... and so on.

Here simultaneously, I want to write different things to different buffers. And then I may only want to render say contents of Buffer2, then after some time flush the display and render Buffer4.

My not working code:

GLuint VB1;
glGenBuffers(1, &VB1);
glUseProgram(ProgramObject);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
DrawRect(VB1);

GLuint VB2;
glGenBuffers(1, &VB2);
glUseProgram(ProgramObject);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
TextDraw(VB1, "Welcome");

eglSwapBuffers(egldisplay, eglsurface);

This renders everything of VB1 and VB2 both, when I say eglSwapBuffer. How can I only render one buffer.

I am doing

glBindBuffer(GL_ARRAY_BUFFER, VB)

in DrawRect() and TextDraw() definitions, which I believe should not be done.

Need help to determine how to write to each buffers separately and how to bind the required buffer contents on the display. (when needed).

DrawRect Implementation

void DrawRect(GLint VB)
{
int position_loc = glGetAttribLocation(ProgramObject, "vertex");
GLfloat Vertices[4][4] = {
              -1.0f,  1.0f, 0.0f, 1.0f,
               1.0f,  1.0f, 0.0f, 1.0f,
              -1.0f,  -1.0f, 0.0f, 1.0f,
               1.0f,  -1.0f, 0.0f, 1.0f
        };
GLfloat red[4] = {1, 0, 1, 1};
glUniform4fv(glGetUniformLocation(ProgramObject, "color"), 1, red);
glEnableVertexAttribArray(position_loc);
printf("\nAfter Enable Vertex Attrib Array");
glBindBuffer(GL_ARRAY_BUFFER, VB);
glVertexAttribPointer(position_loc, 4, GL_FLOAT, GL_FALSE, 0, 0);
glBufferData(GL_ARRAY_BUFFER, sizeof Vertices, Vertices, GL_DYNAMIC_DRAW);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}



void TextDraw(GLuint VB, std::string message, GLfloat x, GLfloat y, GLfloat sx, GLfloat sy)

{
int vPosition = glGetAttribLocation(ProgramObject, "vertex");
std::string::const_iterator ch;
for (ch = message.begin(); ch != message.end(); ch++)
{
    const char c = *ch;
    if (FT_Load_Char(face, c, FT_LOAD_RENDER | FT_LOAD_COLOR))
    {
        std::cout << "ERROR::FREETYTPE: Failed to load Glyph" << std::endl;
        continue;
    }

GLfloat xpos = x + (face->glyph->bitmap_left) * sx;
    GLfloat ypos = -y - (face->glyph->bitmap_top) * sy;
    GLfloat w = (face->glyph->bitmap.width) * sx;
    GLfloat h = (face->glyph->bitmap.rows) * sy;

    GLfloat vertices[4][4] = {
    {xpos,     -ypos    , 0, 0},
    {xpos + w, -ypos    , 1, 0},
    {xpos,     -ypos - h, 0, 1},
    {xpos + w, -ypos - h, 1, 1},
    };

    glActiveTexture(GL_TEXTURE0);
    GLuint text;
    glGenTextures(1, &text);
    glBindTexture(GL_TEXTURE_2D, text);
    glUniform1i(glGetUniformLocation(ProgramObject, "text"), 0);
    PrintGlError();
    GLfloat black[4] = {0, 0, 0, 1};
    glUniform4fv(glGetUniformLocation(ProgramObject, "color"), 1, black);
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(
        GL_TEXTURE_2D,
        0,
        GL_ALPHA,
        face->glyph->bitmap.width,
        face->glyph->bitmap.rows,
        0,
        GL_ALPHA,
        GL_UNSIGNED_BYTE,
        face->glyph->bitmap.buffer
    );
    glBufferData(GL_ARRAY_BUFFER, sizeof vertices, vertices, GL_DYNAMIC_DRAW);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    x += (face->glyph->advance.x/64) * sx;
    y += (face->glyph->advance.y/64) * sy;
    glDeleteTextures(1, &text);
    glDisableVertexAttribArray(vPosition);
}

}
moizh
  • 55
  • 6
  • This smells like an XY problem. Why the requirement to have different 'buffers' and choose between them? What do your `DrawRect` and `TextDraw` functions do with the buffers? Can't you do conditional drawing? Do textures count as buffers? – Botje Nov 22 '18 at 08:55
  • So what exactly prevents you from having n buffers, drawing to them and then drawing them to back buffer? – user7860670 Nov 22 '18 at 09:22
  • @Botje As per the LearnOpenGL tutorials I have followed, I thought we need buffers always, isn't it? What do you mean by conditional drawing? Can it be done without buffers? – moizh Nov 22 '18 at 09:31
  • 1
    @VTT Thats how exactly I want to do. But I did not find any tutorial or example of how in OpenGL should I draw to n buffers and copy one at a time to actual rendering surface to get it rendered. Can you point me to some example that shows how to do that? – moizh Nov 22 '18 at 09:35
  • I think there is a confusion at play here: there are Frame buffers (which are a target that OpenGL can render to and from?), there are Vertex buffer objects (which contain data about vertices used in rendering operations), and there are Vertex array objects (which tell OpenGL how to interpret the VBOs when it is actually rendering) – Botje Nov 22 '18 at 09:38
  • The simplest case is that you use the default framebuffer (ie your window) and render directly the contents of VBOs to it using something like `glDrawArrays(GL_TRIANGLES, vbo)`. Conditional rendering is then simply deciding whether to call `glDrawArrays` or not depending on some condition. – Botje Nov 22 '18 at 09:40
  • If you really insist on having a _frame buffer_ for every object, you will have to generate a frame buffer (`glGenFramebuffers`), attach a texture or render buffer to it, then bind it, render to it, unbind it, and finally render the texture/render buffer to your default frame buffer. – Botje Nov 22 '18 at 09:41
  • I am developing an application, where my requirement is to preapre/draw the selected content in an offscreen buffer 'X'. And then render only buffer X on display. While I am preparing buffer X1, I may get another request to prepare X2 (X3, X4 and more) and hence I prepare X2, but while delivering to screen I will deliver X1 for n seconds first then clear the screen and deliver X2. – moizh Nov 22 '18 at 09:44
  • I have updated the description with the definitions of DrawaRect() and TextDraw(), that I am using. – moizh Nov 22 '18 at 10:02
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/184124/discussion-between-moizh-and-botje). – moizh Nov 23 '18 at 06:13

0 Answers0