1

我有一个用 C++、openGL 和 SFML 设置的基本游戏。

但是当我尝试在屏幕上添加文本或绘制正方形(对于 GUI)时,屏幕主要变黑,我可以看到左上角发生了一些事情,但我不知道是什么

我在控制台中收到此错误:

RenderTarget.cpp<362> 中的内部 OpenGL 调用失败:GL_INVLAD_OPERATION,当前状态下不允许指定的操作

这是完整的代码:

#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);
}

在我的 init 函数中,我只需像这样设置文本属性:

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

text 在我的头文件中声明为 sf::Text 文本。

我看不出文本不打印到屏幕上的任何原因!

编辑 好的,所以我查看了整个推送和弹出 openGL 状态并按照线程上所示实现了它,我现在得到了这个图像!:

医学

所以我到了那里,你可以看到这个问题是播放器不再显示并且输入都搞砸了:/

这是更新的循环:

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();


}
    }

关于加载字体,我已经实现了它,但由于某种原因,无法使用以下代码找到字体:

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

虽然文件在它指向的文件中?

4

1 回答 1

3

1:如果您为该 sf::Text 设置的 sf::Font (我假设您必须拥有)超出范围,它将不会显示它,因为它的字体参考已经消失。

2:如果您有另一个线程正在运行(可能显示您的风景)并且您设置了 App.setActive() 另一个线程会自动停用

3:如果你在它们之间切换,openGL 状态有时会与 SFML 冲突。保存它们,用 SFML 绘制,恢复它们,然后你可以恢复 openGL 绘制。

希望这有所帮助。

哦,嘿,看看这个精彩的页面: http ://www.sfml-dev.org/tutorials/2.0/window-opengl.php

于 2013-04-19T15:59:09.913 回答