0

Im working on a project working wth visual studio 2013 and programming in c++. For some reason i do not understand i got an unknown identifier error while compiling my project. I have seached for 2 days now for an answer havent found anything that could get me in the right direction.

Error mesage: error C2061: syntax error : identifier 'Mesh'.

Mesh header

#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

Mesh source

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

The error comes from the Renderer header file.

Renderer head

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

Renderer source:

#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);
}
jww
  • 97,681
  • 90
  • 411
  • 885
B0nde
  • 143
  • 1
  • 10
  • 2
    Cyclic include dependency: `Mesh.h` includes `Renderer.h` and vice-versa. Plenty of SO posts on that kind of thing. – juanchopanza Feb 06 '14 at 11:59
  • 1
    Not really related to the question but you probably have a defect on your Renderer class. It seems to be implemented as a singleton but you don't suppress the default copy constructor and copy assignment ( and move constructor and assignment in C++11 ) the compiler will provide for this class. This way code like `Renderer r = *Renderer::GetInstance();` will compile and create a copy of the singleton. – Tiago Gomes Feb 06 '14 at 12:04

2 Answers2

3

Your problem is that you have a cyclic include. When Mesh.h is being preprocessed, it includes Renderer.h, which then needs to include Mesh.h. Since you have inclusion guards, Mesh.h cannot be included again, so Renderer won't be able to see the declaration/definition of Mesh.

This is easily fixable by using #include more appropriately:

  1. Mesh.h doesn't even need to include Renderer.h (it doesn't use it at all).
  2. Mesh.cpp does need Renderer.h though, so it should be included at the top of that file.
  3. Renderer.h also doesn't need to include Mesh.h. Since all it has is a pointer to Mesh, you can make do with just a forward declaration. So replace #include "Mesh.h" with class Mesh;.
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
1

Mesh.h includes Renderer.h which tries to include Mesh.h. The result is that one class definition appears before the other, so the second hasn't been declared when it's referred to by the first.

In cases like this, at least one class can manage with only a declaration of the other. That's the case here; Renderer only needs a declaration of Mesh:

class Mesh;

since it only uses the name to declare pointers and function parameters. Mesh doesn't need to know about Renderer at all, since it exploits the invisible coupling of the singleton anti-pattern, so simply remove that include.

Each source file will need to include both headers, since they use both classes in ways that require a definition. Renderer.h will still need to include SceneShader.h, since it declares an object of that type.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644