-1

I'm trying to create a class that will describe a particular object I'm trying to render to the screen. I have a Shaders, Mesh, and Texture object that I have been running in main() that is working fine. All it does now is draw an image to the screen.

But when I put those objects in a class called Entity and try to render with it, it doesn't draw the image.

Main code:

int main(int argc, char*argv[]) {

    Display display;
    display.init();  //Sets up SDL and glew

    Shaders shaders("basicShader");
    Mesh mesh(shaders.getProgram());    
    Texture texture("kitten.png");
    Entity entity;


    //Loop stuff
    bool quit = false;
    SDL_Event e;
    double frameCounter = 0;
    double time = SDL_GetTicks();

    while (!quit) {
        while (SDL_PollEvent(&e)) {
            if (e.type == SDL_QUIT) {
                quit = true;
            }
            if (e.type == SDL_KEYDOWN) {
                if (e.key.keysym.sym == SDLK_ESCAPE)
                    quit = true;
            }
        }

        ++frameCounter;
        if (SDL_GetTicks() - time >= 500) {
            std::cout << "FPS: " << frameCounter / ((SDL_GetTicks() - time) / 1000) << std::endl;
            frameCounter = 0;
            time = SDL_GetTicks();
        }

        // Clear the screen to black
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        mesh.draw();
        //entity.render();

        // Swap buffers
        display.render();
    }

    mesh.~Mesh();
    entity.~Entity();
    display.~Display();
    return 0;
}

Entity header:

#pragma once
#include "Mesh.h"
#include "Shaders.h"
#include "Texture.h"

class Entity
{
public:
    Entity();
    void render();
    ~Entity();
private:
    Mesh mesh;
    Shaders shaders;
    Texture texture;
};

Entity class code:

#include "Entity.h"


Entity::Entity() {
    shaders = Shaders("basicShader");
    mesh = Mesh(shaders.getProgram());
    texture = Texture("kitten.png");
}

void Entity::render() {
    mesh.draw();
}

Entity::~Entity() {
    mesh.~Mesh();
}

This code works when mesh.draw() is uncommented and entity.render() IS commented in main(), but not the other way around. I can post code from headers and other classes if necessary.

Xerict
  • 1
  • 3
  • 2
    What's with all those explicit destructor calls? Are you sure what you are doing there? – Christian Hackl Mar 14 '15 at 17:42
  • Not really. In the past, I have had issues with the program hanging on exit unless i put those there. Currently it seems like your right, I don't need them. I am a novice at this, so I'm still working it out. – Xerict Mar 14 '15 at 17:44
  • 1
    Please show the definition of the `Entity` class as well (what's in the header). Also, you're a C++ novice, you might want to pick up a [good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Angew is no longer proud of SO Mar 14 '15 at 17:50
  • 2
    @Xerict: You must absolutely start with simpler examples, not with OpenGL. That's just not beginners stuff! Your destructor calls here are extremely wrong. In C++, local objects destroy themselves. You should learn about classes with typical mini examples like `Animal` or `Person`... – Christian Hackl Mar 14 '15 at 17:55
  • Not sure if it's a "great" idea to wrap OpenGL in classes.. See: https://www.opengl.org/wiki/Common_Mistakes#The_Object_Oriented_Language_Problem It must be done right. – Brandon Mar 14 '15 at 17:59
  • What is the alternative? Run all OpenGL code in main? That seems like it would produce very messy and difficult to read code. Also, the primary issue with OpenGL in classes seems to be that an active context must exist, which is true for my code. An OpenGL context is created early and only destroyed at the very end in the Display destructor. – Xerict Mar 14 '15 at 18:18
  • @Brandon I don't think that link is arguing against OOP wrapping. It seems to me that it's just warning you of potential pitfalls and giving you advice on how to avoid them. – dbank Mar 14 '15 at 18:23
  • @dbank; True. I just posted it because I too got caught by the pitfalls once. – Brandon Mar 14 '15 at 18:24
  • @Brandon Ah, yes. And now I see you said "It must be done right" at the end there. I think I missed that the first time I read it. :-) – dbank Mar 14 '15 at 18:29
  • 1
    This is very similar to this recent question: http://stackoverflow.com/questions/28929452. My answer there explains some of the pitfalls of wrapping OpenGL objects in C++ classes, particularly when using containers. It's very easy to shoot yourself in the foot if you're not very careful. – Reto Koradi Mar 14 '15 at 19:18

1 Answers1

0

Reto Koradi's link to his answer to another question helped fix this: Mesh class called with default constructor not working OpenGL C++

To fix this, I declared the objects as pointers in class Entity and initialized like this:

Entity header:

#pragma once
#include "Mesh.h"
#include "Shaders.h"
#include "Texture.h"

class Entity
{
public:
    Entity();
    void render();
    ~Entity();
private:
    Mesh* mesh;
    Shaders* shaders;
    Texture* texture;
};

Entity constructor:

Entity::Entity() {
    shaders = new Shaders("basicShader");
    mesh = new Mesh(shaders->getProgram());
    texture = new Texture("kitten.png");
}
Community
  • 1
  • 1
Xerict
  • 1
  • 3
  • Lol.. well I'll be damned. Another person that also got shot in the leg with OpenGL Wrappers (like myself). I would suggest using a `unique_ptr` here and not just raw new. – Brandon Mar 14 '15 at 20:14
  • 1
    @Brandon You're far from alone. It's a common problem. I saw it once in a larger software package, with some pretty entertaining symptoms. And a couple of very puzzled software engineers trying to figure out what was going on. – Reto Koradi Mar 14 '15 at 21:40