C++ 四叉树程序导致死亡的蓝屏
我正在为一颗行星写一个四叉树结构,当你远离四叉树并靠近它时,它的细节会减少或增加。然而,我遇到了一些非常严重、令人讨厌的错误 我有两个预处理器定义的常量,它决定了四叉树的大小(四叉树宽度和四叉树高度),当我将值更改为32以外的任何值(例如16或64)时,我会得到一个蓝色的死亡屏幕。我使用code::blocks作为我的IDE,还有一件事:每当我尝试在code::blocks中调试程序时,我也会得到一个死亡蓝屏(不管常量是否为32) 为什么会这样?我怎样才能修好它。 PQuad.cppC++ 四叉树程序导致死亡的蓝屏,c++,opengl,c-preprocessor,quadtree,bsod,C++,Opengl,C Preprocessor,Quadtree,Bsod,我正在为一颗行星写一个四叉树结构,当你远离四叉树并靠近它时,它的细节会减少或增加。然而,我遇到了一些非常严重、令人讨厌的错误 我有两个预处理器定义的常量,它决定了四叉树的大小(四叉树宽度和四叉树高度),当我将值更改为32以外的任何值(例如16或64)时,我会得到一个蓝色的死亡屏幕。我使用code::blocks作为我的IDE,还有一件事:每当我尝试在code::blocks中调试程序时,我也会得到一个死亡蓝屏(不管常量是否为32) 为什么会这样?我怎样才能修好它。 PQuad.cpp #包含“.
#包含“.\include\PQuad.h”
#包括“.\include\Color3.h”
#包括
#包括
#包括
#包括
#包括
#包括
#定义四舍五入宽度32
#定义四舍五入高度32
#定义子项的数量4
#定义最大深度4
PQuad::PQuad(面方向面方向、浮动行星半径){
这个->构建=假;
此->球形化=错误;
此->面\方向=面\方向;
这个->半径=行星的半径;
这个->行星中心=glm::vec3(0,0,0);
}
PQuad::~PQuad(){
}
std::vector PQuad::get_children(){
返回儿童;
}
bool PQuad::get_Build(){
返回此->已构建;
}
int PQuad::get_depth(){
返回此->深度;
}
float*PQuad::get_table(){
回归树;
}
浮点PQuad::获取元素宽度(){
返回元素的宽度;
}
glm::vec3 PQuad::获取位置(){
返回位置;
}
glm::vec3 PQuad::get_中心(){
返回中心;
}
void PQuad::get_recursive(glm::vec3播放器位置、std::vector和out_子项){
对于(size_t i=0;i应该画(玩家位置)||
此->深度==0){
离开孩子们,把他们安置回来(这个);
}
}
GLuint PQuad::get_vertexbuffer(){
返回vbo_顶点;
}
GLuint PQuad::get_colorbuffer(){
返回vbo_颜色;
}
GLuint PQuad::get_normalbuffer(){
返回vbo_法线;
}
GLuint PQuad::get_elementbuffer(){
返回ibo_元素;
}
void PQuad::set_父项(PQuad*quad){
这->父=四元;
}
void PQuad::set_child_索引(int child_索引){
此->子索引=子索引;
}
void PQuad::设置深度(整数深度){
这个->深度=深度;
}
void PQuad::set_root(bool root){
这个->根=根;
}
void PQuad::计算位置(){
此->元素\u宽度=深度==0?1.0f:parent->获取\u元素\u宽度()/2.0f;
float quad_y=child_index/2==0?0:元素宽度*四元高度-元素宽度;
float quad_x=子索引%2==0?0:元素宽度*四元宽度-元素宽度;
如果(此->深度!=0){
quad_x+=父级->获取_位置().x;
四元y+=父->获取位置().y;
}
这个->位置=glm::vec3(四元x,四元y,0);
}
void PQuad::construct(){
如果(!this->builded){
向量顶点;
std::向量法线;
矢量颜色;
std::向量元素;
构造顶点(顶点和颜色);
构造_元素(&元素);
球体化(&顶点和法线);
构造法线(顶点、元素和法线)(&U);
构造缓冲区(顶点、颜色、元素和法线);
浮动距离=半径;
如果(!球形化){
距离=四边形宽度;
}
构造深度表(距离);
这个->构建=真;
}
}
void PQuad::构造深度表(浮动距离){
树[0]=-1;
对于(int i=1;i面方向,此->半径));
PQuad*child=&children.back();
子->设置深度(深度+1);
子->设置子索引(i);
子项->设置父项(此项);
child->construct_children();
}
}否则{
叶=真;
}
}
void PQuad::构造_顶点(标准::向量*顶点,标准::向量*颜色){
顶点->保留(四边形宽度*四边形高度);
对于(int y=0;y向后放置(glm::vec3(位置x+x*元素宽度,四边形高度-1,-(位置y+y*元素宽度));
打破
案件数量增加:
顶点->向后放置(glm::vec3(位置x+x*元素宽度,0,-(位置y+y*元素宽度));
打破
案例编号:
顶点->向后放置(glm::vec3(四边形宽度-1,position.y+y*元素宽度,-(position.x+x*元素宽度));
打破
案例XD减少:
顶点->向后放置(glm::vec3(0,位置.y+y*元素宽度,-(位置.x+x*元素宽度));
打破
外壳镀锌:
顶点->向后放置(glm::vec3(position.x+x*元素宽度,position.y+y*元素宽度,0));
打破
案例ZD减少:
顶点->放置回(glm::vec3(位置.x+x*元素宽度,位置.y+y*元素宽度,-(四边形宽度-1));
打破
}
//将立方体的底部、右侧和前部顶点从(0,0,0)定位到(-16,-16,16)
(*顶点)[顶点->大小()-1]=glm::vec3(四边形宽度/2.0f,四边形宽度/2.0f,-(四边形宽度/2.0f));
颜色->背面定位(颜色3(255.0f、255.0f、255.0f、false));
}
#include "..\include\PQuad.h"
#include "..\include\Color3.h"
#include <iostream>
#include <vector>
#include <cmath>
#include <GL/glew.h>
#include <GL/glu.h>
#include <GL/gl.h>
#define QUAD_WIDTH 32
#define QUAD_HEIGHT 32
#define NUM_OF_CHILDREN 4
#define MAX_DEPTH 4
PQuad::PQuad(FaceDirection face_direction, float planet_radius) {
this->built = false;
this->spherised = false;
this->face_direction = face_direction;
this->radius = planet_radius;
this->planet_centre = glm::vec3(0, 0, 0);
}
PQuad::~PQuad() {
}
std::vector<PQuad> PQuad::get_children() {
return children;
}
bool PQuad::get_built() {
return this->built;
}
int PQuad::get_depth() {
return this->depth;
}
float *PQuad::get_table() {
return tree;
}
float PQuad::get_element_width() {
return element_width;
}
glm::vec3 PQuad::get_position() {
return position;
}
glm::vec3 PQuad::get_centre() {
return centre;
}
void PQuad::get_recursive(glm::vec3 player_pos, std::vector<PQuad*>& out_children) {
for (size_t i = 0; i < children.size(); i++) {
children[i].get_recursive(player_pos, out_children);
}
if (this->should_draw(player_pos) ||
this->depth == 0) {
out_children.emplace_back(this);
}
}
GLuint PQuad::get_vertexbuffer() {
return vbo_vertices;
}
GLuint PQuad::get_colorbuffer() {
return vbo_colors;
}
GLuint PQuad::get_normalbuffer() {
return vbo_normals;
}
GLuint PQuad::get_elementbuffer() {
return ibo_elements;
}
void PQuad::set_parent(PQuad *quad) {
this->parent = quad;
}
void PQuad::set_child_index(int child_index) {
this->child_index = child_index;
}
void PQuad::set_depth(int depth) {
this->depth = depth;
}
void PQuad::set_root(bool root) {
this->root = root;
}
void PQuad::calculate_position() {
this->element_width = depth == 0 ? 1.0f : parent->get_element_width() / 2.0f;
float quad_y = child_index / 2 == 0 ? 0 : element_width * QUAD_HEIGHT - element_width;
float quad_x = child_index % 2 == 0 ? 0 : element_width * QUAD_WIDTH - element_width;
if (this->depth != 0) {
quad_x += parent->get_position().x;
quad_y += parent->get_position().y;
}
this->position = glm::vec3(quad_x, quad_y, 0);
}
void PQuad::construct() {
if (!this->built) {
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;
std::vector<Color3> colors;
std::vector<GLushort> elements;
construct_vertices(&vertices, &colors);
construct_elements(&elements);
spherise(&vertices, &normals);
construct_normals(&vertices, &elements, &normals);
construct_buffers(&vertices, &colors, &elements, &normals);
float distance = radius;
if (!spherised) {
distance = QUAD_WIDTH;
}
construct_depth_table(distance);
this->built = true;
}
}
void PQuad::construct_depth_table(float distance) {
tree[0] = -1;
for (int i = 1; i < MAX_DEPTH; i++) {
tree[i] = distance;
distance /= 2.0f;
}
}
void PQuad::construct_children() {
calculate_position();
if (depth < (int)MAX_DEPTH) {
children.reserve((int)NUM_OF_CHILDREN);
for (int i = 0; i < (int)NUM_OF_CHILDREN; i++) {
children.emplace_back(PQuad(this->face_direction, this->radius));
PQuad *child = &children.back();
child->set_depth(depth + 1);
child->set_child_index(i);
child->set_parent(this);
child->construct_children();
}
} else {
leaf = true;
}
}
void PQuad::construct_vertices(std::vector<glm::vec3> *vertices, std::vector<Color3> *colors) {
vertices->reserve(QUAD_WIDTH * QUAD_HEIGHT);
for (int y = 0; y < QUAD_HEIGHT; y++) {
for (int x = 0; x < QUAD_WIDTH; x++) {
switch (face_direction) {
case YIncreasing:
vertices->emplace_back(glm::vec3(position.x + x * element_width, QUAD_HEIGHT - 1, -(position.y + y * element_width)));
break;
case YDecreasing:
vertices->emplace_back(glm::vec3(position.x + x * element_width, 0, -(position.y + y * element_width)));
break;
case XIncreasing:
vertices->emplace_back(glm::vec3(QUAD_WIDTH - 1, position.y + y * element_width, -(position.x + x * element_width)));
break;
case XDecreasing:
vertices->emplace_back(glm::vec3(0, position.y + y * element_width, -(position.x + x * element_width)));
break;
case ZIncreasing:
vertices->emplace_back(glm::vec3(position.x + x * element_width, position.y + y * element_width, 0));
break;
case ZDecreasing:
vertices->emplace_back(glm::vec3(position.x + x * element_width, position.y + y * element_width, -(QUAD_WIDTH - 1)));
break;
}
// Position the bottom, right, front vertex of the cube from being (0,0,0) to (-16, -16, 16)
(*vertices)[vertices->size() - 1] -= glm::vec3(QUAD_WIDTH / 2.0f, QUAD_WIDTH / 2.0f, -(QUAD_WIDTH / 2.0f));
colors->emplace_back(Color3(255.0f, 255.0f, 255.0f, false));
}
}
switch (face_direction) {
case YIncreasing:
this->centre = glm::vec3(position.x + QUAD_WIDTH / 2.0f, QUAD_HEIGHT - 1, -(position.y + QUAD_HEIGHT / 2.0f));
break;
case YDecreasing:
this->centre = glm::vec3(position.x + QUAD_WIDTH / 2.0f, 0, -(position.y + QUAD_HEIGHT / 2));
break;
case XIncreasing:
this->centre = glm::vec3(QUAD_WIDTH - 1, position.y + QUAD_HEIGHT / 2.0f, -(position.x + QUAD_WIDTH / 2.0f));
break;
case XDecreasing:
this->centre = glm::vec3(0, position.y + QUAD_HEIGHT / 2.0f, -(position.x + QUAD_WIDTH / 2.0f));
break;
case ZIncreasing:
this->centre = glm::vec3(position.x + QUAD_WIDTH / 2.0f, position.y + QUAD_HEIGHT / 2.0f, 0);
break;
case ZDecreasing:
this->centre = glm::vec3(position.x + QUAD_WIDTH / 2.0f, position.y + QUAD_HEIGHT / 2.0f, -(QUAD_HEIGHT - 1));
break;
}
this->centre -= glm::vec3(QUAD_WIDTH / 2.0f, QUAD_WIDTH / 2.0f, -(QUAD_WIDTH / 2.0f));
}
void PQuad::construct_elements(std::vector<GLushort> *elements) {
int index = 0;
elements->reserve((QUAD_WIDTH - 1) * (QUAD_HEIGHT - 1) * 6);
for (int y = 0; y < QUAD_HEIGHT - 1; y++) {
for (int x = 0; x < QUAD_WIDTH - 1; x++) {
GLushort bottom_left = x + y * QUAD_WIDTH;
GLushort bottom_right = (x + 1) + y * QUAD_WIDTH;
GLushort top_left = x + (y + 1) * QUAD_WIDTH;
GLushort top_right = (x + 1) + (y + 1) * QUAD_WIDTH;
elements->emplace_back(top_left);
elements->emplace_back(bottom_right);
elements->emplace_back(bottom_left);
elements->emplace_back(top_left);
elements->emplace_back(top_right);
elements->emplace_back(bottom_right);
}
}
}
void PQuad::construct_normals(std::vector<glm::vec3> *vertices, std::vector<GLushort> *elements, std::vector<glm::vec3> *normals) {
normals->reserve(QUAD_WIDTH * QUAD_HEIGHT);
for (int i = 0; i < elements->size() / 3; i++) {
int index1 = elements->at(i * 3);
int index2 = elements->at(i * 3 + 1);
int index3 = elements->at(i * 3 + 2);
glm::vec3 side1 = vertices->at(index1) - vertices->at(index3);
glm::vec3 side2 = vertices->at(index1) - vertices->at(index2);
glm::vec3 normal = glm::cross(side1, side2);
normal = glm::normalize(normal);
normals->emplace_back(normal);
normals->emplace_back(normal);
normals->emplace_back(normal);
}
}
void PQuad::spherise(std::vector<glm::vec3> *vertices, std::vector<glm::vec3> *normals) {
for (int i = 0; i < QUAD_WIDTH * QUAD_HEIGHT; i++) {
glm::vec3 normal = glm::normalize(vertices->at(i) - planet_centre);
(*vertices)[i] = (float)(radius) * normal;
}
glm::vec3 normal = glm::normalize(centre - planet_centre);
centre = normal * (float)(radius);
this->spherised = true;
}
void PQuad::construct_buffers(std::vector<glm::vec3> *vertices, std::vector<Color3> *colors, std::vector<GLushort> *elements, std::vector<glm::vec3> *normals) {
glGenBuffers(1, &vbo_vertices);
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertices);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * vertices->size(), &((*vertices)[0]), GL_STATIC_DRAW);
glGenBuffers(1, &vbo_colors);
glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
glBufferData(GL_ARRAY_BUFFER, sizeof(Color3) * colors->size(), &((*colors)[0]), GL_STATIC_DRAW);
glGenBuffers(1, &vbo_normals);
glBindBuffer(GL_ARRAY_BUFFER, vbo_normals);
glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * normals->size(), &((*normals)[0]), GL_STATIC_DRAW);
glGenBuffers(1, &ibo_elements);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_elements);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLushort) * elements->size(), &((*elements)[0]), GL_STATIC_DRAW);
}
float distance3(glm::vec3 v1, glm::vec3 v2) {
return sqrt(pow(abs(v1.x - v2.x), 2) + pow(abs(v1.y - v2.y), 2) + pow(abs(v1.z - v2.z), 2));
}
bool PQuad::should_draw(glm::vec3 player_position) {
float distance = distance3(player_position, centre);
if (distance < tree[depth]) {
return true;
}
return false;
}