最近我一直在用OpenGL编写游戏引擎并提出问题。当我生成我的BSP文件(Quake 3)时,它会生成非常奇怪的顶点!我检查了顶点向量,下面是它包含的截图(它重复自己)
我检查了glGetError
,它没有返回任何内容(零)!我真的很难过,我不知道该怎么做。
这是我的代码:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/vec3.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <vector>
#include "map.h"
#include <fstream>
#include <memory>
#include "game_manager.h"
std::vector<BSPVerts> vertexes;
bool KikoBSP::load_map(std::string file_name)
{
this->file.open(file_name.c_str(), std::ios::in | std::ios::binary);
if (this->file.is_open())
{
this->file.read(reinterpret_cast<char*>(&this->header), sizeof(this->header));
BSPEntities* ents = new BSPEntities;
ents->ents_array = new char[this->header.lumps[BSPLUMPS::ENTITIES].length];
this->num_textures = this->header.lumps[BSPLUMPS::TEXTURES].length / sizeof(BSPTexture);
this->num_planes = this->header.lumps[BSPLUMPS::PLANES].length / sizeof(BSPPlane);
this->num_textures = this->header.lumps[BSPLUMPS::TEXTURES].length / sizeof(BSPTexture);
this->num_nodes = this->header.lumps[BSPLUMPS::NODES].length / sizeof(BSPNode);
this->num_leafs = this->header.lumps[BSPLUMPS::LEAFS].length / sizeof(BSPLeaf);
this->num_leaf_faces = this->header.lumps[BSPLUMPS::LEAF_FACES].length / sizeof(BSPLeafFace);
this->num_leaf_brushes = this->header.lumps[BSPLUMPS::LEAF_BRUSHES].length / sizeof(BSPLeafBrush);
this->num_models = this->header.lumps[BSPLUMPS::MODELS].length / sizeof(BSPModel);
this->num_brushes = this->header.lumps[BSPLUMPS::BRUSHES].length / sizeof(BSPBrush);
this->num_brush_sides = this->header.lumps[BSPLUMPS::BRUSHSIDES].length / sizeof(BSPBrushSides);
this->num_vertexes = this->header.lumps[BSPLUMPS::VERTEXES].length / sizeof(BSPVerts);
this->num_meshverts = this->header.lumps[BSPLUMPS::MESHVERTS].length / sizeof(BSPMeshVerts);
this->num_effects = this->header.lumps[BSPLUMPS::EFFECTS].length / sizeof(BSPEffects);
this->num_faces = this->header.lumps[BSPLUMPS::FACES].length / sizeof(BSPFaces);
for (int32_t x = 0; x < this->num_vertexes; x++)
{
vertexes.push_back(*reinterpret_cast<BSPVerts*>(&x));
}
for (int32_t x = 0; x < this->num_textures; x++)
{
this->textures.push_back(*reinterpret_cast<BSPTexture*>(&x));
}
for (int32_t x = 0; x < this->num_meshverts; x++)
{
this->mesh_verts.push_back(*reinterpret_cast<BSPMeshVerts*>(&x));
}
for (int32_t x = 0; x < this->num_planes; x++)
{
this->planes.push_back(*reinterpret_cast<BSPPlane*>(&x));
}
for (int32_t x = 0; x < this->num_nodes; x++)
{
this->nodes.push_back(*reinterpret_cast<BSPNode*>(&x));
}
for (int32_t x = 0; x < this->num_leafs; x++)
{
this->leaf.push_back(*reinterpret_cast<BSPLeaf*>(&x));
}
for (int32_t x = 0; x < this->num_faces; x++)
{
this->faces.push_back(*reinterpret_cast<BSPFaces*>(&x));
}
for (int32_t x = 0; x < this->num_leaf_faces; x++)
{
this->leaf_faces.push_back(*reinterpret_cast<BSPLeafFace*>(&x));
}
for (int32_t x = 0; x < this->num_leaf_brushes; x++)
{
this->leaf_brush.push_back(*reinterpret_cast<BSPLeafBrush*>(&x));
}
for (int32_t x = 0; x < this->num_models; x++)
{
this->model.push_back(*reinterpret_cast<BSPModel*>(&x));
}
for (int32_t x = 0; x < this->num_brushes; x++)
{
this->brushes.push_back(*reinterpret_cast<BSPBrush*>(&x));
}
for (int32_t x = 0; x < this->num_brush_sides; x++)
{
this->brush_sides.push_back(*reinterpret_cast<BSPBrushSides*>(&x));
}
for (int32_t x = 0; x < this->num_effects; x++)
{
this->effect.push_back(*reinterpret_cast<BSPEffects*>(&x));
}
this->file.seekg(this->header.lumps[BSPLUMPS::ENTITIES].offset);
this->file.read(reinterpret_cast<char*>(ents->ents_array), this->header.lumps[BSPLUMPS::ENTITIES].length);
this->file.seekg(this->header.lumps[BSPLUMPS::TEXTURES].offset);
this->file.read(reinterpret_cast<char*>(textures.data()), this->header.lumps[BSPLUMPS::TEXTURES].length);
this->file.seekg(this->header.lumps[BSPLUMPS::PLANES].offset);
this->file.read(reinterpret_cast<char*>(this->planes.data()), this->header.lumps[BSPLUMPS::PLANES].length);
this->file.seekg(this->header.lumps[BSPLUMPS::NODES].offset);
this->file.read(reinterpret_cast<char*>(this->nodes.data()), this->header.lumps[BSPLUMPS::NODES].length);
this->file.seekg(this->header.lumps[BSPLUMPS::LEAFS].offset);
this->file.read(reinterpret_cast<char*>(this->leaf.data()), this->header.lumps[BSPLUMPS::LEAFS].length);
this->file.seekg(this->header.lumps[BSPLUMPS::LEAF_FACES].offset);
this->file.read(reinterpret_cast<char*>(this->leaf_faces.data()), this->header.lumps[BSPLUMPS::LEAF_FACES].length);
this->file.seekg(this->header.lumps[BSPLUMPS::LEAF_BRUSHES].offset);
this->file.read(reinterpret_cast<char*>(this->leaf_brush.data()), this->header.lumps[BSPLUMPS::LEAF_BRUSHES].length);
this->file.seekg(this->header.lumps[BSPLUMPS::MODELS].offset);
this->file.read(reinterpret_cast<char*>(this->model.data()), this->header.lumps[BSPLUMPS::MODELS].length);
this->file.seekg(this->header.lumps[BSPLUMPS::BRUSHES].offset);
this->file.read(reinterpret_cast<char*>(this->brushes.data()), this->header.lumps[BSPLUMPS::BRUSHES].length);
this->file.seekg(this->header.lumps[BSPLUMPS::BRUSHSIDES].offset);
this->file.read(reinterpret_cast<char*>(this->brush_sides.data()), this->header.lumps[BSPLUMPS::BRUSHSIDES].length);
this->file.seekg(this->header.lumps[BSPLUMPS::VERTEXES].offset);
for (int32_t x = 0; x < this->num_vertexes; x++)
{
this->file.read(reinterpret_cast<char*>(&vertexes.data()[x]), this->header.lumps[BSPLUMPS::VERTEXES].length);
}
this->file.seekg(this->header.lumps[BSPLUMPS::MESHVERTS].offset);
this->file.read(reinterpret_cast<char*>(this->mesh_verts.data()), this->header.lumps[BSPLUMPS::MESHVERTS].length);
this->file.seekg(this->header.lumps[BSPLUMPS::EFFECTS].offset);
this->file.read(reinterpret_cast<char*>(this->effect.data()), this->header.lumps[BSPLUMPS::EFFECTS].length);
this->file.seekg(this->header.lumps[BSPLUMPS::FACES].offset);
this->file.read(reinterpret_cast<char*>(this->faces.data()), this->header.lumps[BSPLUMPS::FACES].length);
std::printf("BSP VERSION: '%s'\n", this->header.magic);
if (std::strncmp(this->header.magic, "IBSP", 4) == 0)
{
std::printf("SUCCESS: VALID BSP FORMAT!\n");
}
else
{
std::printf("ERROR: INVALID BSP FORMAT!\n");
return false;
}
this->shader.load_shader("shaders/bsp.vs", "shaders/bsp.fs");
/* heres where I try to store the data for the faces vertices */
for (int32_t x = 0; x < this->num_faces; x++)
{
BSPFaces& face = this->faces[x];
for (int32_t vertices = 0; vertices < this->num_vertexes; vertices++)
{
BSPVerts* vert = reinterpret_cast<BSPVerts*>(&vertexes[x]);
this->vertices_vector.push_back(vert[x].position.x);
this->vertices_vector.push_back(vert[x].position.y);
this->vertices_vector.push_back(vert[x].position.z);
this->colors.push_back(vert[x].position.x / 0xFF);
this->colors.push_back(vert[x].position.y / 0xFF);
this->colors.push_back(vert[x].position.z / 0xFF);
this->indices.push_back(vert[x].position.x);
this->indices.push_back(vert[x].position.y);
this->indices.push_back(vert[x].position.z);
}
}
glGenVertexArrays(1, &this->vao);
glBindVertexArray(this->vao);
glGenBuffers(1, &this->vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, this->vertices_vector.size() * sizeof(float), &this->vertices_vector.front(), GL_STATIC_DRAW);
glGenBuffers(1, &this->color_vbo);
glBindBuffer(GL_ARRAY_BUFFER, this->color_vbo);
glBufferData(GL_ARRAY_BUFFER, this->colors.size() * sizeof(float), &this->colors.front(), GL_STATIC_DRAW);
this->coord3d = glGetAttribLocation(this->shader.program, "coord3d");
this->mvp = glGetUniformLocation(this->shader.program, "mvp");
this->attrib_color = glGetAttribLocation(this->shader.program, "v_color");
glBindBuffer(GL_ARRAY_BUFFER, this->vbo);
glVertexAttribPointer(this->coord3d, // attribute
3, // number of elements per vertex, here (R,G,B)
GL_FLOAT, // the currentBlock of each element
GL_FALSE, // take our values as-is
0, // no extra data between each position
nullptr // offset of first element
);
glBindBuffer(GL_ARRAY_BUFFER, this->color_vbo);
glVertexAttribPointer(this->attrib_color,
3,
GL_FLOAT,
GL_FALSE,
0,
nullptr
);
glBindVertexArray(0);
glVertexAttrib3fv(this->attrib_color, reinterpret_cast<float*>(this->colors.data()));
return true;
}
else
{
std::printf("ERROR: COULDN'T OPEN FILE!\n");
return false;
}
return false;
}
void KikoBSP::render(glm::vec3 position)
{
glBindVertexArray(this->vao);
glEnableVertexAttribArray(this->coord3d);
glEnableVertexAttribArray(this->attrib_color);
glm::mat4 model = glm::translate(glm::mat4(1.0), glm::vec3(position.x, position.y, position.z));
glm::mat4 mvp = game_manager->projection * game_manager->view * model;
glUniformMatrix4fv(this->mvp, 1, GL_FALSE, glm::value_ptr(mvp));
glLineWidth(3.0);
glDrawArrays(GL_LINES, 0, this->vertices_vector.size());
glDisableVertexAttribArray(this->coord3d);
glDisableVertexAttribArray(this->attrib_color);
glBindVertexArray(0);
}
void KikoBSP::cleanup_map()
{
/* delete[] textures;
delete[] planes;
delete[] this->leafs;
delete[] this->nodes;
delete[] this->leaf_this->faces;
delete[] this->models;
delete[] this->brushes;
delete[] this->brush_sides;
delete[] this->vertexes;
delete[] this->mesh_verts;
delete[] this->effects;
delete[] this->this->faces;
(use maybe later?) */
this->file.close();
}
代码中没有错误,它只是绘制了这个:
这显然不是地图!
另外,如果您需要,请继承我的头文件:
#pragma once
#pragma pack(2)
#include <iostream>
#include <cstdint>
#include <string>
#include <vector>
#include <glm/vec3.hpp>
#include <fstream>
#include "shader.h"
#include <memory>
#include <array>
#define FACE_POLYGON 1
enum BSPLUMPS
{
ENTITIES,
TEXTURES,
PLANES,
NODES,
LEAFS,
LEAF_FACES,
LEAF_BRUSHES,
MODELS,
BRUSHES,
BRUSHSIDES,
VERTEXES,
MESHVERTS,
EFFECTS,
FACES,
LIGHTMAPS,
LIGHTVOLS,
VISDATA,
MAX_LUMPS
};
struct BSPLump
{
int32_t offset; /* offset to start of lump */
int32_t length; /* length of lump, always multiple of 4 */
};
struct BSPHeader
{
char magic[4]; /* ALWAYS IBSP */
int32_t version; /* 0x2E for Quake 3 */
BSPLump lumps[BSPLUMPS::MAX_LUMPS]; /* direntries */
};
struct BSPEntities
{
char* ents_array;
};
struct BSPTexture
{
char name[64];
int32_t flags;
int32_t contents;
};
struct BSPPlane
{
glm::vec3 normal;
float distance;
};
struct BSPNode
{
int32_t plane;
glm::ivec2 children;
glm::ivec3 mins;
glm::ivec3 maxs;
};
struct BSPLeaf
{
int32_t cluster;
int32_t area;
glm::ivec3 mins;
glm::ivec3 maxs;
int32_t leafface;
int32_t num_leaffaces;
int32_t leaf_brush;
int32_t num_leaf_brushes;
};
struct BSPLeafFace
{
int32_t face;
};
struct BSPLeafBrush
{
int32_t brush;
};
struct BSPModel
{
glm::fvec3 mins;
glm::fvec3 maxs;
int32_t face;
int32_t num_faces;
int32_t brush;
int32_t num_brushes;
};
struct BSPBrush
{
int32_t brush_side;
int32_t num_brush_sides;
int32_t texture;
};
struct BSPBrushSides
{
int32_t plane;
int32_t texture;
};
struct BSPVerts
{
glm::vec3 position;
glm::vec2 tex_coord; /* same as float tex_coord[2][2] */
glm::vec2 lm_coord; /* same as float tex_coord[2][2] */
glm::vec3 normal;
char color[4];
};
struct BSPMeshVerts
{
int32_t offset;
};
struct BSPEffects
{
char name[64];
int32_t brush;
int32_t unk; /* unknown */
};
struct BSPFaces
{
int32_t texture;
int32_t effect;
int32_t type;
int32_t vertex;
int32_t num_vertexes;
int32_t meshvert; /* start */
int32_t num_of_meshverts;
int32_t lm_index;
glm::ivec2 lm_start;
glm::ivec2 lm_size;
glm::vec3 lm_origin;
float lm_vecs[2][3];
glm::fvec3 normal;
glm::ivec2 size;
};
class KikoBSP
{
public:
bool load_map(std::string);
void render(glm::vec3);
void draw_level();
int32_t get_max();
int32_t get_min();
void get_vert();
void cleanup_map();
Shader shader;
BSPHeader header;
int32_t num_vertexes;
private:
std::ifstream file;
uint32_t vbo;
uint32_t vao;
uint32_t color_vbo;
uint32_t ebo;
int32_t coord3d;
int32_t mvp;
int32_t attrib_color;
BSPFaces* cur_face;
std::vector<float> vertices_vector;
std::vector<float> colors;
std::vector<float> indices;
std::vector<BSPFaces> faces;
std::vector<BSPTexture> textures;
std::vector<BSPPlane> planes;
std::vector<BSPNode> nodes;
std::vector<BSPMeshVerts> mesh_verts;
std::vector<BSPLeaf> leaf;
std::vector<BSPLeafFace> leaf_faces;
std::vector<BSPLeafBrush> leaf_brush;
std::vector<BSPModel> model;
std::vector<BSPBrush> brushes;
std::vector<BSPBrushSides> brush_sides;
std::vector<BSPEffects> effect;
int32_t num_textures;
int32_t num_planes;
int32_t num_nodes;
int32_t num_leafs;
int32_t num_leaf_faces;
int32_t num_leaf_brushes;
int32_t num_models;
int32_t num_brushes;
int32_t num_brush_sides;
int32_t num_meshverts;
int32_t num_effects;
int32_t num_faces;
int32_t num_lightmaps;
int32_t num_lightvols;
};
我认为问题是指数或顶点。我认为问题在于我如何存储顶点的数据。它真的很麻烦。
谢谢!所有帮助赞赏! :)
答案 0 :(得分:1)
每当有人说'#34;代码中没有错误&#34;,你知道某些事情已经非常错误了!
例如,这应该做什么?
for (int32_t x = 0; x < this->num_vertexes; x++)
{
vertexes.push_back(*reinterpret_cast<BSPVerts*>(&x));
}
看起来它在这里调用了一些未定义的行为。如果您只想填充数组,请执行以下操作:
vertexes.resize(num_vertices);
其次,从文件中读取顶点的代码看起来像是有逻辑错误:
for (int32_t x = 0; x < this->num_vertexes; x++)
{
this->file.read(reinterpret_cast<char*>(&vertexes.data()[x]), this->header.lumps[BSPLUMPS::VERTEXES].length);
}
看起来它会读取每个顶点的整个顶点块,可能会导致奇怪的行为。你可能只是想这样做:
file.read(reinterpret_cast<char*>(vertexes.data()), header.lumps[BSPLUMPS::VERTEXES].length);
另外,关于您的代码与您的问题无关的说明:在任何地方使用this->
会损害可读性并且不会对代码添加任何内容,请将其删除。
前一段时间我做了同样的BSP渲染器,我无法记住我留下的状态,但是你可以查看代码here。