Problem mit OpenGL-Klasse und BCB
-
Hi Leute!
Wir haben in der Schule ein Projekt in OpenGL angefangen. Jetzt haben wir aber immer nur so Beispielcode bekommen, der schon alles fertig initialisiert etc. Aber das auf eine sehr unschöne art (scheuslicher Programmierstil). Jetzt hab ich mich dann der FAQ bedient und dadurch eine wesentlich schönere Methode gefunden mit dem BCB OpenGL zu initialisieren. Allerdings bekomme ich es jetzt nicht mehr hin, das er mir die Würfel meiner Klasse Cube zeichnet. Weder ein normales Rechteck, noch einen Würfel. Wenn ich ein Fenster selber erstelle per WinAPI, dann funktioniert das wunderbar. Aber läuft das ganze über die Art wie es in der FAQ steht, dann geht nichts mehr. Alles wird richtig initialisiert, aber er zeichnet mir keinen Würfel, nichts...
Hier mal meine Klasse Cube
Header
#include <windows.h> #include <gl/gl.h> #include <gl/glu.h> #include <gl/glaux.h> #include <math.h> class Cube { private: int m_cubearray_size; float m_x; float m_y; float m_z; float m_cubesize; GLColor col; void fillGLColor(void); protected: public: Cube(); Cube(int size); Cube(int size, int cubearray_size); ~Cube(); void setCubesize(int size) { m_cubesize = (float)size/10; }; void setCubearray_size(int cubearray_size) { m_cubearray_size = cubearray_size; }; float getCubesize() { return m_cubesize; }; int getCubearray_size() { return m_cubearray_size; }; void Quad(GLdouble n[], GLdouble v0[], GLdouble v1[], GLdouble v2[],GLdouble v3[], GLenum mode); void ColoredCube(GLdouble x0, GLdouble y0, GLdouble z0, GLdouble x1, GLdouble y1, GLdouble z1, GLenum mode); void CubeArray(); };
CPP
#include "cube.h" Cube::Cube() : m_cubesize(0.0), m_cubearray_size(4), m_x(0.0), m_y(0.0), m_z(0.0) { fillGLColor(); } Cube::Cube(int size) : m_cubearray_size(4), m_x(0.0), m_y(0.0), m_z(0.0) { m_cubesize = (float)size/10; fillGLColor(); } Cube::Cube(int size, int cubearray_size) : m_cubearray_size(cubearray_size), m_x(0.0), m_y(0.0), m_z(0.0) { m_cubesize = (float)size/10; fillGLColor(); } Cube::~Cube() { } void Cube::fillGLColor(void) { col.colRed[0] = 1; col.colRed[1] = 0; col.colRed[2] = 0; col.colGreen[0] = 0; col.colGreen[1] = 1; col.colGreen[2] = 0; col.colBlue[0] = 0; col.colBlue[1] = 0; col.colBlue[2] = 1; col.colYellow[0] = 1; col.colYellow[1] = 1; col.colYellow[2] = 0; col.colBlack[0] = 0; col.colBlack[1] = 0; col.colBlack[2] = 0; col.colWhite[0] = 1; col.colWhite[1] = 1; col.colWhite[2] = 1; } void Cube::Quad(GLdouble n[], GLdouble v0[], GLdouble v1[], GLdouble v2[],GLdouble v3[], GLenum mode) { // Viereck mit den Eckpunkten v0, v1, v2 und v3 glBegin(mode); glNormal3dv(n); // Normale glVertex3dv(v0); glVertex3dv(v1); glVertex3dv(v2); glVertex3dv(v3); glEnd(); } void Cube::ColoredCube(GLdouble x0, GLdouble y0, GLdouble z0, GLdouble x1, GLdouble y1, GLdouble z1, GLenum mode) { // Wire Cube: mode = GL_LINE_LOOP, Gefüllte Seiten: mode = GL_QUADS // Sichergehen das x0 <= x1, y0 <= y1 und z0 <= z1: GLdouble tmp; if (x0 > x1) { tmp = x0; x0 = x1; x1 = tmp; } if (y0 > y1) { tmp = y0; y0 = y1; y1 = tmp; } if (z0 > z1) { tmp = z0; z0 = z1; z1 = tmp; } GLdouble v[8][3] = // ecken v[5] ---- v[6] {{x0,y0,z1}, //=v[0] /| /| {x0,y1,z1}, //=v[1] v[1] ---- v[2]| {x1,y1,z1}, //=v[2] | | | | {x1,y0,z1}, //=v[3] | | | | {x0,y0,z0}, //=v[4] | | | | {x0,y1,z0}, //=v[5] | v[4] ---| v[7] {x1,y1,z0}, //=v[6] |/ |/ {x1,y0,z0}}; //=v[7] v[0] ---- v[3] GLdouble FrontNormal[] = {0,0,1}, BackNormal[] = { 0, 0,-1}, RightNormal[] = {1,0,0}, LeftNormal[] = {-1, 0, 0}, UpNormal[] = {0,1,0}, DownNormal[] = {0,-1, 0}; glColor3fv(col.colRed); Quad(FrontNormal, v[0], v[1], v[2], v[3], mode); // vorne glColor3fv(col.colRed); Quad(RightNormal, v[3], v[2], v[6], v[7], mode); // rechts glColor3fv(col.colRed); Quad(BackNormal, v[4], v[5], v[6], v[7], mode); // hinten glColor3fv(col.colRed); Quad(LeftNormal, v[0], v[1], v[5], v[4], mode); // links glColor3fv(col.colBlue); Quad(UpNormal, v[1], v[5], v[6], v[2], mode); // oben glColor3fv(col.colBlue); Quad(DownNormal, v[0], v[4], v[7], v[3], mode); // unten } void Cube::CubeArray() { int a = 0; int x = m_cubearray_size; int zeile = 0; int block = 0; bool b_block = false; while(a < (int)pow(m_cubearray_size, 3)) { m_x = 0.0; //m_cubearray_size * m_cubearray_size Cubes gezeichnet, auf z-Achse 1 nach vorne if((zeile % m_cubearray_size == 0 && zeile > 0) || b_block) //oder block > 0? { m_z = (m_cubesize*2*(block)); m_y = 0.0; b_block = true; if(zeile % m_cubearray_size == 0) zeile = 0; } //eine Reihe fertig, dann auf y-Achse 1 nach oben if(a % m_cubearray_size == 0 && a > 0) m_y = (m_cubesize*2*(zeile)); //eine Reihe zeichnen for(int j = 0; j<x; j++) { //Cube zeichnen glPushMatrix(); glTranslatef(m_x, m_y, m_z); ColoredCube(-m_cubesize, -m_cubesize, -m_cubesize, m_cubesize, m_cubesize, m_cubesize, GL_LINE_LOOP); m_x = (m_cubesize*2); m_y = 0.0; m_z = 0.0; a++; } zeile++; //ein Block fertig, block um 1 erhöhen if(zeile % m_cubearray_size == 0) block++; for(int k = 0; k<x; k++) glPopMatrix(); } }
Und hier mal die Implementierung in der Form. (wie im FAQ Beispiel halt)
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Application->OnIdle = IdleLoop; _control87(MCW_EM, MCW_EM); cube = new Cube(4,4); } //--------------------------------------------------------------------------- void __fastcall TForm1::IdleLoop(TObject* Object, bool& done) { done = false; DrawGLScene(); SwapBuffers(hdc); } //--------------------------------------------------------------------------- void __fastcall TForm1::DrawGLScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(x, y, -8.0); //Wired Cube Array zeichnen cube->CubeArray(); glFlush(); } void __fastcall TForm1::FormCreate(TObject *Sender) { hdc = GetDC(Handle); SetPixelFormatDescriptor(); hrc = wglCreateContext(hdc); wglMakeCurrent(hdc, hrc); SetupRC(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { ReleaseDC(this->Handle, hdc); wglMakeCurrent(hdc, NULL); wglDeleteContext(hrc); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormResize(TObject *Sender) { GLfloat nRange = 0.0f; glViewport(0, 0, ClientWidth, ClientHeight); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (ClientWidth <= ClientHeight) glOrtho(-nRange, nRange, -nRange*ClientHeight/ClientWidth, nRange*ClientHeight/ClientWidth, -nRange, nRange); else glOrtho(-nRange*ClientWidth/ClientHeight, nRange*ClientWidth/ClientHeight, -nRange, nRange, -nRange, nRange); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } //--------------------------------------------------------------------------- void __fastcall TForm1::SetPixelFormatDescriptor() { PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 24, 0,0,0,0,0,0, 0,0, 0,0,0,0,0, 32, 0, 0, PFD_MAIN_PLANE, 0, 0,0,0 }; PixelFormat = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, PixelFormat, &pfd); } void __fastcall TForm1::SetupRC() { glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); glFlush(); }
Vielleicht wisst ihr ja worans liegen kann, dass ich nichts dargestellt bekomme?!
-
Hab den Fehler gefunden
Lag daran, das ich in DrawGLScene() den Code aus SetupRC() wiederholt habe. Jetzt läufts!