Advertisement Jump to content
Sign in to follow this  

OpenGL Multiple clipping planes

This topic is 3863 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am making a game using OpenGL (Visual C++, Windows) and i need to use multiple clipping planes. I use glScissor to clip a region of text within a GUI component (i.e. a label or textbox) and also to clip components within a container (i.e. window). How do i do both of these at the same time? Is it possible? Here is a screenshot showing how i have my GUI: EDIT: oh, i should mention how i am currently attempting to do it. See, i create an OpenGL display list for each GUI component (button, label, etc) and call that dl when i want to draw the component. I do this mainly because i only need to create the image when and if the component changes position or size. So i thought i could clip the text on a TextBox when i create the display list for it. And then when i draw the TextBox on the container in my screenshot, the image created by the dl would be clipped to the container. But that doesn't quite work. Here is some of my code:
//// TextField.cpp ///////////////////

/* Updates the component's image when one of it's properties changes */
void TextField::update() {
    // Create display lists to draw the image

    const int textSize = (int)(height*TEXT_FIELD_SIZE);
    const int textY = (int)(height/2.0f - textSize/2.0f);

    // Clip text to component edge
    clipRect(getAbsX()+TEXT_FIELD_PADDING_X, getAbsY(),
             width-(2*TEXT_FIELD_PADDING_X), height);
    printText(x+TEXT_FIELD_PADDING_X, y+textY, text, font, textSize);

    hasChanged = false;

void TextField::draw() {
    if (hasChanged) update();  // Update image if need be

    int cxPos = x + getCharCoord(cursorPos);
    int sxPos = x + getCharCoord(selectPos);
    if (cxPos > width) cxPos = width;
    if (sxPos > width) sxPos = width;
    if (cursorPos == selectPos)
        drawLine(cxPos, y + TEXT_FIELD_PADDING_Y,
                 cxPos, y + height - TEXT_FIELD_PADDING_Y); // Draw cursor
    else {
        if (cursorPos > selectPos)     // Draw selection
            fillRect(sxPos, y + TEXT_FIELD_PADDING_Y,
                     cxPos-sxPos, height-(2*TEXT_FIELD_PADDING_Y));
            fillRect(cxPos, y + TEXT_FIELD_PADDING_Y,
                     sxPos-cxPos, height-(2*TEXT_FIELD_PADDING_Y));

//// Container.cpp ////////////

void Container::draw() {
    // Clip to container bounds.
    clipRect(getAbsX(), getAbsY()+2, width, height);
    glTranslated(x + cX, y + cY, 0);   // Draw relative to container pos
    for (int i = 0; i < numComponents(); i++) {
        components->draw();         //### Draw each component in this container ###

    if (scrollBar) {
        glTranslated(x, y, 0);

/* Draws the currently active Window/Panel and any other visible */
/* components (i.e. a Panel behind another Panel)                */
void Container::drawScreen() {
    for (int i = MAX_SCREENS; i >= 0; i--) { // Draw first one last
        if (Component::visible)
            Component::visible->draw();  //### This draws the window shown in the screenshot ###

//// Graphics.h /////////////
inline void clipRect(int x, int y, int width, int height) {
    glScissor(x, y, width, height);
inline void disableClip() { glDisable(GL_SCISSOR_TEST); }

The textboxes (TextFields) in my screenshot are components in the Container, they are drawn in Container::draw(). I currently draw the screen in the WinMain loop (until i find a better way of doing it):
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR cmdLine, int wndState) {
    MSG msg;
    // Init stuff

    while(!appQuit) {
        if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
            if (msg.message==WM_QUIT) {
                appQuit = true;
            else {
        else {
            Container::drawScreen();  // Draw the screen

I haven't provided the code for the rest of my GUI (window code and stuff) but comments with ### explain what happens. [Edited by - XTAL256 on June 20, 2008 7:50:52 PM]

Share this post

Link to post
Share on other sites
i think youre over complicating things, overworrying but anyways
one possible method would be to use the stencil test
eg clear the stencil to 0, and set the window to 1, and the box to 2.
and then set it to only draw if the current stencil value of the pixel is > 0

also surely u only need to clip to one region at once? ie glScissor should be enuf

Share this post

Link to post
Share on other sites
Original post by zedz
i think youre over complicating things, overworrying but anyways...

I don't see any other way of doing it. Like i mentioned, i am clipping each component when i create a display list for them and then clipping when the display list is drawn (so i am only using glScissor once at a time, sort of) but that doesn't work. I will read up on how to do it the way you mentioned but i would really like to know how i would do it a simpler way.
btw, i am sort of a n00b at OpenGL which is why i am "overworrying" :)

[Edited by - XTAL256 on June 23, 2008 7:59:59 PM]

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using, you agree to our community Guidelines, Terms of Use, and Privacy Policy. is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!