Problem with glScissor test.

Hi, I draw guis in several panels, I’ve made a test if the gui is not entierly in the panel I don’t draw it.
But if the gui intersects the border of the panel, I want to draw the part of the gui which is in the panel.
I tried to use glScissor.


void draw(RenderTarget& target, RenderStates states) {                
                glCheck(glEnable(GL_SCISSOR_TEST));
                glCheck(glScissor(getPosition().x, getPosition().y,getSize().x,getSize().y));
                onDraw(target, states);
                std::multimap<int, LightComponent*, std::greater<int>> sortedChildren;
                for (unsigned int i = 0; i < children.size(); i++) {
                    sortedChildren.insert(std::make_pair(children[i]->getPriority(), children[i].get()));
                }
                std::multimap<int, LightComponent*, std::greater<int>>::iterator it;
                for (it = sortedChildren.begin(); it != sortedChildren.end(); it++) {
                    if (it->second->isVisible() && it->second->getPosition().x + it->second->getSize().x >= getPosition().x && it->second->getPosition().y  + it->second->getSize().y >= getPosition().y
                    && it->second->getPosition().x <= getPosition().x + getSize().x
                    && it->second->getPosition().y <= getPosition().y + getSize().y) {
                        it->second->draw(target, states);
                    }
                }
                drawOn(target, states);
                glCheck(glDisable(GL_SCISSOR_TEST));
            }

But even if the gui is inside the panel it doesn’t draw it.
And it seems that sometimes panels are even not drawn!
position and size are the position and the size of the panel.
children[i]->position and children[i]->size are the guis that I draw on the panel.
But I’ve a question what is the system coordinates of opengl ? Is the top left corner with have 0 as y position or is it the bottom left corner ?
PS : hum it seems that it’s exactly the same coordinates as the windows I displayed the values with getIntegerv from one panel : (0, 10, 200, 700) but nothing is drawn inside that area…

I know what I’ll doing, I’ll use a shader to test if gl_FragCoord.xy i sinside the area but is gl_FragCoords.xy in window coordinates ?

The y axis is inverted so I had to do this :

glCheck(glScissor(getPosition().x, -getPosition().y,getSize().x,getSize().y));

So if I want to draw from 10 to 700 for y I have to set -10, 700 because -10 + 700 = 690.

I’ve tested a simple code and it works but when I want to draw the rectangle here :


void Panel::onDraw(RenderTarget& target, RenderStates states) {
                rect.setPosition(getPosition());
                rect.setSize(getSize());
                target.draw(rect);
                for (unsigned int i = 0; i < sprites.size(); i++) {
                    target.draw(sprites[i], states);
                }
                for (unsigned int i = 0; i < shapes.size(); i++) {
                    target.draw(*shapes[i], states);
                }
            }


glCheck(glEnable(GL_SCISSOR_TEST));
                glCheck(glScissor(getPosition().x, -getPosition().y,getSize().x,getSize().y));
                GLint* params = new GLint[4];
                glGetIntegerv(GL_SCISSOR_BOX, params);
                if (name == "PPROJECTS") {
                    for (unsigned int i = 0; i <  4; i++)
                        std::cout<<"param : "<<i<<" : "<<params[i]<<std::endl;
                }
                onDraw(target, states);

It doesn’t work…, I really doesn’t understand because the rectangle drawn here :


RenderWindow window(sf::VideoMode(1200, 700), "Scissor test");
    window.getView().move(600, 350, 0);
    RectangleShape rect(Vec3f(1200, 700, 0));
    RectangleShape rect2(Vec3f(200, 700, 0));
    rect2.setPosition(Vec3f(0, 10, 0));
    std::cout<<"rect pos : "<<rect2.getPosition()<<" rect size : "<<rect2.getSize()<<std::endl;
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }
        }
        window.clear();

        //window.draw(rect);
        glEnable(GL_SCISSOR_TEST);
        glScissor(0, -10, 200, 700);
        window.draw(rect2);
        glDisable(GL_SCISSOR_TEST);
        window.display();
    }
    return 0;

It works but when I want to draw the rect in the Panel class it doesn’t work anymore and THE TWO RECT HAVE THE SAME COORDINATES AND THE SCISSORS PARAMETER ARE THE SAME!!! :mad:

I know! draw is called recursively. So it redefines the scissor box each time I draw a child or I don’t want that!

Ok I’ve found the solution :


void Panel::onDraw(RenderTarget& target, RenderStates states) {
                rect.setPosition(getPosition());
                rect.setSize(getSize());
                glCheck(glEnable(GL_SCISSOR_TEST));
                glCheck(glScissor(getPosition().x, getWindow().getSize().y - (getPosition().y + getSize().y), getSize().x, getSize().y));
                target.draw(rect, states);
                for (unsigned int i = 0; i < sprites.size(); i++) {
                    target.draw(sprites[i], states);
                }
                for (unsigned int i = 0; i < shapes.size(); i++) {
                    target.draw(*shapes[i], states);
                }
            }
            void Panel::drawOn(RenderTarget& target, RenderStates states) {
                if (scrollX || scrollY) {
                    target.draw(corner, states);
                }
                if (scrollX) {
                    target.draw(vertScrollBar, states);
                }
                if (scrollY) {
                    target.draw(horScrollBar, states);
                }
                glDisable(GL_SCISSOR_TEST);
            }


void draw(RenderTarget& target, RenderStates states) {
                //states.transform = getTransform();
                /*shadScissor->setParameter("winSize",getWindow().getSize().x, getWindow().getSize().y);
                shadScissor->setParameter("componentPos", getPosition().x, getPosition().y);
                shadScissor->setParameter("componentSize",getSize().x,getSize().y);
                states.shader = shadScissor.get();*/
                onDraw(target, states);
                std::multimap<int, LightComponent*, std::greater<int>> sortedChildren;
                for (unsigned int i = 0; i < children.size(); i++) {
                    sortedChildren.insert(std::make_pair(children[i]->getPriority(), children[i].get()));
                }
                std::multimap<int, LightComponent*, std::greater<int>>::iterator it;
                for (it = sortedChildren.begin(); it != sortedChildren.end(); it++) {
                    if (it->second->isVisible()
                        && it->second->getPosition().x + it->second->getSize().x >= getPosition().x
                        && it->second->getPosition().y + it->second->getSize().y >= getPosition().y
                        && it->second->getPosition().x <= getPosition().x + getSize().x
                        && it->second->getPosition().y <= getPosition().y + getSize().y) {
                        /*if(name == "PFILES" && it == sortedChildren.begin()) {
                            std::cout<<"child pos : "<<it->second->getPosition()<<" child size : "<<it->second->getSize()<<std::endl;
                        }*/
                        it->second->draw(target, states);
                    }
                }
                drawOn(target, states);
            }

But now I’ve another problem when I use glScissor in a subwindow, scissor also hide the content of the main window.

The scissor rectangle affects all rendering performed while it’s active. Any changes to the scissor rectangle (or its enabled state) persist until changed. So if you want to change it temporarily, you need to change it back afterwards.

I’ve found why, the opengl context wasn’t activated when I drawed on the other window :

[code=cpp]
void draw(RenderTarget& target, RenderStates states) {
//states.transform = getTransform();
getWindow().setActive(true);
if (getWindow().getName() == “WAPPLICATIONNEW”) {
GLboolean* params = new GLboolean[1];
glGetBooleanv(GL_SCISSOR_TEST, params);
if (params[0] == GL_TRUE)
std::cout<<getWindow().getName()<<" true"<<std::endl;
else
std::cout<<getWindow().getName()<<" false"<<std::endl;
}
onDraw(target, states);
std::multimap<int, LightComponent*, std::greater<int>> sortedChildren;
for (unsigned int i = 0; i < children.size(); i++) {
sortedChildren.insert(std::make_pair(children[i]->getPriority(), children[i].get()));
}
std::multimap<int, LightComponent*, std::greater<int>>::iterator it;
for (it = sortedChildren.begin(); it != sortedChildren.end(); it++) {
if (it->second->isVisible()
&& it->second->getPosition().x + it->second->getSize().x >= getPosition().x
&& it->second->getPosition().y + it->second->getSize().y >= getPosition().y
&& it->second->getPosition().x <= getPosition().x + getSize().x
&& it->second->getPosition().y <= getPosition().y + getSize().y) {
/if(name == “PFILES” && it == sortedChildren.begin()) {
std::cout<<"child pos : “<<it->second->getPosition()<<” child size : "<<it->second->getSize()<<std::endl;
}
/
it->second->draw(target, states);
}
}
drawOn(target, states);
}



So GL_SCISSOR_TEST value changed alone (GL_TRUE, GL_FALSE)...