我想知道为什么OpenGL会将指针指向资源ID,因为我正在做这样的事情:
#include "OglResource.h"
#include <iostream>
void WINAPI DeleteVertexArray( GLuint item )
{
glDeleteVertexArrays(1, &item);
}
OglResource MakeOglResource( GLenum type )
{
switch( type )
{
case GL_VERTEX_SHADER:
return OglResource(glCreateShader(GL_VERTEX_SHADER), (OglResource::ReleaseFunc)glDeleteShader, GL_VERTEX_SHADER);
break;
case GL_FRAGMENT_SHADER:
return OglResource(glCreateShader(GL_FRAGMENT_SHADER), (OglResource::ReleaseFunc)glDeleteShader, GL_FRAGMENT_SHADER);
break;
case GL_VERTEX_ARRAY:
{
GLuint out = OglResource::INVALID_OGL_RESOURCE_ID;
glGenVertexArrays(1, &out);
return OglResource(out, DeleteVertexArray, GL_VERTEX_ARRAY);
}
break;
}
return OglResource();
}
如果我传递给OpenGL的资源ID的地址确实很重要,这很危险,因为只要MakeOglResource函数返回,我传递给OpenGL(&amp; out)的位置就无效。
我对此进行了测试,但似乎没有崩溃应用程序,但我很担心。
以下是OglResource的实现:
#ifndef _HANDLE_H
#define _HANDLE_H
#include <memory>
#include <functional>
#define CALL_CONVENTION WINAPI
template <typename HANDLE_TYPE>
class Handle
{
public:
typedef void (CALL_CONVENTION *ReleaseFunc)(HANDLE_TYPE);
private:
// Handler
std::shared_ptr<void> m_spItem;
public:
operator HANDLE_TYPE()
{
return (HANDLE_TYPE)(m_spItem.get());
}
Handle( void )
: m_spItem()
{
}
Handle( HANDLE_TYPE id, ReleaseFunc fpRelease )
: m_spItem(nullptr)
{
Reset(id,fpRelease);
}
void Reset( void )
{
m_spItem.reset();
}
void Reset( HANDLE_TYPE handle, ReleaseFunc fpRelease)
{
m_spItem.reset((void*)handle,[=](void* vpItem)
{
fpRelease((HANDLE_TYPE)vpItem);
});
}
};
#endif // _HANDLE_H
#ifndef _OGLRESOURCE_H
#define _OGLRESOURCE_H
#include <Windows.h>
#include <gl/glew.h>
#include <Gl/GL.h>
#include "Handle.h"
class OglResource : public Handle<GLuint>
{
friend OglResource MakeOglResource( GLenum type );
public:
GLenum m_type;
OglResource( void )
: Handle()
, m_type(0)
{
}
OglResource( GLuint resource, Handle::ReleaseFunc fpRelease, GLenum type )
: Handle(resource, fpRelease)
, m_type(type)
{
}
enum { INVALID_OGL_RESOURCE_ID = 0 };
}; // class OglShader
OglResource MakeOglResource( GLenum type );
#endif // _OGLRESOURCE_H
答案 0 :(得分:5)
此接口允许调用者通过单个调用生成或删除多个资源ID(也称为名称)。我认为这纯粹是一种效率考虑。如果您通过值传递,则每个ID都需要一次调用。
例如,这会生成并删除3个ID:
GLuint ids[3];
glGenBuffers(3, ids);
glDeleteBuffers(3, ids);
否则你将需要3个电话来生成和删除3个ID。
无需将同一指针传递给Gen
和Delete
。以下是完全合法和安全的:
GLuint id = 0;
glGenBuffers(1, &id);
GLuint idCopy = id;
glDeleteBuffers(1, &idCopy);