2014-02-06 66 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,因为它声明了该类型的对象。

相关问题