0

I'm a c++ beginner , trying to build my first application with openGL.

I'm trying to create a Room class that will take parameters like width, length and height to create a mesh object which I then want to draw from the main function.

At the moments I'm not trying to initialize Room with any parameters, just trying to create a basic mesh from within room, CPP rather than from main.

I'm having trouble creating a mesh object as a private variable within the class room, and then defining a method to draw it by calling it from main.

I'm using Benny's awesome tutorial and have his exact GitHub files on my visual studio solution.

Im posting it here, they include the mesh.h and mesh. CPP which are probably where the problem is coming from this link.

Here is the current code (I've included everything I include in main, just to make sure)

----Room.h ---------------

#pragma once

#include <iostream>
#include <SDL2/SDL.h>
#include "display.h"
#include "mesh.h"
#include "shader.h"
#include "texture.h"
#include "transform.h"
#include "camera.h"


class Room
{
public:
 Room();
 ~Room();
 void drawRoom();

private:
 Mesh* mesh;

};

----Room.cpp ---------------

#include "Room.h"
#include <iostream>
#include <SDL2/SDL.h>
#include "display.h"
#include "mesh.h"
#include "shader.h"
#include "texture.h"
#include "transform.h"
#include "camera.h"


Room::Room()
{ 
 Vertex vertices[] =
 {
  Vertex(glm::vec3(-1, -1, -1), glm::vec2(1, 0), glm::vec3(0, 0, -1)),
  Vertex(glm::vec3(-1, 1, -1), glm::vec2(0, 0), glm::vec3(0, 0, -1)),
  Vertex(glm::vec3(1, 1, -1), glm::vec2(0, 1), glm::vec3(0, 0, -1)),
  Vertex(glm::vec3(1, -1, -1), glm::vec2(1, 1), glm::vec3(0, 0, -1)),

  Vertex(glm::vec3(-1, -1, 1), glm::vec2(1, 0), glm::vec3(0, 0, 1)),
  Vertex(glm::vec3(-1, 1, 1), glm::vec2(0, 0), glm::vec3(0, 0, 1)),
  Vertex(glm::vec3(1, 1, 1), glm::vec2(0, 1), glm::vec3(0, 0, 1)),
  Vertex(glm::vec3(1, -1, 1), glm::vec2(1, 1), glm::vec3(0, 0, 1)),

  Vertex(glm::vec3(-1, -1, -1), glm::vec2(0, 1), glm::vec3(0, -1, 0)),
  Vertex(glm::vec3(-1, -1, 1), glm::vec2(1, 1), glm::vec3(0, -1, 0)),
  Vertex(glm::vec3(1, -1, 1), glm::vec2(1, 0), glm::vec3(0, -1, 0)),
  Vertex(glm::vec3(1, -1, -1), glm::vec2(0, 0), glm::vec3(0, -1, 0)),

  Vertex(glm::vec3(-1, 1, -1), glm::vec2(0, 1), glm::vec3(0, 1, 0)),
  Vertex(glm::vec3(-1, 1, 1), glm::vec2(1, 1), glm::vec3(0, 1, 0)),
  Vertex(glm::vec3(1, 1, 1), glm::vec2(1, 0), glm::vec3(0, 1, 0)),
  Vertex(glm::vec3(1, 1, -1), glm::vec2(0, 0), glm::vec3(0, 1, 0)),

  Vertex(glm::vec3(-1, -1, -1), glm::vec2(1, 1), glm::vec3(-1, 0, 0)),
  Vertex(glm::vec3(-1, -1, 1), glm::vec2(1, 0), glm::vec3(-1, 0, 0)),
  Vertex(glm::vec3(-1, 1, 1), glm::vec2(0, 0), glm::vec3(-1, 0, 0)),
  Vertex(glm::vec3(-1, 1, -1), glm::vec2(0, 1), glm::vec3(-1, 0, 0)),

  Vertex(glm::vec3(1, -1, -1), glm::vec2(1, 1), glm::vec3(1, 0, 0)),
  Vertex(glm::vec3(1, -1, 1), glm::vec2(1, 0), glm::vec3(1, 0, 0)),
  Vertex(glm::vec3(1, 1, 1), glm::vec2(0, 0), glm::vec3(1, 0, 0)),
  Vertex(glm::vec3(1, 1, -1), glm::vec2(0, 1), glm::vec3(1, 0, 0)),
 };

 unsigned int indices[] = { 0, 1, 2,
  0, 2, 3,

  6, 5, 4,
  7, 6, 4,

  10, 9, 8,
  11, 10, 8,

  12, 13, 14,
  12, 14, 15,

  16, 17, 18,
  16, 18, 19,

  22, 21, 20,
  23, 22, 20
 };

 mesh = new Mesh(vertices, sizeof(vertices) / sizeof(vertices[0]), indices, sizeof(indices) / sizeof(indices[0]));

}

Room::~Room()
{
}

void Room::drawRoom()
{
    mesh.Draw();
}

I'm getting the following error:

Error C2228 left of '.Draw' must have class/struct/union ArchProgramer c:\users\nuno bártolo\documents\visual studio 2015\projects\archprogramer\archprogramer\room.cpp 78

Thank very much you for your help!

Nuno Bártolo
  • 75
  • 2
  • 6
  • 2
    Learning C++ and OpenGL at the same time? That's quite ambitious! – DeathByTensors May 11 '16 at 13:52
  • 1
    I agree with Drew. This is quite a simple issue and you'll be hitting lots of those on both C++ and OpenGL if you're approaching both for the first time. Your problem is the instance variable is declared as Mesh mesh which requires a default constructor to work. You'll need to declare it as Mesh* mesh and use mesh = new Mesh(...parameters...) to create it – Mariano Ruggiero May 11 '16 at 14:08
  • @MarianoRuggiero Thanks for your help Mariano, the instance is now being saved as Room's private mesh; However I've added a method drawRoom() and in this method I can't get the mesh object to use the Draw() method in the Mesh Class. in Room.h under public I've protoyped void drawRoom(); and in Room.cpp I have defined void drawRoom() { mesh.Draw()} but it won't compile? – – Nuno Bártolo May 11 '16 at 18:48

2 Answers2

1

mesh is a pointer (Mesh* mesh;). To call Draw you must use the arrow notation: mesh->Draw();.

If you don't want to have problems later, you should also check that mesh != nullptr before calling Draw (you can simply log that you are trying to draw an uninitialized room or something like that, much easier to debug than memory corruption or segfaults).

Finally in the destructor you should have a line delete mesh; to release the memory associated and other resources a Mesh instance might be using (Or even better declare mesh using unique_ptr, like this: std::unique_ptr<Mesh>, so that it behaves like a pointer but it will be deleted automatically when you destroy your room instance.

Sorin
  • 11,863
  • 22
  • 26
-1

Mesh doesn't have a default constructor (one which takes no parameters) because the following constructor is defined:

Mesh(Vertex* vertices, unsigned int numVertices, unsigned int* indices, unsigned int numIndices);

You are not constructing Room::mesh in Room's constructor, instead you are declaring a local variable that will be destroyed after the constructor finishes. To properly construct Room::mesh, you must do something like this:

Room::Room() : mesh( /*insert arguments here*/ )
{ 
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
SurvivalMachine
  • 7,946
  • 15
  • 57
  • 87