面向对象编程和 OpenGL
我想使用 OpenGL 作为我项目的图形。但我真的很想以一种好的风格来做。如何为每个类声明一个成员函数“draw()”以在 OpenGL 显示函数中调用它?
例如,我想要这样的东西:
class Triangle
{
public:
void draw()
{
glBegin(GL_TRIANGLES);
...
glEnd();
}
};
I want to use OpenGL as graphics of my project. But I really want to do it in a good style. How can I declare a member function "draw()" for each class to call it within OpenGL display function?
For example, I want something like this:
class Triangle
{
public:
void draw()
{
glBegin(GL_TRIANGLES);
...
glEnd();
}
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
嗯,这还取决于您有多少时间以及需要什么。你的方法还不错,只是有点老套。现代 OpenGL 使用着色器,但我猜这并不包含在你的(学校?)项目中。为此,对于初学者来说,您的方法应该完全没问题。
除了着色器之外,如果您想进一步进步,您还可以朝着使用更通用的多边形< /a> 对象,只需存储顶点列表并将其与能够渲染由三角形组成的多边形的单独“渲染器”类相结合。代码如下所示:
当然,多边形可以有一些附加属性,如颜色、纹理、透明度等。您可以有一些更具体的多边形类,如
TriangleStrip
、TriangleFan等也。然后您需要做的就是在 OpenGL
Renderer
中编写一个通用的draw()
方法,该方法将能够设置所有状态并将顶点推送到渲染管道。Well, it also depends on how much time you have and what is required. Your approach is not bad, a little old-fashioned, though. Modern OpenGL uses shaders, but I this is not covered by your (school?) project, I guess. For that purpose, and for starters, your approach should be completely OK.
Besides shaders, if you wanted to progress a little further, you could also go in the direction of using more generic polygon objects, simply storing a list of vertices and combine that with a separate 'Renderer' class that would be capable of rendering polygons, consisting of triangles. The code would look like this:
Of course, a polygon can have some additional attributes like color, texture, transparency, etc. You can have some more specific polygon classes like
TriangleStrip
,TriangleFan
, etc., also. Then all you need to do is to write a genericdraw()
method in your OpenGLRenderer
that will be able to set all the states and push the vertices to rendering pipeline.当我攻读博士学位时,我编写了一个模拟器,它可以完成你想做的事情。请记住,即使您的代码可能看起来是面向对象的,OpenGL 引擎仍然按顺序渲染事物。此外,矩阵代数的顺序性质(在 OpenGL 中)有时与您逻辑上认为的顺序不同(何时平移、何时绘制、何时旋转等?)。
还记得以前的LOGO吗?它有一只乌龟,它是一支笔,你移动乌龟,它就会画线。如果笔向下,则绘制,如果笔向上,则不绘制。这就是我在做这个项目时的心态。我会在熟悉的坐标 (0, 0, 0) 处启动“乌龟”,并使用数学来平移它(将其移动到我想要绘制的对象的中心),然后调用您的 draw() 方法正在尝试根据“乌龟”所在的相对坐标系来绘制我的形状,而不是绝对坐标系(0,0,0)。然后我会移动,乌龟,画画等等。希望有帮助......
When I was working on my PhD, I wrote a simulator which did what you wanted to do. Just remember that even though your code may look object oriented, the OpenGL engine still renders things sequentially. Also, the sequential nature of matrix algrebra, which is under the hood in OpenGL, is sometimes not in the same order as you would logically think (when do I translate, when do I draw, when do I rotate, etc.?).
Remember LOGO back in the old days? It had a turtle, which was a pen, and you moved the turtle around and it would draw lines. If the pen was down, it drew, if the pen was up, it did not. That is how my mindset was when I worked on this program. I would start the "turtle" at a familiar coordinate (0, 0, 0), and use the math to translate it (move it around to the center of the object I want to draw), then call the draw() methods you are trying to write to draw my shape based on the relative coordinate system where the "turtle" is, not from absolute (0, 0, 0). Then I would move, the turtle, draw, etc. Hope that helps...
不,它不会这样工作。问题是 GLUT Display 函数恰好是一个函数。因此,如果你想绘制一堆三角形,你仍然可以只将它们的一个draw()函数注册为GLUT显示函数。 (此外,C++ 中指向成员函数的指针也是一个难题)。
因此,如上所述,选择专用的 Renderer 类。该类将了解应用程序中的所有可绘制对象。
然后,您的 GLUT 显示函数将是一个静态函数,它在(全局或非全局)渲染器对象上调用 drawAllObjects() 。
No, it won't work like this. The problem is that the GLUT Display function is exactly one function. So if you wanted to draw a bunch of triangles, you could still only register one of their draw() functions to be the GLUT display function. (Besides, pointers to member functions in C++ are a hard topic as well).
So as suggested above, go for a dedicated Renderer class. This class would know about all drawable objects in your application.
Your GLUT display function would then be a static function that calls drawAllObjects() on a (global or not) renderer object.
啊,古老的即时模式 OpenGL。 :) 那个例程看起来不错。
不过,我可能会将“draw”方法设为虚拟,并从指定此类类所具有的方法的“Drawable”基类型继承。
Ah, good old immediate-mode OpenGL. :) That routine there looks fine.
I would probably make the 'draw' method virtual, though, and inherit from a 'Drawable' base type that specifies the methods such classes have.