开发者

Nested scissor boxes with OpenGL

I am working on an OpenGL-based UI written in C. I have a hierarchy of controls -- small square 2D boxes inside a scrollable region of a bigger control. Inside the small boxes 3D scenes are drawn. The 3D scene must be scissored within the small 2D boxes and the small 2D boxes must be scissored within the larger region.

glScissor() is an obvious candidate for making sure drawing takes places within the desired region. The problem is that I cannot simultaneously call glScissor() for the large region and then call glScissor() again for subregions inside the larger scissored region.

Example code to demonstrate what I want:

void drawBigBox() {
    glScissor( ... ); //set the bounds of the larger region
    for each little box {
        //these mig开发者_开发问答ht be anywhere, but they should only be visible if inside the glScissor bounds
        drawLittleBoxes(); 
    }
}

void drawLittleBoxes() {
    //draw only inside little box -- Whoops! This replaces the big box bounds!
    //How can I meet this constraint while retaining the outer scissor region?
    glScissor( ... );
    draw3dScene();
}

Is there a simple way of doing what I want? Obviously I can also calculate the intersection of the small and large scissor boxes, or I could more carefully clip/project my 3D scene, but that is more complicated than an OpenGL call. Perhaps there is another approach to doing this that I am unaware of.

Thanks!


For this it is probably easier to use the stencil buffer. You can use INCR to increase the stencil buffer values when writing a quad to it, and when drawing you set the test to EQUAL or GEQUAL to only write where the stencil buffer has the highest value, thus it will only write in the region constrained by all current clipping regions. To remove them when drawing an hierarchy use DECR to remove them again. This way you can also have non rectangular clipping regions.


You could try to rely on glPush/PopAttribs calls to save and restore the scissor state. However, that was removed in 3.1, and the stack for attributes may not be as large as you need. So you should use an explicit stack.

Just make some object that you use to set the current scissor state. Each layer as you go down the call stack pushes its scissor state, which uses an actual stack of scissor rectangles. I have a generalized version of this that also pushes transform matrices, blend parameters, and so forth.

The object either has to be global GUI state, or bundled with some object that you pass to each of the functions.


You can get the coordinates of the current scissor box (either to save them, or to calculate their intersection with another region) using glGet() with the GL_SCISSOR_BOX parameter.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜