我有一个用 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;
}
虽然文件在它指向的文件中?