如何在OpenGL的缓冲区对象中使用new和delete?

ads*_*axy 1 c++ opengl

我正在学习OpenGL并将其与C++一起使用......我是初学者,如果这是一个愚蠢的问题,那就很抱歉.

我正在学习本教程(https://learnopengl.com/#!Getting-started/Hello-Triangle),我分割代码以创建片段着色器和顶点着色器并将其编译成单独的函数.显然这意味着一旦函数结束,对象就会超出范围,所以我尝试使用new并删除它们.

我试过这样做:

GLuint * pvertexShader; //pointer to a GLuint
pvertexShader = new GLuint;
Run Code Online (Sandbox Code Playgroud)

但是不知道如何将实际的缓冲区对象放入刚刚分配的新内存中.

我知道使用raw new/delete是不好的做法,所以我应该尝试使用智能指针吗?如果是这样,那对OpenGL的对象有什么用呢?

或者我应该创建一个包装类并将代码生成缓冲区放入类构造函数中,所以它变成这样:

class VBO;
(snip)
pvertexShader = new VBO; //the class is constructed on the heap 
Run Code Online (Sandbox Code Playgroud)

据我所知,当你为一个对象调用new时,它会在堆上构造.如果我这样做,我仍然可以使用像glBindBufferglAttachShader通过传递指针pvertexShader而不是实际的顶点着色器的函数?所以写作glAttachShader(shaderprogram, pvertexShader).

编辑

好的,现在我发现你做的任何东西都是通过OpenGL分配到GPU上的,所以你不必使用new/delete.因为我正在做的是这样的:

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

SetUpFragmentShader(){
//all the code to make and compile this shader
};
Run Code Online (Sandbox Code Playgroud)

然后,当我到达链接着色器和程序的阶段时,在这些函数中创建的两个着色器已超出范围(根据XCode).

我该如何预防/解决这个问题?

sen*_*nex 6

您在OpenGL中分配的缓冲区的实际内存位于GPU内.gl_buffer*函数不会像您期望的那样返回内存数组的第一个地址,而是将ID(类型为GLuint)插入到id参数中,然后您可以将其与其他OpenGL函数一起使用以处理内存.在GPU中初始化.您不需要指向其地址的指针,OpenGL仅询问内部分配给缓冲区的数字.

这是一个说明这一点的小例子.

 // 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);
Run Code Online (Sandbox Code Playgroud)

注意这个顶点着色器是如何编译的,甚至没有移动它的地址.原因是OpenGL在GPU方面为您管理,您所要做的就是使用包含OpenGL用于识别着色器的数字的GLuint.

一开始它反直觉,但这个系统确实有它的好处,例如,你可以移动任何类型的正确初始化的GL资源(如纹理或着色器),只有它的(GLuint)ID.

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