【发布时间】:2016-12-28 15:51:25
【问题描述】:
我对 C++ 还很陌生,所以我希望在这里能得到一些帮助。 我尝试将我的游戏引擎移植到 C++,但 C++ 的行为有点……“奇怪”。 以下情况:
如果我运行 test1() 一切正常。
main.cpp
#include <iostream>
#include "../headers/base.h"
#include "../headers/DemoGame.h"
#include "../headers/TestShader.h"
using namespace std;
using namespace engine;
void run(TestShader* t, GLuint VAO, GLFWwindow* w)
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(t->progID);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(w);
}
void test1()
{
Window w = Window(800, 600, "test");
TestShader t = TestShader();
GLuint VAO, VBO;
GLfloat vertices[9] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while (!glfwWindowShouldClose(w.getWindow()))
{
run(&t, VAO, w.getWindow());
}
}
void test2()
{
DemoGame game = DemoGame();
game.start();
}
int main()
{
test1();
return 0;
}
如果我使用以下涉及的类运行 test2():
Engine.h
#pragma once
#ifndef H_ENGINE
#define H_ENGINE
#include "base.h"
namespace engine
{
class Engine
{
private:
bool running;
public:
void start()
{
init();
process();
}
void stop()
{
this->running = false;
}
private:
void process()
{
update();
}
public:
virtual void init() = 0;
virtual void update() = 0;
virtual void render() = 0;
virtual void terminate() = 0;
};
}
#endif
DemoGame.h
#pragma once
#ifndef DEMO_DEMO_GAME
#define DEMO_DEMO_GAME
#include "base.h"
#include "Window.h"
#include "Engine.h"
#include "TestShader.h"
using namespace engine;
class DemoGame : public Engine
{
public:
Window* w;
TestShader* t;
GLuint VBO, VAO;
public:
DemoGame() : Engine() { }
public:
void init();
void update();
void render();
void terminate();
};
#endif
DemoGame.cpp
#include "../headers/DemoGame.h"
#include <iostream>
using namespace std;
void DemoGame::init()
{
cout << "ping" << endl;
Window wi = Window(800, 600, "test");
w = &wi;
TestShader te = TestShader();
t = &te;
GLfloat vertices[9] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while (!glfwWindowShouldClose(w->getWindow()))
{
render();
}
}
void DemoGame::update()
{
}
void DemoGame::render()
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(t->progID);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(w->getWindow());
}
void DemoGame::terminate()
{
}
它也有效。但正如您所见,Engine.h 应该控制主循环。如果我稍微更改一下代码:
Engine.h
#pragma once
#ifndef H_ENGINE
#define H_ENGINE
#include "base.h"
namespace engine
{
class Engine
{
private:
bool running;
public:
void start()
{
init();
running = true;
while (running)
{
process();
}
}
void stop()
{
this->running = false;
}
private:
void process()
{
update();
}
public:
virtual void init() = 0;
virtual void update() = 0;
virtual void render() = 0;
virtual void terminate() = 0;
};
}
#endif
DemoGame.cpp
#include "../headers/DemoGame.h"
#include <iostream>
using namespace std;
void DemoGame::init()
{
cout << "ping" << endl;
Window wi = Window(800, 600, "test");
w = &wi;
TestShader te = TestShader();
t = &te;
GLfloat vertices[9] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void DemoGame::update()
{
render();
}
void DemoGame::render()
{
glfwPollEvents();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(t->progID);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(w->getWindow());
}
void DemoGame::terminate()
{
}
现在突然间我收到“访问冲突”。问题是为什么? 文件“base.h”只包含
#define GLEW_STATIC
#include "GL/glew.h"
#include "GLFW/glfw3.h"
Window 和 TestShader 类无关紧要,因为它们在前两个示例中有效。正如我之前所说,我对 C++ 很陌生,我只是不明白为什么这不起作用。你能帮我找出至少为什么这不起作用或更好地帮助我解决问题吗?
这是我第二次尝试通过发布问题从 StackOverflow 获得有用的答案。请帮我一个忙。在将此问题标记为重复之前,请考虑阅读情况。上次它不是重复时,问题就大不相同了。
编辑
根据要求提供错误消息(对不起,我在工作,所以语言是德语)
GLFWGame.exe 中的 Ausnahme ausgelöst bei 0x0126489D:0xC0000005: Zugriffsverletzung beim Lesen an Position 0xCCCCCEA4.
Falls ein Handler für dieese Ausnahme vorhanden ist, kann das Programm möglicherweise weiterhin sicher ausgeführt werden。
我会尽量缩短代码到最重要的部分。
【问题讨论】:
-
调试器是解决此类问题的正确工具。 在询问 Stack Overflow 之前,您应该逐行浏览您的代码。如需更多帮助,请阅读How to debug small programs (by Eric Lippert)。至少,您应该 [编辑] 您的问题以包含一个重现您的问题的 Minimal, Complete, and Verifiable 示例,以及您在调试器中所做的观察。
-
你能贴出实际的错误信息吗?
-
据我所知,我很惊讶您在第一个测试用例中没有遇到“访问冲突”。您正在将指针设置为指向在 DemoGame::Init() 函数末尾超出范围的变量。这意味着它们会被清理并导致未定义的行为。