2014-02-06 46 views
0

我在一個項目工作的視覺工作室2013年和編程在C + +的工作。出於某種原因,我不明白我在編譯我的項目時遇到了未知的標識符錯誤。我已經搜尋了兩天,現在答案還沒有找到任何可以讓我朝正確方向發展的答案。奇怪的未知標識符錯誤

錯誤消息:error C2061: syntax error : identifier 'Mesh'

網格報頭

#ifndef MESH_H 
#define MESH_H 

#include <GL/glew.h> 
#include <glm/glm.hpp> 
#include <vector> 

#include "Renderer.h" 

class Mesh 
{ 
public: 
    GLuint GetVao(); 
    GLuint GetVbo(); 
    GLuint GetSize(); 

    void AddVertex(const glm::vec3& position); 
    void SendData(); 
    void Destroy(); 

private: 
    std::vector<GLfloat> verticies; 
    GLuint vao; 
    GLuint vbo; 
    GLuint size; 
}; 

#endif 

網格源

#include "Mesh.h" 

void Mesh::AddVertex(const glm::vec3& position) 
{ 
    verticies.push_back(position.x); 
    verticies.push_back(position.y); 
    verticies.push_back(position.z); 
} 

void Mesh::Destroy() 
{ 
    glDeleteVertexArrays(1, &vao); 
    glDeleteBuffers(1, &vbo); 

    verticies.clear(); 
} 

void Mesh::SendData() 
{ 
    if (vao == 0) 
     glGenVertexArrays(1, &vao); 

    if (vbo == 0) 
     glGenBuffers(1, &vbo); 

    glBindVertexArray(vao); 
    glBindBuffer(GL_VERTEX_ARRAY, vbo); 

    glBufferData(GL_VERTEX_ARRAY, 0, 0, GL_STATIC_DRAW); 
    glBufferData(GL_VERTEX_ARRAY, verticies.size() * sizeof(GLfloat), verticies.data(), GL_STATIC_DRAW); 

    glEnableVertexAttribArray(Renderer::GetInstance()->GetSceneShader()->GetPositionLocation()); 

    glVertexAttribPointer(Renderer::GetInstance()->GetSceneShader()->GetPositionLocation(), 3, GL_FLOAT, false, 0, 0); 

    glBindVertexArray(0); 
} 

GLuint Mesh::GetVao() 
{ 
    return vao; 
} 

GLuint Mesh::GetVbo() 
{ 
    return vbo; 
} 

GLuint Mesh::GetSize() 
{ 
    return size; 
} 

誤差來自於渲染器頭文件。

渲染器頭

#ifndef RENDERER_H 
#define RENDERER_H 

#include <GL/glew.h> 
#include "SceneShader.h" 
#include "Mesh.h" 

class Renderer 
{ 
public: 
    static Renderer* GetInstance() 
    { 
     static Renderer instance; 
     return &instance; 
    } 

    void Initialize(); 
    void PreDraw(); 
    void Destroy(); 
    void DrawMesh(Mesh* mesh); 

    SceneShader* GetSceneShader(); 

protected: 
    virtual ~Renderer(); 

private: 
    Renderer(); 
    SceneShader sceneShader; 
}; 

#endif; 

渲染器源:

#include "Renderer.h" 

Renderer::Renderer() 
{ 
} 

Renderer::~Renderer() 
{ 
    Destroy(); 
} 

void Renderer::Initialize() 
{ 
    glClearColor(0.5f, 0.5f, 1.0f, 1.0f); 

    glEnable(GL_DEPTH_TEST); 

    glEnable(GL_CULL_FACE); 
    glCullFace(GL_BACK); 
    glFrontFace(GL_CW); 

    sceneShader.Create(); 
    sceneShader.Bind(); 
} 

void Renderer::PreDraw() 
{ 
    glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT); 
} 

void Renderer::Destroy() 
{ 
    sceneShader.Unbind(); 
    sceneShader.Destroy(); 
} 

SceneShader* Renderer::GetSceneShader() 
{ 
    return &sceneShader; 
} 

void Renderer::DrawMesh(Mesh* mesh) 
{ 
    glBindVertexArray(mesh->GetVao()); 
    glDrawArrays(GL_TRIANGLES, 0, mesh->GetSize()); 
    glBindVertexArray(0); 
} 
+2

循環包含依賴關係:'Mesh.h'包含'Renderer.h',反之亦然。有很多關於這種事情的SO帖子。 – juanchopanza

+1

與問題沒有真正關聯,但您的Renderer類可能有缺陷。它似乎是作爲一個單例實現的,但是你不禁止編譯器爲這個類提供的默認拷貝構造函數和拷貝分配(以及移動C++ 11中的構造函數和賦值)。這種方式的代碼像'Renderer r = * Renderer :: GetInstance();'將編譯並創建單例副本。 –

回答

3

你的問題是你有一個循環包括。當Mesh.h正在進行預處理時,它包括Renderer.h,然後需要包括Mesh.h。由於您有內含警衛,因此Mesh.h不能再次包含,因此Renderer將無法​​看到Mesh的聲明/定義。

這是更恰當地使用#include輕易可以解決的:

  1. Mesh.h甚至不需要包括Renderer.h(它不使用它的話)。
  2. Mesh.cpp確實需要Renderer.h雖然,所以它應該包含在該文件的頂部。
  3. Renderer.h也不需要包括Mesh.h。由於它只是一個指向Mesh的指針,因此您可以僅使用前向聲明。因此請用class Mesh;替換#include "Mesh.h"
1

Mesh.h包括Renderer.h它試圖包括Mesh.h。結果是一個類定義出現在另一個之前,所以第二個類在第一個引用時沒有被聲明。

在這樣的情況下,至少有一個類只能管理另一個類的聲明。這裏就是這種情況; Renderer只需要的Mesh聲明:

class Mesh; 

,因爲它僅使用名字來聲明指針和函數的參數。 Mesh完全不需要知道關於Renderer,因爲它利用了單體反模式的不可見耦合,因此只需簡單地刪除它即可。

每個源文件都需要包含兩個頭文件,因爲它們以需要定義的方式使用這兩個類。 Renderer.h仍然需要包含SceneShader.h,因爲它聲明瞭該類型的對象。