Learn to draw OpenGL primitives

 

Drawing OpenGL Primitives using glVertex command is simple. This tutorial will explain drawing every possible type of primitive in OpenGL except points and lines because they are trivial to understand. If you are still a bit uncertain, please see my previous OpenGL tutorial for an example of how it is done. I will start with polygons because this is the next type of a primitive on the complexity scale after lines. But before I do I need to mention one important point. If you're making a jump from 2D graphics to 3D like many people do, you need to completely forget about the 2D coordinate system. It's time to think in 3D, which can be a little frustrating in the beginning. To refresh your memory here is the coordinate system that OpenGL uses which is the 3D Cartesian Coordinate System.

 

Remember that when OpenGL is initialized and the projection is set up we are initially looking down the negative Z space as seen on the image above. The point x=0, y=0, z=0 is in the exact center of the screen. Keep this image in your head when you write primitive-rendering code. Before we continue, I'd like to point out that I have learned much of this from  some of these OpenGL books, available at other sites like Amazon and/or Barnes and Nobles.

Open up my OpenGL base code and bring up glmain.cpp into the main view. That's where the function RenderFrame is located. This function executes once per frame or a single run through the main execution loop. Here you will usually want to draw everything and process the rest of your program. Since we are only practicing to draw primitives, you will only use this function to merely display some simple stuff.

Initially, the base code has a single line in that function referring to clearing the contents of the video and depth buffers. This call should generally be there before you add any drawing code since it clears the back (video) buffer as well as the depth buffer; just think of it as clearing the screen to start drawing "from scratch". The reason you clear the depth buffer is that there might be some garbage from the previous frame and you wouldn't want it there. The video buffer clear color is specified by the function glClearColor which is called during initialization. Its parameters specify the R G B and A (alpha) values of the clearing color. How they are specified is the topic of the next tutorial entitled "Colors" and you shouldn't be bothered by it at this point. Just think about it as when you pass all parameters as 0.0f, the clear color is black. Also note that by default, all primitives' color is white even if you don't specify their color (which we won't for now, and which is also one of the topics of the next tutorial where I explain how to add some color to your primitives). In this tutorial we will be constrained to drawing plain white primitives.

Well, it's time to draw something on the screen. You're about to draw your first polygon! Type the following lines inside the RenderFrame function after the call to glClear.



void RenderFrame (void)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


glBegin(GL_TRIANGLES);

glVertex3f(-1.0f, -0.5f, -4.0f);    // lower left vertex
glVertex3f( 1.0f, -0.5f, -4.0f);    // lower right vertex
glVertex3f( 0.0f,  0.5f, -4.0f);    // upper vertex

glEnd();

}

Compile and run the program. You should see a white polygon centered on the screen with given coordinates. Note that the z value is always -4.0f, this means the triangle is drawn a little further into the screen, otherwise it would be too close to the camera. This glBegin-glEnd sequence can be used to create any other type of primitives. In this example, if you change the GL_ TRIANGLES flag to, say, GL_POINT you will see 3 points positioned at the ending points of the triangle. Try it. If you specify the GL_TRIANGLES flag and list 4 vertices instead of required 3, the last vertex will be ignored. However, if you specify 6 vertices, TWO triangles will be rendered. Here's an example of drawing two triangles. Add 3 more vertices to the list you already have as in the following example:


glBegin(GL_TRIANGLES);

glVertex3f(-1.0f, -0.5f, -4.0f);    // lower left vertex
glVertex3f( 1.0f, -0.5f, -4.0f);    // lower right vertex
glVertex3f( 0.0f,  0.5f, -4.0f);    // upper vertex

glVertex3f(-0.5f, -1.5f, -4.0f);
glVertex3f( 0.5f, -1.5f, -4.0f);
glVertex3f( 0.0f, -1.0f, -4.0f);

glEnd();

Recompile this code and run it. One more, smaller triangle appears at the bottom of the first one. As you can see this way you can save time on glBegin and glEnd calls and draw multiple triangles using only one glBegin and one glEnd calls. This is true for all primitives. Say you want to draw 3 lines, then you will specify GL_LINES as the parameter of glBegin and specify 6 vertices one by one. Each 2 vertices in a consequent order will specify the starting and ending points of the 3 lines. Same goes for the rest of primitives specified by following flags: GL_POINTS, GL_LINES, GL_TRIANGLES, GL_QUADS, GL_POLYGON. Just apply the same rules when using glBegin with these flags to draw points, lines, triangles, quads and n-sided polygons.

STRIPS

As you can imagine a call to glVertex takes some time to process. It is possible to minimize the number of calls to glVertex while drawing the same amount of primitives be it a line or a triangle or a quad. For this purpose there are 3 additional flags which are

GL_LINE_STRIP
GL_TRIANGLE_STRIP
GL_QUAD_STRIP

These types of rendering can greatly increase performance of large models! I will demonstrate only one type of strips in theory - GL_TRIANGLE_STRIP. The same rules will apply to the other two types of strips, only with a different number of vertices. Let's take a look at this image generated by following code.

 
And here's the according code to generate this image:

glBegin(GL_TRIANGLE_STRIP);

glVertex3f(-1.0f, -0.5f, -4.0f);    // A
glVertex3f( 1.0f, -0.5f, -4.0f);    // B

glVertex3f( 0.0f,  0.5f, -4.0f);    // C
glVertex3f(1.5f,  0.0f, -4.0f);     // D
glVertex3f(2.0f, -1.5f, -4.0f);     // E

glEnd();

Compare coordinates of this code with the corresponding image above; I named vertices with letters A through E to make it easier to compare the code with the visual output and also connected them with red lines so you can see the triangles. You see, when you will get to the point of creating 3D objects out of triangles, you will realize that many triangles share the same vertices. These points would normally be listed as separate vertices, with the same coordinates. But why call glVertex twice? This is the whole point of primitive strips. To initialize a triangle strip you will need to at least specify one initial triangle. In the example above, this triangle is ABC. From then on, as you add new vertices (D and E), you add a new triangle to the "strip" with only ONE vertex. And this is the idea behind triangle strips. This technique can also be applied to both line strips and quad strips. Using this technique can improve the speed of your 3D model rendering loops. With only 5 calls to glVertex you can make 3 triangles.

LINE LOOPS

Another unique type of rendering is called a line loop. You cannot create triangle loops or quad loops. This will only work with lines. The flag you will use to generate it is GL_LINE_LOOP. A line loop is the same thing as a line strip. The only difference is that the last and the first vertices specified in the list are also connected.

FANS

The next and the last type of rendering triangles are fans. Fans also can only be used with triangles and no other type of primitive and are identified by the GL_TRIANGLE_FAN flag. A triangle fan has one origin indicated by the first vertex, and an initial triangle, indicated by the first 3 vertices including the origin. As you add the 4th and 5th vertices to you fan, you continue it just like you did with a triangle strip. The difference is that all consequent triangles are tied to one origin point and do not extend into a line (or a strip) of triangles. Here is an example of a triangle fan and code to generate it.

 



glBegin(GL_TRIANGLE_FAN);

glVertex3f(-1.0f, -0.5f, -4.0f);    // A
glVertex3f( 1.0f, -0.5f, -4.0f);    // B
glVertex3f( 0.0f,  0.5f, -4.0f);    // C

glVertex3f(-1.5f,  0.0f, -4.0f);    // D
glVertex3f(-1.8f, -1.0f, -4.0f);    // E
glVertex3f( 0.2f, -1.5f, -4.0f);    // F

glVertex3f( 1.0f, -0.5f, -4.0f);    // G

glEnd();

A triangle fan doesn't have to be closed as in this example, just remember that all triangles in a triangle fan share the same vertex which is the origin. As you see here, with only 7 calls to glVertex it was possible to create FIVE triangles as opposed to 6 vertices per 2 triangles when using GL_TRIANGLES flag. The limitation of this is of course that you cannot have a whole model made out of ONE triangle fan because it only has one origin! To use this type of rendering you need to parse the model data in a special way. Well this seems to cover all types of rendering primitives. I didn't demonstrate drawing quads (GL_QUADS) but it is trivial to understand; as I said before, just follow the same rules. There is no source code for this tutorial, just remember all possible flags and practice, practice, practice.

Give this page to your friends

If the content on this website somehow helped you to learn something new, please let others know about it by sharing it on your Facebook page with your friends. In addition you can help by making a donation, bookmarking the site or subscribing to the Website Homework newsletter to receive occasional emails related to what you have just read on this page.

 

 

Source from:http://www.falloutsoftware.com

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值