奇怪的未知标识符错误

时间:2014-02-06 11:57:14

标签: c++ opengl compiler-errors

我正在开发一个使用visual studio 2013并使用c ++编程的项目。出于某种原因,我不明白我在编译项目时遇到了未知标识符错误。我现在已经连续2天没有找到答案,因为没有找到任何能让我朝着正确方向前进的方法。

错误消息: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;
}

错误来自Renderer头文件。

渲染器头

#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 个答案:

答案 0 :(得分: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的指针,所以你可以只使用前向声明。因此,请将#include "Mesh.h"替换为class Mesh;

答案 1 :(得分:1)

Mesh.h包含Renderer.h,其中包含Mesh.h。结果是一个类定义出现在另一个类之前,所以第二个类定义在第一个类引用时没有被声明。

在这种情况下,至少有一个类可以只使用另一个类的声明进行管理。这就是这种情况; Renderer只需要声明Mesh

class Mesh;

因为它只使用名称来声明指针和函数参数。 Mesh根本不需要了解Renderer,因为它利用了单例反模式的不可见耦合,因此只需删除包含。{/ p>

每个源文件都需要包含两个标头,因为它们以需要定义的方式使用这两个类。 Renderer.h仍然需要包含SceneShader.h,因为它声明了该类型的对象。