Tom Burman
Tom Burman

Reputation: 957

Screen goes black when drawing to it SFML C++

I have a basic game set up in C++, openGL and SFML.

But then when i try to add text or draw a square to the screen(for the GUI) the screen goes mainly black, i can see something happens in the top left, but i don't know what

And i receive this error in the console:

An internal OpenGL call failed in RenderTarget.cpp<362> : GL_INVLAD_OPERATION, the specified operation is not allowed in the current state

Here is the full code:

#include "Engine.h"

static sf::RenderWindow App(sf::VideoMode(1600, 900, 32), "SFML OpenGL");

Engine::Engine()
{
    glewInit();
    c_player = Player(Vector3D(0, 14, 0), 0);
    c_enemy = Enemy(Vector3D(0, 14, -10), 0);
    c_gui = Gui(App);

    c_mouseSensitivityX = 5;
    c_mouseSensitivityY = 5;
}

Engine::~Engine(void)
{
}

void Engine::init(void)
{

     text.setString("Hello SFML");
     text.setCharacterSize(50);
     text.setPosition(10.0f, 10.0f);


    c_wall.LoadModel("Wall.dae");
    c_crates.LoadModel("crates.dae");
    c_cargoWall.LoadModel("cargoWall.dae");
    c_leftCorner.LoadModel("leftCorner.dae");
    c_rightCorner.LoadModel("rightCorner.dae");
    c_shipPipeWall.LoadModel("shipPipeWall.dae");
    c_shipWindow.LoadModel("shipWindow.dae");

    float posx = -200;
    float posfar = 200;
    float posnear = -200;

    /*for(int i = -200; i < 200 ; i += 20)
    {
        c_wallProperties.push_back(wallProps(Vector3D(i, 15, posfar), 0));
        c_wallProperties.push_back(wallProps(Vector3D(i, 15, posnear),0));
        c_wallProperties.push_back(wallProps(Vector3D(posfar, 15, i), 90));
        c_wallProperties.push_back(wallProps(Vector3D(posnear, 15, i),90));
    }*/

    int xflip = 1;

    for (int i=0; i<2; ++i)
    {
    c_wallProperties.push_back(wallProps(Vector3D(70 * xflip,15,20), 0));
    c_crateProperties.push_back(wallProps(Vector3D(55 * xflip,15,10), 0));
    //  //c_wallProperties.push_back(wallProps(Vector3D(40 * xflip,15,20), 0));
    //  ////c_wallProperties.push_back(wallProps(Vector3D(25 * xflip,15,20), 0));
    //  //c_wallProperties.push_back(wallProps(Vector3D(85 * xflip,15,20), 0));
    //  //c_wallProperties.push_back(wallProps(Vector3D(100 * xflip,15,20), 0));
    //  //c_wallProperties.push_back(wallProps(Vector3D(140 * xflip,15,20), 0));
    //  //c_wallProperties.push_back(wallProps(Vector3D(70 * xflip,15,-10), 0));
    //  //c_wallProperties.push_back(wallProps(Vector3D(55 * xflip,15,-10), 0));
    //  //c_wallProperties.push_back(wallProps(Vector3D(40 * xflip,15,-10), 0));
    //  ////c_wallProperties.push_back(wallProps(Vector3D(25 * xflip,15,-10), 0));
    //  //c_wallProperties.push_back(wallProps(Vector3D(85 * xflip,15,-10), 0));
    //  //c_wallProperties.push_back(wallProps(Vector3D(100 * xflip,15,-10), 0));
    //  c_wallProperties.push_back(wallProps(Vector3D(140 * xflip,15,-10), 0));

        xflip = xflip * -1;
    }

    //c_myModels.push_back(new buildings("rightCorner.dae",Vector3D(120,15,1)));
    ////c_myModels.push_back(new Objects("phoenix_ugv.md2", Vector3D(-50,0,20)));

    glClearDepth(1.f);
    glClearColor(0.f, 0.f, 0.f, 0.f);
    glEnable(GL_DEPTH_TEST);
    glDepthMask(GL_TRUE);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    GLfloat lightpos[] = {.5, 1., 1., 0.};
    glLightfv(GL_LIGHT0, GL_POSITION, lightpos);

    c_FPSClock.restart();

    ParticleSystem newParticle;
    newParticle.setMaxParticles(500);
    newParticle.setParticleColour(sf::Color(143, 44, 1, 255), sf::Color(255, 127, 39, 255));

    newParticle.setParticleLifespan(60, 180);
    newParticle.setParticleSpawnrate(0.2, 0.3);
    newParticle.setParticleVelocity(Vector3D(-10, 30, -10), Vector3D(10, 50, 10));
    newParticle.setParticleAcceleration(Vector3D(0, -9.81, 0), Vector3D(0, -9.81, 0));
    newParticle.setSpawnerPosition(Vector3D(0, 10, 0));

    c_particleSystems.push_back(newParticle);
}

void Engine::getInput(void)
{
    while (App.pollEvent(c_event))
    {
        // Close window : exit
        if (c_event.type == sf::Event::Closed)
            App.close();

        // Resize event : adjust viewport
        if (c_event.type == sf::Event::Resized)
            glViewport(0, 0, c_event.size.width, c_event.size.height);

        // Camera Controls
        if (c_event.type == sf::Event::KeyPressed)
        {
            switch (c_event.key.code)
            {
            case sf::Keyboard::Escape:
                App.close();
                break;
            case sf::Keyboard::W:
                c_player.move(Vector3D(0, 0, -1));
                break;
            case sf::Keyboard::S:
                c_player.move(Vector3D(0, 0, 1));
                break;
            case sf::Keyboard::A:
                c_player.move(Vector3D(-1, 0, 0));
                break;
            case sf::Keyboard::D:
                c_player.move(Vector3D(1, 0, 0));
                break;
            case sf::Keyboard::X:
                c_camera.togglePerspective();
                break;
            }
        }
    }
}

void Engine::run()
{
    while (App.isOpen())
    {
        while (c_FPSClock.getElapsedTime().asSeconds() < 1.f/60)
        {
        }

        // Set the active window before using OpenGL commands
        // It's useless here because active window is always the same,
        // but don't forget it if you use multiple windows or controls
        App.setActive();

        //App.draw(rectangle);
        // Clear color and depth buffer
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        getInput();
        update();
        render();
    }
}

void Engine::update(void)
{
    mouseMove();
    c_worldEngine.update();
    c_player.update();
    c_enemy.update();
    c_camera.update(c_player);





    for (vector<ParticleSystem>::iterator iter = c_particleSystems.begin(); iter != c_particleSystems.end(); ++iter)
    {
        iter->update();
    }
}

void Engine::render(void)
{
    c_camera.render();
    c_gui.render();
    c_worldEngine.render(c_camera.getPos());
    App.draw(text);

    for (vector<pair<Vector3D, float>>::iterator iter = c_wallProperties.begin(); iter != c_wallProperties.end(); ++iter)
    {
        glEnable(GL_TEXTURE_3D);
        glPushMatrix();
        glTranslatef(iter->first.x, iter->first.y, iter->first.z);
        glRotatef(iter->second, 0, 1, 0);
        c_wall.Render();
        glPopMatrix();
        glDisable(GL_TEXTURE_3D);
    }

    glPushMatrix();

    glEnable(GL_COLOR_MATERIAL);
    if (c_camera.isFirstPerson() == false)
    {
        c_player.render();
    }
    c_enemy.render();
    glDisable(GL_COLOR_MATERIAL);
    glPopMatrix();

    c_glModel.render(Vector3D(0,5,0));

    for (vector<ParticleSystem>::iterator iter = c_particleSystems.begin(); iter != c_particleSystems.end(); ++iter)
    {
        iter->render();
    }

    App.display();
    c_FPSClock.restart();
}

void Engine::mouseMove(void)
{
    sf::Vector2u winSize = App.getSize();
    sf::Vector2u winMid = sf::Vector2u(winSize.x/2, winSize.y/2);
    sf::Vector2i mousePos = sf::Mouse::getPosition(App);

    if ((mousePos.x == winMid.x) && (mousePos.y == winMid.y))
    {
        return;
    }

    sf::Mouse::setPosition(Vector2i(winMid.x, winMid.y), App);

    sf::Vector2i mouseDiff = sf::Vector2i(winMid.x - mousePos.x, winMid.y - mousePos.y);
    sf::Vector2f diffRatio = sf::Vector2f(mouseDiff.x / c_mouseSensitivityX, mouseDiff.y / c_mouseSensitivityY);

    if (c_camera.isFirstPerson())
    {
        diffRatio.y /= 10;
    }

    c_player.rotate(diffRatio.x);
    c_camera.rotateY(diffRatio.y);
}

In my init function i simply set the text properties like so:

text.setString("Hello SFML");
 text.setCharacterSize(50);
 text.setPosition(10.0f, 10.0f);

text is declared in my header file as sf::Text text.

I cant see any reason for the text not to be printed to the screen!

EDIT Ok so i looked into the whole pushing and popping openGL states and implemented it as shown on a thread and i now get this image!:

med

So im getting there, as you can see the problem with this is the player is no longer shown and the input is all messed up :/

Here is the updated loop:

void Engine::run()
   {
while (App.isOpen())
{
    while (c_FPSClock.getElapsedTime().asSeconds() < 1.f/60)
    {
    }


    App.pushGLStates();
    App.draw(text);
    App.popGLStates();

    // Set the active window before using OpenGL commands
    // It's useless here because active window is always the same,
    // but don't forget it if you use multiple windows or controls
    App.setActive();

    //App.draw(rectangle);



    // Clear color and depth buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();



    getInput();
    update();
    render();


}
    }

In regards to loading a font i have implemented it but for some reason the font cant be found with this code:

if(!font.loadFromFile("../arial.tff"))
{
    cout<<"no font"<<endl;
}

although the file is in the file it is directed at?

Upvotes: 1

Views: 1958

Answers (1)

Alexandra
Alexandra

Reputation: 56

1: if the sf::Font you set for that sf::Text (which i assume you must have) goes out of scope it wont display it, because its font reference is gone.

2: if you have another thread running (possibly displaying your scenery) and you set your App.setActive() the other thread is deactivated automagically

3: openGL states sometimes conflict with SFML if you're switching between them.. Save them, draw with SFML, restore them, then you can resume openGL drawing.

hope this helps a little.

oh and hey, look at this wonderful page: http://www.sfml-dev.org/tutorials/2.0/window-opengl.php

Upvotes: 3

Related Questions