Background Information
I'm currently taking a computer graphics class. The way we're learning the main concepts is by making an abstraction that anyone could use (aka a simple 3D library). We're using SDL for the real graphics part. Actually, all we use SDL for is to render and manipulate a pixel buffer. We're only allowed to use that. But our abstraction is supposed to allow the client to draw pixels, lines, triangles, etc. all the way to complete models composed of those triangles.
Things were going along pretty smoothly... until the professor took a look at my abstraction. He said it wasn't very object oriented.
My Question
I'm not looking so much for a review of my code, as I'm looking for some general advice and suggestions on how to design this SDL library using sound Object Oriented principles.
What I have so far
My code actually makes good use of some object oriented principles. I have the following objects working fine so far:
- Vec4 - represents coordinates or colors. It does operations related to vectors.
- Mat4 - represents a 4x4 matrix that I use for transformations and such. Does operations related to matrices, such as multiply by another matrix, by a vec4, etc.
- MatrixFactory - creates different types of Mat4 (MatrixTranslate, MatrixRotate, etc)
- Shape - an interface used to make drawing various shapes easier
- Dot : Shape
- Line : Shape
- Triangle : Shape
My "engine" itself does the following (based somewhat on the three.js structure):
- Creates a window (the main window where things are drawn)
- Creates a scene (where shapes are displayed)
- Registers callback functions based on keyboard events (key presses)
Where I'm struggling specifically
The main thing I'm struggling with so far is handling callbacks. For instance, to draw a triangle, I currently do something like the following:
int main()
{
// Create instance of my library
RDL* rdl = new RDL(WIDTH, HEIGHT, 32);
// Draw a triangle when T is pressed
// RDL_KEY_t = #define RDL_KEY_t SDLK_t for consistency
rdl->registerKeyEvent(RDL_KEY_t, drawTriangle);
rdl->show();
return 0;
}
// X, Y, Z and R, G, B are random values not shown for simplicity
void drawTriangle(RDL* rdl)
{
RDL_Point p1(Vec4(X, Y, Z), Vec4(R, G, B));
RDL_Point p2(Vec4(X, Y, Z), Vec4(R, G, B));
RDL_Point p3(Vec4(X, Y, Z), Vec4(R, G, B));
rdl->insertShape(RDL_Triangle(pt1, pt2, pt3));
}
Inside RDL::show() I run the standard SDL loop where I do 2 things:
- Call any registered callbacks
- Drawn shapes in my vector where all shapes are stored
But this is no good. If I insert 10 triangles, they all draw nicely. But if I want to rotate a specific one, I can't do that because my callbacks only give me access to my RDL object from main.
Any ideas, tips, or general advice?
Thank you very much. I know this is a long question...