adstlaxy
adstlaxy

Reputation: 51

How do you use new and delete with OpenGL's buffer objects?

I am learning OpenGL and using it with C++... I'm a beginner so sorry if this is a stupid question.

I was following this tutorial (https://learnopengl.com/#!Getting-started/Hello-Triangle), and I split the code to create & compile the fragment shader and vertex shader into separate functions. Obviously this means the objects go out of scope once the function ends so I tried to use new and delete with them.

I tried doing this:

GLuint * pvertexShader; //pointer to a GLuint
pvertexShader = new GLuint;

but didn't know how to put the actual buffer object into the new memory I just allocated.

I know it's bad practice to use raw new/delete, so should I try using a smart pointer instead? If so, how would that work with OpenGL's objects?

Or should I make a wrapper class and put the code to generate the buffer into the class constructor, so it becomes like this:

class VBO;
(snip)
pvertexShader = new VBO; //the class is constructed on the heap 

As far as I know when you call new for an object then it gets constructed on the heap. If I did this, would I still be able to use functions like glBindBuffer or glAttachShader by passing the pointer pvertexShader instead of the actual vertex shader? so writing glAttachShader(shaderprogram, pvertexShader).

EDIT

Ok, so now I found out that anything you make is allocated onto the GPU by OpenGL, so you don't have to use new/delete. Since what I'm doing is like this:

SetUpVertexShader(){
//all the code to make and compile a shader
};

SetUpFragmentShader(){
//all the code to make and compile this shader
};

Then when I get to the stage where you link the shaders and the program, the two shaders made in those functions have gone out of scope (according to XCode).

How do I prevent/get around this?

Upvotes: 1

Views: 1108

Answers (2)

senex
senex

Reputation: 447

The actual memory for the buffers you allocate with pretty much anything in OpenGL lies within the GPU. gl_buffer* functions do not return the first address of an array of memory like you seem to expect, instead they insert an ID (of type GLuint) to the id argument that you can then use with other OpenGL functions to work with the memory that was initialized in the GPU. You don't need a pointer to its address, OpenGL only asks for the number it internally assigned to the buffer.

Here's a small example illustrating this.

 // unsigned int to hold the ID that OpenGL will assign to this shader
  GLuint sVertex;

  sVertex = glCreateShader(GL_VERTEX_SHADER);
  glShaderSource(sVertex, 1, &vertexSource, NULL);
  glCompileShader(sVertex);

Notice how this vertex shader was compiled without even moving around its address. The reason is that OpenGL manages that for you on the GPU side, all you have to do is work with the GLuint that contains a number OpenGL uses to identify your shader.

It's counter intuitive at first but this system does have its benefits, for example you can move around any kind off correctly initialized GL resource (like a texture or a shader) with just its (GLuint)ID, for example.

// texture_id contains the number that OpenGL uses to reference this particular texture in the GPU memory
void use_texture(GLuint texture_id);

Upvotes: 6

Ripi2
Ripi2

Reputation: 7198

Step by step.

You only need pointers when you store complex data, likely inside a struct/class. And then smart pointers are quite appropiate.

glXXXX calls don't provide pointers (except glMapBuffer). Any memory they create (e.g. by glBufferData) is GPU memory, not client (i.e. on the CPU side) one. Don't bother with it.

Reading shaders code, compiling them, linking them, getting errors, are repetitive jobs with few client results to store, like the integer that identifies the shader program. They are suitable to be encapsulated in classes.

Objects VBO, VAO, vertices data and so on are also suitable for classes. Same goes for camera handling, rendering and other features of your app.

The main point is that you organizate your code by tasks/objects.

Upvotes: 1

Related Questions