OpenGL Selection Using Unique Color IDs

本文介绍了一种使用唯一颜色ID进行对象选择的技术,适用于OpenGL和DirectX应用。通过为每个对象分配独特的颜色,并读取鼠标位置的颜色信息来确定被选中的对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Introduction

There are a number of ways object selection can be performed. Using OpenGL you can use the special Selection Buffer, which allows you to select objects in the scene having unique ID's preassigned to them. A tutorial demonstrating this method can be found here: OpenGL:Tutorials:Picking

But there is another method. This method can not only be applied to OpenGL apps, but to DirectX apps as well. For the sake of this tutorial, the code given below will be using OpenGL.

[ edit]

How It Works

Essentially the way this method works, is that each object in our world is assigned a unique color. Since we're using a 24bit color scheme, this means we can have A LOT of objects with unique colors. If we wish to find out which object the user has clicked, we simply do the following:

  • Render the scene with textures, lighting, fog turned off
  • Render each object using its unique color
  • Read back data from the color buffer at the current mouse position
  • Search through the list of objects looking for a color ID match
  • If we find one, we have a selection

 

This is extremely simple to implement and is not API dependent.

So the first thing we must do is declare a base class for every object in our world. This base class must take care of initializing every object's colorID. It does this by declaring a static variable in the class, gColorID[3], and setting it to the color black, (0, 0, 0). From there, each time an object is created, gColorID is incremented. The first component, or red color channel, is incremented first, and when it reaches a value of 255, it is reset back to 0 and the second component, or green channel, is incremented. The same goes for the third, or blue channel.

 

Now every class we declare in our game or app should be derived from this base class. So suppose we wish to declare a Scene Object class. This class should be derived from the Base Object class and, depending on our implementation, you can simply insert a function to render the object only using its colorID. Hence in the example code below the only function of the function Picking() is to render the scene object with a solid color, specifically the object's colorID color.

 

Now as stated before we need to turn off texturing, lighting and fog before doing any of this. We also probably only want to perform object selection when a mouse button is pressed. So in the event of a mouse button being pressed, we render every object in the scene to the color buffer, read back the color information and search through our object list.

 

And that's it! Its extremely fast, depending on how many objects you have in the scene. It is API independent and is fairly straightward to implement. If for some crazy reason you feel that only using 24bits is not enough for how many objects you have in your world, then simply add an alpha channel to each object's colorID. Then when calling glReadPixels, you would change GL_RGB to GL_RGBA.

 

Also, some of you may be wondering why for the y - coordinate of glReadPixels, we passed in

 

This is because of the way OpenGL sets up the viewport, specially the lower left is the origin. Since in Windows the upper left is the origin, we must subtract the y mouse coordinate from the height of the viewport to get the correct OpenGL y coordinate.

 

To see this technique in action you can run the terrain editing software, Freeworld3D. This software uses this technique, not only for object selection, but also for Axis selection when translating, rotating and scaling objects. This is a very powerful and flexible way of handling object selection.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值