0

I am writing a simple graphics library in C++ that uses freeglut. I have multiple source files, one handling colors, one handling shapes, and one handling OpenGL functions. I have a base Shape Class, and shapes deriving from it (Triangle, Quad, etc.). I initialize the GL from a .cpp, and the glutDisplayFunc calls a method which iterates through a list of shapes, which in return calls the virtual flush function of triangles, quads, etc.

The thing is, when I write a test flush function inside the same .cpp with init and display functions, the triangle gets rendered. But when I call the flush functions of each shape from inside the seperate Shape.cpp file, it does not work. Is it possible that the glVertex2f's fall out of scope when used accross different source files?

//Glut_Functions.cpp
#include "Glut_Functions.h"

using namespace Cors;

static int shapeCount = 0;
static Shape** shapeList = nullptr;

void Cors::display()
{
    glClear(GL_COLOR_BUFFER_BIT);
    for (int i = 0; i < Cors::shapeCount; i++)
    {
        Cors::shapeList[i]->flush();
    }   
    glutSwapBuffers();
}

void Cors::init(int *argc, char **argv)
{
    glutInit(argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowPosition(700, 100);
    glutInitWindowSize(800, 600);
    glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
    glutCreateWindow("whatevs");

    glutDisplayFunc(Cors::display);
    glutIdleFunc(Cors::display);
}

//Glut_Functions.h
#ifndef GLUT_FUNCTIONS_H_INCLUDED
#define GLUT_FUNCTIONS_H_INCLUDED

#include <freeglut.h>
#include "Shape.h"

namespace Cors
{
    static Shape **shapeList; //not used in this example for simplification of code.
    static int shapeCount;  //ditto...

    void init(int*, char**);
    void display(void);
}

#endif

//Shape.h
#ifndef SHAPE_H_INCLUDED
#define SHAPE_H_INCLUDED

#include <cmath>
#include <freeglut.h>
#include "Vector.h"
#include "Color.h"

namespace Cors
{
    class Shape
    {
    protected:
        Vector position;
        Vector *localVertexList;
        int localVertexCount;
        Color color;

    public:
        Shape();
        Shape(Vector argPosition);
        virtual void flush() = 0;
        //some other functions...
    };

    class Triangle : public Shape
    {
    private:
        void flush();
    public:
        Triangle();
        Triangle(Vector argVertex0, Vector argVertex1, Vector argVertex2);
    };
}
#endif

//Shape.cpp
#include "Shape.h"

using namespace Cors;
using namespace std;

//Shape Base Class
Shape::Shape() : position(0.0f, 0.0f) {}
Shape::Shape(Vector argPosition) : position(argPosition) {}

//Triangle Class
Triangle::Triangle()
{
    //some stuff
}
Triangle::Triangle(Vector argVertex0, Vector argVertex1, Vector argVertex2)
{
    //some other stuff
}
void Triangle::flush()
{
    //The triangle flush method has been simplified for test purposes.
    glColor3f(1.0f, 0.0f, 0.0f);
    glBegin(GL_TRIANGLES);
    glVertex2f(-0.5f, -0.5f);
    glVertex2f(0.5f, -0.5f);
    glVertex2f(0.0f, 0.2f);
    glEnd();
}

Note that I have posted a reduced code for simplicity, constructors and some other derived classes are excluded.

I am certain that Triangle::flush() is being called, I have put a std::cout in it and it does get invoked.

Also note that I am always welcome to any suggestions related to my coding style too :)

PS: To clear things out again, when I make a flush function inside the Glut_Functions.cpp, the triangle gets rendered. When I do it in Shape.cpp, it does not.

genpfault
  • 51,148
  • 11
  • 85
  • 139
corsel
  • 315
  • 2
  • 12
  • 2
    Out of curiosity, why are you calling your draw method `flush`? Seems like a weird name. – Colonel Thirty Two Sep 26 '14 at 16:06
  • It is quite a common word for the job, OpenGL has a glFlush() function (for sending the vertices to whatever pipeline to be rendered). It is also used in some game engines. Kind of like flushing the data to the rendering pipeline. – corsel Sep 26 '14 at 18:20
  • 2
    But it's not really flushing anything. `Triangle::flush (...)` queues up some immediate mode commands, but the implementation is actually still free to start executing those whenever it deems necessary. – Andon M. Coleman Sep 26 '14 at 19:22
  • Could you rephrase that? I am assuming the shapeList[0]->flush is queueing up the triangles, and at the end of the loop, glutSwapBuffers is sending it to the pipeline. – corsel Sep 26 '14 at 19:30
  • No, those commands are sent to the pipeline immediately, but GL doesn't necessarily have to start executing them until you get to the `glutSwapBuffers (...)` call, because that performs an implicit `glFlush (...)`. – Andon M. Coleman Sep 26 '14 at 19:58
  • But glutSwapBuffers is called at the end of the flush loop? `glClear(GL_COLOR_BUFFER_BIT); for (int i = 0; i < Cors::shapeCount; i++) { Cors::shapeList[i]->flush(); } glutSwapBuffers();` – corsel Sep 26 '14 at 20:00
  • 1
    I don't even know what we're talking about anymore. The point I was originally making is that the method you named `flush` merely queues up commands. The pipeline's not flushed until the swap buffers operation. – Andon M. Coleman Sep 26 '14 at 20:09
  • @cem: It ius totally unclear what the GL state at the time of the call is - or if you even have a GL context then. – derhass Sep 26 '14 at 21:28
  • @cem: Flushing means, that OpenGL is told, that everything that has been queued up so far should be processed now. Adding something to a command queue **is not** flushing it. It is in fact the very opposite of it. What you do in those "flush" functions is exactly the opposite of flushing. – datenwolf Sep 27 '14 at 00:36
  • @AndonM.Coleman: Ah I'm sorry yeah it basically does not flush yet inside the flush method, that's apperantly a false naming convention. But still, I don't understand why the code does not work, Cors::display() is supposed to iterate all glVertex2f's, and then display them in glutSwapBuffers, right? – corsel Sep 27 '14 at 10:38
  • @datenwolf: It does have a definition in Glut_Functions.cpp (topmost code block). Did you miss that or did I do something wrong in the definition? – corsel Sep 27 '14 at 10:39
  • @cem: Sorry, I missed that. But then you must increment `Cors::shapeCount` somewhere. Why don't you just use a std::vector? – datenwolf Sep 27 '14 at 14:09
  • @datenwolf: I don't think that's the problem, I also have a main function (which I forgot to add here) and list is initialized there. When I add cout << "triangle (/quad/ellipse/etc.) flush called." in derived flush methods, they do get printed. The flush does get called correctly, but when called from another source file, the glvertex's disappear somehow. Even when I bypass shapelist totally, and add constant values to glvertex's (it's the case in my posted code, actually) it does not get rendered. When I make a function that queues up vertices inside glut_functions.cpp, the code works. – corsel Sep 27 '14 at 20:07
  • @cem: Did you make sure your drawing functions get called at all; did you add a print statement to see it gets actually called? BTW: Please rename your "flush" functions "draw". There's nothing flushed there. Enqueued maybe, but in OpenGL terms things are **drawn**. – datenwolf Sep 27 '14 at 21:49
  • @datenwolf I feel so embarrassed, the error has nothing to do with OpenGL at all, I made a mistake while externing variables and shapeCount goes zero, blocking the whole for loop. Thanks for your assistance everybody. – corsel Sep 29 '14 at 08:52
  • and I will fix the naming error with flush :) – corsel Sep 29 '14 at 12:06

0 Answers0