gpt4 book ai didi

c++ - OpenGL渲染器类设计: flexible and simple?

转载 作者:太空宇宙 更新时间:2023-11-04 12:01:57 25 4
gpt4 key购买 nike

我正在为 OpenGL 3.1 设计渲染系统(目前仅限于 2D)。我真正想做的是考虑优雅的设计模式,这样我就不必担心一些难以维护和调试的乱七八糟的东西。

起初,我的想法是拥有一个模板化的基类,其函数接受不同的类型名作为参数。然后子类将从基类继承,在派生时发送它们将用作模板参数的类型。

Then I found out this was basically impossible .

所以,我有点困惑,我应该如何正确地设计它而不只是把东西砍掉。关键是我正在使用自己的顶点结构,它环绕着 glm vector 类,因此我可以在结构中包含顶点对,并在调用 glVertexAttribPointer() 时使用内存偏移跨过它们

换句话说,

typedef struct colorVertex_d
{
glm::vec3 Position;
glm::vec4 Color;
}
colorVertex_t;

typedef struct textureVertex_d
{
glm::vec3 Position;
glm::vec2 UV;
}
textureVertex_t;

理想情况下,我想做的是将此渲染器中可用的实际类型限制为已定义的顶点类型。

我认为这样做的一种方法是按照 this 的方式做一些事情,然后在发送到类的类型无效时调用 Shutdown 方法(有点像异常,只是不是异常...)。

不过,我什至不确定在这种情况下这是否可以被视为一个好的实现。

我真正想要的是一种方法,我可以支持多种缓冲区类型(例如顶点、索引、法线、颜色等),这些缓冲区类型符合上面显示的顶点结构等类型。

原始来源

/**
* Is an abstract class to inherit from for defining custom buffer handler classes,
* the type name specified is the type of data stored in the buffer specifically, e.g. textureVertex_t or colorVertex_t
*/

template < typename DataT, typename ContainerT >
class RenderBuffer
{
public:
enum RenderMethod
{
Stream, // used for writing data into the buffer once per render
Dynamic, // values in the buffer are changed from time to time
Static // data is set only once, then rendered as many times as it needs to be
};

enum DrawMode
{
Triangle,
TriangleStrip,
Line,
LineStrip
};

enum BufSetType
{
Alloc,
Update
};

RenderBuffer( RenderMethod rm, DrawMode dm )
{
switch( rm )
{
case Stream: mRenderMethod = GL_STREAM_DRAW; break;
case Dynamic: mRenderMethod = GL_DYNAMIC_DRAW; break;
case Static: mRenderMethod = GL_STATIC_DRAW; break;
}

switch( dm )
{
case Triangle: mDrawMode = GL_TRIANGLES; break;
case TriangleStrip: mDrawMode = GL_TRIANGLE_STRIP; break;
case Line: mDrawMode = GL_LINES; break;
case LineStrip: mDrawMode = GL_LINE_STRIP; break;
}
}

virtual ~RenderBuffer( void )
{
}

virtual void Reserve( size_t sz ) = 0; // Reserve space for whatever container used to store the buffer data.

virtual void Bind( void ) const = 0;

virtual void UnBind( void ) const = 0;

template < typename DataT, ContainerT >
virtual void SetBufferData( const ShaderProgram& program, const ContainerT& data, BufSetType m )
{
}

template < typename DataT, ContainerT >
virtual void SetBufferData( const ShaderProgram& program, const DataT* data, const size_t len, BufSetType m )
{
}

virtual void Render( void ) const = 0;

size_t VertexCount;

protected:
GLenum mDrawMode, mRenderMethod;
};

最佳答案

我打了一堆东西,但我仍然不确定你的目标或问题是什么。您似乎正在尝试创建一个 对象来封装 OpenGL 可以执行的所有操作。我的第一个建议是不要这样做。

我建议使用 Mesh 类,它包含一个 VAO 和一个程序,并且知道如何渲染自己:

glUseProgram(mProgramID);
glBindVertexArray(mVAO);
glDrawArrays(mDrawMode, 0, mNumPrimitives);

我认为这就是您要实现的目标。

我建议使用子类而不是所有的模板。设置一个有很多工作(可能还有不同的子类、参数化函数或重载),但一旦设置完成,渲染就很简单。

如果您对使用模板死心塌地,那么模板特化可能会帮助您弥合差距。但是我在这里并没有真正看到模板的良好用途;感觉就像你试图把它们塞进去。

关于c++ - OpenGL渲染器类设计: flexible and simple?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13770263/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com