OpenGL mit c++ - Klassen
Ich versucht habe, etwas zu schreiben, die lassen mich einfach zu verwalten OpenGL mit Klassen.
Nahm ich einen Ansatz, der mit einem Drawable-Klasse [die Formen/etc würde vererben und überschreiben, eine zeichnen-Funktion], und dann mit einer Controller-Klasse zum Durchlaufen einer Tabelle der Drawable-Klassen und zeichnen Sie alle.
Das einzige Problem, das ich habe bemerkt, dass die draw () - Methode aufgerufen wird, von der Drawable-Klasse, anstelle der Rechteck-Klasse. ??
class Drawable {
public:
void draw();
};
class Rectangle : public Drawable {
public:
void draw();
};
class Controller {
public:
Drawable ents[200];
int ent_count;
void frame();
void append(Drawable item); //this will add an object onto the list
Controller();
};
void Drawable::draw() {
//this is the default drawing function, which should be overridden
}
void Rectangle::draw() {
//gl functions here
}
void Controller::frame() {
for(int i=0;i<ent_count,i++) {
ents[i].draw(); //draw all entities on the list
}
//here, a timer would loop back the frame() function
}
void Controller::append(Drawable item) {
ents[ent_count++]=item;
}
int main(void) {
Controller main_controller; //create a controller
Rectangle rect; //create a rectangle
main_controller.append(rect); //insert rectangle into controller list
main_controller.frame(); //start the frame loop
}
[wenn es um kleine Tippfehler in, dass es ist, weil es geschrieben wurde, als eine Zusammenfassung der Methode.]
Diese Methode, die ich versucht habe zu verwenden, ist nicht sehr erfolgreich gewesen, und ich bin mir ziemlich sicher, dass es hat zu tun mit der Vererbung.
Irgendwelche Ideen?
Gesamten source-code:
#include <iostream>
#include <GL/glfw.h>
#include <GL/gl.h>
class Drawable {
public:
int x,y;
void draw();
void frame();
void create();
void destroy();
};
void Drawable::create() {
}
void Drawable::draw() {
}
class Rectangle : public Drawable {
public:
int w,h;
unsigned short r,g,b;
Rectangle(int x,int y, int w, int h, unsigned short r, unsigned short g, unsigned short b);
void draw();
};
void Rectangle::draw() {
glColor3ub(r,g,b);
glBegin(GL_QUADS);
glVertex2i(x,y);
glVertex2i(x+w,y);
glVertex2i(x+w,y+h);
glVertex2i(x,y+h);
glEnd();
}
Rectangle::Rectangle(int x,int y, int w, int h, unsigned short r, unsigned short g, unsigned short b) {
this->x=x;
this->y=y;
this->w=w;
this->r=r;
this->g=g;
this->b=b;
}
class Controller {
public:
Controller(int w,int h,int fsaa,bool fs,bool vsync,const char* title);
bool running;
int frame_limit;
Drawable entity[200];
int entity_count;
void fev();
void begin();
void bind();
void append(Drawable item);
};
Controller::Controller(int w,int h,int fsaa,bool fs,bool vsync,const char* title) {
int fullscreen= (fs ? GLFW_FULLSCREEN : GLFW_WINDOW);
bool window=glfwOpenWindow(w,h,0,0,0,0,10,10,fullscreen);
glfwSetWindowTitle(title);
frame_limit=120;
entity_count=0;
std::cout << (window ? "Successfully initialized a window.\n" : "Error initializing window!\n");
}
void Controller::begin() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0,640,480,0,0,5);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.4f,0.4f,0.4f,1.0f);
running=true;
fev();
}
void Controller::append(Drawable item) {
entity[entity_count++]=item;
}
void Controller::fev() {
glClear(GL_COLOR_BUFFER_BIT);
for (int i=0;i<entity_count;++i) {
entity[i].draw();
}
glfwSwapBuffers();
if (frame_limit>0) {
glfwSleep(1000/frame_limit*0.001);
}
if (running) {
if (glfwGetKey(GLFW_KEY_ESC) || !glfwGetWindowParam(GLFW_OPENED)) {
running=false;
}
fev();
} else {
std::cout << "terminated!";
}
}
int main(void) {
glfwInit();
Controller main(640,480,0,false,false,"WindTitle");
Rectangle rect(50,50,50,50,50,50,50);
main.append(rect);
main.begin();
}
- Vielleicht möchten Sie erwägen Blick auf vorhandene C++ - Wrapper, wie OGLplus: oglplus.org
- Als Hinweis, denken Sie daran, dass OpenGL ist eine finite-state-Maschine. So haben Sie, um sicherzustellen, dass alle von Ihrer Klasse Methoden/Klassen verlassen, dass die Maschine, in was Sie betrachten, ein "sicherer" Zustand (oder "erwartet" - Zustand)
- Versuchen Sie, draw () - virtuelle.
- Es hatte keine Wirkung, wenn ich aus der draw() virtual sowohl im Rechteck und in Drawable.
- Wenn Ihr eine Frage über Fehler, es ist immer hilfreich, eigentlich gehören die Fehler, die Sie erhalten. Es sollte komplett und ungeschnitten. Es wird auch gut sein, wenn Sie darauf hinweisen könnte, in der geposteten Quelle der Linien, die Fehler werden über.
- Naja, um ehrlich zu sein, es gibt keine Fehler, es ist nur so, dass die draw () - Methode in der Drawable-Objekt aufgerufen wird, statt der im Rechteck.
- Und ein hilfreicher Tipp: Bitte verwenden Sie nicht roh-arrays,
std::vector
. Es wird Ihr Leben viel einfacher auf lange Sicht - Sie sagen, es wurde "geben Sie die Fehler Links und rechts"? Und das problem mit
Drawable::draw
genannt wird, weil es nichtvirtual
. - Behoben die Frage, und wie ich bereits antwortete, was Drawable::draw() virtual hatte keine Wirkung, ebenso wie Rectangle::draw() virtuelle.
- Würde man nur brauchen, um Drawable::draw() virtuelle hier. Kratzen diese heraus bringen würde, die Sie weiter von der Lösung.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wie andere erwähnt haben, wäre es am besten, um zu versuchen, einige der bestehenden Wrapper.
Dieser sagte, müssen Sie die Zeiger für die Liste der Entitäten. Sie haben Probleme mit schneiden.
Als einige der Kommentare erwähnt, die Sie brauchen, um
Drawable::draw()
virtuellen so aufrufendraw()
auf eineDrawable
wird ein Anruf über das Kind der Umsetzung. Das sagte, weil Sie mit dem hinzufügen IhrerDrawable
s auf eine Liste von Objekten, anstatt eine Liste von Zeigern auf Objekte, die Objekte werden in Scheiben geschnitten. Dies bedeutet, dass Sie sind seiend umgewandelt von der Kind-Typ zurück inDrawable
Objekte, das entfernen der zusätzlichen Angaben über bestimmte Arten.Also statt dieser:
Sollten Sie etwas wie das hier tun:
oder wenn Sie C++11 oder-Boost:
Und den append-Methode würde eine Referenz.
oder
oder
Und Ihre render-Schleife würde so Aussehen:
Diese Schleife könnte auch gereinigt werden, um
iterator
.vector_ptr
vielleicht ein besseres Werkzeug für den jobNeulinge versuchen oft, diesem. Aber OpenGL ist wirklich nicht gut übersetzen in OOP. Das problem ist, dass es ein finite-state-Maschine und um die Karte richtig zu OOP müsste man zu viel Staat tracking zwischen den verschiedenen Klassen und Instanzen.
Ich selbst versuchte mich mindestens 3 mal zu abstrahieren, OpenGL in eine OOP-Schema. Es ist immer brach in gewisser Weise.
Welche ist nicht zu sagen, dass Sie nicht verwenden können, OOP mit OpenGL. Sie können nicht nur anzeigen OpenGL-Konzepte 1:1 in die Klassen.
Bezüglich Ihres eigentlichen Problems: die Verwendung von virtuellen Funktionen.
Möchten Sie vielleicht einen Blick auf Coin3D. Es ist eine große, reiche Gruppe von C++ - Klassen-Wrapper für OpenGL. Sie clould entweder sehen, wie Sie tun Dinge, die nur Sie verwenden. Es gibt Bibliotheken für die integration mit verschiedenen windowing-Systeme (Qt, Windows, Kakao, ...).