系列文章目录
前言
如果使用GLFW,没有这句glfwPollEvents()程序崩溃
一、程序崩溃的地方找不到
运行openGL程序时,发现程序崩溃了,但又不知道具体是哪句代码引起的,怎么办呢?
二、解决步骤
1.vs2019中打开“诊断工具”窗口
2.在vs2019中打开“并行堆栈”窗口
查看在哪个线程中崩溃的
总结
最后在主线程中发现少了这句"
glfwPollEvents();
例子
#include "glew/glew.h"
#include "glfw/glfw3.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include "Torus.h"
#include "Utils.h"
#include "camera.h"
#include "SOIL2/SOIL2.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
static const float pai = 3.1415926f;
float toRadins(float degrees) { return degrees * 2.f * pai / (float)360.f; }
static const int screenWidth = 1920;
static const int screenHeight = 1080;
GLuint renderingProgram = 0;
static const int numVAOs = 1;
static const int numVBOs = 5;
float cameraX = 0.f, cameraY = 0.f, cameraZ = 0.f;
float torLocX = 0.f, torLocY = 0.f, torLocZ = 0.f;
GLuint vao[numVAOs] = { 0 };
GLuint vbo[numVBOs] = { 0 };
GLuint brickTexture = 0, skyboxTexture = 0;
float rotAmt = 0.f;
// variable allocation for display
GLuint mvLoc = 0, projLoc = 0;
int width = 0;
int height = 0;
float aspect = 0.f;
glm::mat4 mMat(1.f), vMat(1.f), pMat(1.f), mvMat(1.f);
Torus myTorus(0.5f, 0.2f, 48);
int numTorusVertices = 0, numTorusIndices = 0;
Camera camera(glm::vec3(0.f, 1.f, 4.f));
GLboolean keys[1024] = { GL_FALSE };
GLboolean b_firstMouse = GL_TRUE;
float deltaTime = 0.f;
float lastFrame = 0.f;
float lastLocX = 0.f;
float lastLocY = 0.f;
void do_movement()
{
if (keys[GLFW_KEY_W])
{
camera.ProcessKeyboard(FORWARD, deltaTime);
}
if (keys[GLFW_KEY_S])
{
camera.ProcessKeyboard(BACKWARD, deltaTime);
}
if (keys[GLFW_KEY_A])
{
camera.ProcessKeyboard(LEFT, deltaTime);
}
if (keys[GLFW_KEY_D])
{
camera.ProcessKeyboard(RIGHT, deltaTime);
}
/*if (keys[GLFW_KEY_ESCAPE])
{
glfwSetWindowShouldClose(window, GL_TRUE);
}*/
}
void key_press_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if ((key == GLFW_KEY_ESCAPE) && (action == GLFW_PRESS))
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
if (action == GLFW_PRESS)
{
keys[key] = GLFW_TRUE; //这里一定一定不能写成“==“,否则 按键WSAD按键失效!!!!!!!
}
else if (action == GLFW_RELEASE)
{
keys[key] = GLFW_FALSE; //这里一定一定不能写成“==“,否则 按键WSAD按键失效!!!!!!!
}
}
void mouse_move_callback(GLFWwindow* window, double xPos, double yPos)
{
if (b_firstMouse)
{
lastLocX = xPos;
lastLocY = yPos;
b_firstMouse = GL_FALSE;
}
float xOffset = xPos - lastLocX;
float yOffset = lastLocY - yPos;
lastLocX = xPos;
lastLocY = yPos;
camera.ProcessMouseMovement(xOffset, yOffset);
}
void mouse_scroll_callback(GLFWwindow* window, double xPos, double yPos)
{
camera.ProcessMouseScroll(yPos);
}
void setupVertices(void)
{
float cubeVertexPosition[108] =
{
-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f
};
float cubeTextureCoords[72] =
{
1.00f, 0.6666666f, 1.00f, 0.3333333f, 0.75f, 0.3333333f, // back face lower right
0.75f, 0.3333333f, 0.75f, 0.6666666f, 1.00f, 0.6666666f, // back face upper left
0.75f, 0.3333333f, 0.50f, 0.3333333f, 0.75f, 0.6666666f, // right face lower right
0.50f, 0.3333333f, 0.50f, 0.6666666f, 0.75f, 0.6666666f, // right face upper left
0.50f, 0.3333333f, 0.25f, 0.3333333f, 0.50f, 0.6666666f, // front face lower right
0.25f, 0.3333333f, 0.25f, 0.6666666f, 0.50f, 0.6666666f, // front face upper left
0.25f, 0.3333333f, 0.00f, 0.3333333f, 0.25f, 0.6666666f, // left face lower right
0.00f, 0.3333333f, 0.00f, 0.6666666f, 0.25f, 0.6666666f, // left face upper left
0.25f, 0.3333333f, 0.50f, 0.3333333f, 0.50f, 0.0000000f, // bottom face upper right
0.50f, 0.0000000f, 0.25f, 0.0000000f, 0.25f, 0.3333333f, // bottom face lower left
0.25f, 1.0000000f, 0.50f, 1.0000000f, 0.50f, 0.6666666f, // top face upper right
0.50f, 0.6666666f, 0.25f, 0.6666666f, 0.25f, 1.0000000f // top face lower left
};
numTorusVertices = myTorus.getNumVertices();
numTorusIndices = myTorus.getNumIndices();
vector<int> ind = myTorus.getIndices();
vector<glm::vec3> vert = myTorus.getVertices();
vector<glm::vec2> text = myTorus.getTexCoords();
vector<glm::vec3> norm = myTorus.getNormals();
vector<float> pValues;
vector<float> tValues;
vector<float> nValues;
for (int i=0; i<numTorusVertices; i++)
{
pValues.push_back(vert[i].x);
pValues.push_back(vert[i].y);
pValues.push_back(vert[i].z);
tValues.push_back(text[i].s);
tValues.push_back(text[i].t);
nValues.push_back(norm[i].x);
nValues.push_back(norm[i].y);
nValues.push_back(norm[i].z);
}
glGenVertexArrays(numVAOs, vao);
glBindVertexArray(vao[0]);
glGenBuffers(numVBOs, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
size_t cubeVertexPositionSize = sizeof(cubeVertexPosition);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertexPosition) * sizeof(float), cubeVertexPosition, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(cubeTextureCoords) * sizeof(float), cubeTextureCoords, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
glBufferData(GL_ARRAY_BUFFER, pValues.size() * sizeof(float), &pValues[0], GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);
glBufferData(GL_ARRAY_BUFFER, tValues.size() * sizeof(float), &tValues[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ind.size() * sizeof(int), &ind[0], GL_STATIC_DRAW);
}
void init(GLFWwindow* window)
{
renderingProgram = Utils::createShaderProgram("vertShader.vert", "fragShader.frag");
glfwGetFramebufferSize(window, &width, &height);
aspect = (float)width / (float)height;
pMat = glm::perspective(toRadins(45.f), aspect, 0.01f, 1000.f);
setupVertices();
brickTexture = Utils::loadTexture("brick1.jpg");
skyboxTexture = Utils::loadTexture("alien.jpg");
torLocX = 0.f, torLocY = -0.75f, torLocZ = 0.f;
cameraX = 0.f, cameraY = 0.f, cameraZ = 5.f;
}
void display(GLFWwindow* window, double currentTime)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0.f, 0.5f, 1.f, 1.f);
vMat = glm::translate(glm::mat4(1.f), glm::vec3(-cameraX, -cameraY, -cameraZ));
// draw cube map
glUseProgram(renderingProgram);
deltaTime = currentTime - lastFrame;
lastFrame = currentTime;
do_movement();
//这句必须要有,否则鼠标中键失效
pMat = glm::perspective(camera.Zoom, aspect, 0.01f, 1000.f);
//没有这句,背景就没在相机视点上了
mMat = glm::translate(glm::mat4(1.f), glm::vec3(cameraX, cameraY, cameraZ));
mMat = glm::rotate(mMat, glm::radians(35.f), glm::vec3(1.f, 0.f, 0.f));
mvMat = vMat * mMat;
vMat = camera.GetViewMatrix();
mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");
projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");
glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, skyboxTexture);
glEnable(GL_CULL_FACE); //开启剔除操作效果
//GL_CCW 表示窗口坐标上投影多边形的顶点顺序为逆时针方向的表面为正面。
//GL_CW 表示窗口坐标上投影多边形的顶点顺序为顺时针方向的表面为正面。
glFrontFace(GL_CCW);// cube is CW, but we are viewing the inside
glDisable(GL_DEPTH_TEST); //为了绘制背景天空盒,先关闭深度测试,时天空盒被物体遮挡
glDrawArrays(GL_TRIANGLES, 0, 36); //绘制立方体贴图
glEnable(GL_DEPTH_TEST);
// draw scene (in this case it is just a torus
glUseProgram(renderingProgram);
mvLoc = glGetUniformLocation(renderingProgram, "mv_matrix");
projLoc = glGetUniformLocation(renderingProgram, "proj_matrix");
mMat = glm::translate(glm::mat4(1.f), glm::vec3(torLocX, torLocY, torLocZ));
mMat = glm::rotate(mMat, toRadins(15.f), glm::vec3(1.f, 0.f, 0.f));
mvMat = vMat * mMat;
glUniformMatrix4fv(mvLoc, 1, GL_FALSE, glm::value_ptr(mvMat));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(pMat));
glBindBuffer(GL_ARRAY_BUFFER, vbo[2]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
//纹理layout(location = 1)
glBindBuffer(GL_ARRAY_BUFFER, vbo[3]);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, brickTexture);
glClear(GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glDisable(GL_LEQUAL);
glDrawArrays(GL_TRIANGLES, 0, 36);
glEnable(GL_DEPTH_TEST);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[4]);
glDrawElements(GL_TRIANGLES, numTorusIndices, GL_UNSIGNED_INT, 0);
}
void window_size_callback(GLFWwindow* window, int newWidth, int newHeight)
{
aspect = (float)newWidth / (float)newHeight;
glViewport(0, 0, newWidth, newHeight);
pMat = glm::perspective(toRadins(45.f), aspect, 0.01f, 1000.f);
}
int main(int argc, char** argv)
{
int glfwState = glfwInit();
if (GLFW_FALSE == glfwState)
{
cout << "GLFW initialize failed,invoke glfwInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_CORE_PROFILE, GLFW_OPENGL_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
GLFWwindow* window = glfwCreateWindow(screenWidth, screenHeight, "sky box simple", nullptr, nullptr);
if (!window)
{
cout << "GLFW create window failed,invoke glfwCreateWindow()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glfwSetWindowSizeCallback(window, window_size_callback);
glfwSetCursorPosCallback(window, mouse_move_callback);
glfwSetScrollCallback(window, mouse_scroll_callback);
glfwSetKeyCallback(window, key_press_callback);
int glewState = glewInit();
if (GLEW_OK != glewState)
{
cout << "GLEW initialize failed,invoke glewInit()......Error file:" << __FILE__ << "......Error line:" << __LINE__ << endl;
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwSwapInterval(1);
init(window);
while (!glfwWindowShouldClose(window))
{
display(window, glfwGetTime());
glfwSwapBuffers(window);
glfwPollEvents(); //如果没这句,程序直接挂了
}
glfwDestroyWindow(window);
glfwTerminate();
exit(EXIT_SUCCESS);
return 0;
}