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!


Anmelden zum Antworten