2017-09-11 22 views
-2

最近我一直在OpenGL寫一個遊戲引擎,並有一個問題。當我生成我的BSP文件(Quake 3)時,它會生成非常奇怪的頂點!我檢查了頂點向量,繼承人包含的內容的截圖(它重演)Quake 3 BSP渲染器繪製隨機頂點

What vertex vector contains (vertexes)

我檢查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(); 
} 

有在代碼中沒有錯誤,它只是繪本:

What it draws

這顯然不是地圖!

而且,我的繼承人的頭文件,如果你需要到:

#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; 
}; 

我認爲這個問題是指數或頂點。我相信問題在於如何存儲頂點的數據。它真的是越野車。

謝謝!所有幫助讚賞! :)

+3

你會期望在'vertexes.push_back(* reinterpret_cast (&x));')中解除引用像x這樣的整數嗎?如何避免訪問衝突? – PeterT

回答

1

每當有人說「代碼中沒有錯誤」,就知道某些東西已經發生了嚴重的錯誤!

例如,這應該是做什麼?

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