# OpenGL (mit Glut) 3D Würfel



## baum77 (5. Mai 2005)

Hallo,

    wir versuchen zur Zeit einen 3D Würfel mit OpenGL (oder auch GLUT) zu erzeugen. (Borland C++ Builder 5)
    Eine Möglichkeit haben wir auch schon gefunden:

  void glutSolidCube(GLdouble size);
   void glutWireCube(GLdouble size);

   siehe http://www.opengl.org/resources/libraries/glut/spec3/node82.html

   Das Problem ist nur das man hier leider keine x,y,z Koordinaten angeben kann,
   so dass der Würfel an einer bestimmten Position erzeugt wird.
   Mit 2D Würfel war dies kein Problem:

   Bsp:

   glBegin(GL_QUADS);
    glColor3f(0.0,0.0,0.0);
    glVertex2i(100,200);
    glVertex2i(100,100);
    glVertex2i(200,100);
    glVertex2i(200,200);
   glEnd();

   Weiß jemand eine Möglichkeit den oben gennanten (oder aber auch einen ganz anderen) 3D Würfel 
   zu erzeugen und an beliebige Positionen zu verschieben?

   Vielen Dank im Vorraus


----------



## Patrick Kamin (5. Mai 2005)

Hallo,
wenn du mit den glut-Funktionen einen Würfel zeichnest, werden diese im Ursprung gezeichnet, du müsstest also vorher eine Translation der Modelview Matrix vornehmen.

```
glTranslatef(0.0, 0.0, 10.0);
//glut-Funktion für deinen Cube
```

Du kannst einen Würfel natürlich auch selber per Hand zeichnen, besteht ja immerhin aus 6 Quads 

Viel Erfolg
Patrick


----------



## baum77 (5. Mai 2005)

Patrick Kamin hat gesagt.:
			
		

> Hallo,
> wenn du mit den glut-Funktionen einen Würfel zeichnest, werden diese im Ursprung gezeichnet, du müsstest also vorher eine Translation der Modelview Matrix vornehmen.
> 
> ```
> ...


 Ja das funktioniert, danke.

 Aber unser eigentliches Problem löst es trotzdem nicht  (hab ich oben aber auch noch nicht gefragt)

 Wir sind dabei ein Tetris Spiel in OpenGL zu programmieren.
 Die 2D Version ist auch schon fertig, eine 3D "ähnliche" Version auch (siehe Anhang).

 Nur ist das eben eine 3D "ähnliche" Version, weil wir dazu einfach 2D Befehle verwendet haben.
 OpenGL bietet aber eine Z-Achse, mit der dies auch gehen müsste.

 Wie machen wir das am einfachsten, dass es so ähnlich aussieht wie im Anhang?

 Das mit dem glSolidCube funktioniert ja auch nicht, da man das auch nicht so richtig "in die Tiefe" sieht.

 Zur Erklärung: Jeder Stein unseres Tetris besteht aus 4 einzelnen Würfeln, die zusammengesetzt sind.


----------



## Matthias Reitinger (5. Mai 2005)

Warum sieht man denn die Würfel bei euch nicht "in die Tiefe"? Poste doch mal einen Screenshot von euerem 3D-Versuch.


----------



## baum77 (5. Mai 2005)

Matthias Reitinger hat gesagt.:
			
		

> Warum sieht man denn die Würfel bei euch nicht "in die Tiefe"? Poste doch mal einen Screenshot von euerem 3D-Versuch.


 [Edit]
 Tetris direkt haben wir noch nicht versucht, aber einen 3D Würfel (nach Anleitung) erstellt, und da sah man aber leider auch nur die vordere Fläche.
  Nur nach schwenken der Kameraperspektive sah man das er in die Tiefe geht.
  Problem daran, es soll ja für jeden Stein gleich aussehen, so wie auf dem oberen Bild.
  Wenn man dann die Kamera dreht, ist das ja nicht mehr so.

 Hier der 3D Würfel:
 glBegin(GL_QUADS); // Vierecke zeichnen


   glColor3f(0.0f,1.0f,0.0f); 
   glVertex3f( 1.0f, 1.0f,-1.0f); 
   glVertex3f(-1.0f, 1.0f,-1.0f); 
   glVertex3f(-1.0f, 1.0f, 1.0f); 
   glVertex3f( 1.0f, 1.0f, 1.0f); 

    glColor3f(1.0f,0.5f,0.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f); 
    glVertex3f(-1.0f,-1.0f, 1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f); 


    glColor3f(1.0f,0.0f,0.0f); 
    glVertex3f( 1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f); 
    glVertex3f(-1.0f,-1.0f, 1.0f); 
    glVertex3f( 1.0f,-1.0f, 1.0f); 

    glColor3f(1.0f,1.0f,0.0f); 
    glVertex3f( 1.0f,-1.0f,-1.0f); 
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f( 1.0f, 1.0f,-1.0f); 


    glColor3f(0.5f,0.5f,0.5f); 
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f); 
    glVertex3f(-1.0f,-1.0f,-1.0f); 
    glVertex3f(-1.0f,-1.0f, 1.0f);


    glColor3f(1.0f,0.0f,1.0f); 
    glVertex3f( 1.0f, 1.0f,-1.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f); 
    glVertex3f( 1.0f,-1.0f, 1.0f); 
    glVertex3f( 1.0f,-1.0f,-1.0f); 

   glEnd();


----------



## Matthias Reitinger (5. Mai 2005)

Dann verwende doch einfach eine orthogonale Projektionsmatrix (glOrtho), dann klappt's auch mit der Parallelprojektion


----------



## baum77 (5. Mai 2005)

Matthias Reitinger hat gesagt.:
			
		

> Dann verwende doch einfach eine orthogonale Projektionsmatrix (glOrtho), dann klappt's auch mit der Parallelprojektion


 Kannst du mir das bitte genauer erklären?
 (hab meinen vorherigen Post übrigens etwas geändert und ergänzt)


----------



## Matthias Reitinger (5. Mai 2005)

Zum Beispiel so:

```
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, 5, 100);
```
Damit erhältst du eine Parallelprojektion, sprich: im Raum parallele Geraden erscheinen auch in der Projektion parallel. Mit dieser Projektionsmatrix erstellst du dann munter deine Würfel, drehst sie vielleicht etwas (bzw. die Kamera), und dann sollte es eigentlich ähnlich dem Screenshot von dir aussehen.


----------



## KrokantKrockete (20. April 2007)

Habe einen auf deinem Code basierenden sich drehenden Würfel geschrieben:


```
/**************************
 * Includes
 *
 **************************/

#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>


/**************************
 * Function Declarations
 *
 **************************/

LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);
float rotateLinks=1.0f;
float rotateRechts=1.0f;
float rotateOben=1.0f;
float rotateUnten=1.0f;

/**************************
 * WinMain
 *
 **************************/

int WINAPI
WinMain (HINSTANCE hInstance,
         HINSTANCE hPrevInstance,
         LPSTR lpCmdLine,
         int iCmdShow)
{
    WNDCLASS wc;
    HWND hWnd;
    HDC hDC;
    HGLRC hRC;
    MSG msg;
    BOOL bQuit = false;
    float theta = 0.0f;

    /* register window class */
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "GLSample";
    RegisterClass (&wc);

    /* create main window */
    hWnd = CreateWindow (
      "GLSample", "OpenGL Sample",
      WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
      0, 0, 512, 512,
      NULL, NULL, hInstance, NULL);

    /* enable OpenGL for the window */
    EnableOpenGL (hWnd, &hDC, &hRC);

    /* program main loop */
    while (!bQuit)
    {
        /* check for messages */
        if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
        {
            /* handle or dispatch messages */
            if (msg.message == WM_QUIT)
            {
                bQuit = TRUE;
            }
            else
            {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
            }
        }
        else
        {
            /* OpenGL animation code goes here */

            glClearColor (0.0f, 0.0f, 0.0f, 0.0f);
            glClear (GL_COLOR_BUFFER_BIT);

            glPushMatrix ();

rotateRechts+=0.1f;
rotateLinks+=0.1f;
rotateOben+=0.1f;
rotateUnten+=0.1f;
glRotatef(rotateLinks, rotateRechts, rotateOben, rotateUnten); // glRotatef(1.0f,0.0f,0.0f,1.0f);

            glBegin(GL_QUADS); // Vierecke zeichnen
//glutSolidCube();

glColor3f(0.0f,1.0f,0.0f);
glVertex3f( 0.5f, 0.5f,0.5f);
glVertex3f(-0.5f, 0.5f,-0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f, 0.5f, 0.5f);

glColor3f(1.0f,0.5f,0.0f);
glVertex3f( 0.5f,-0.5f, 0.5f);
glVertex3f(-0.5f,-0.5f, 0.5f);
glVertex3f(-0.5f,-0.5f,-0.5f);
glVertex3f( 0.5f,-0.5f,-0.5f);


glColor3f(1.0f,0.0f,0.5f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f,-0.5f, 0.5f);
glVertex3f( 0.5f,-0.5f, 0.5f);

glColor3f(1.0f,1.0f,0.0f);
glVertex3f( 0.5f,-0.5f,-0.5f);
glVertex3f(-0.5f,-0.5f,-0.5f);
glVertex3f(-0.5f, 0.5f,-0.5f);
glVertex3f( 0.5f, 0.5f,-0.5f);


glColor3f(0.5f,0.5f,0.5f);
glVertex3f(-0.5f, 0.5f, 0.5f);
glVertex3f(-0.5f, 0.5f,-0.5f);
glVertex3f(-0.5f,-0.5f,-0.5f);
glVertex3f(-0.5f,-0.5f, 0.5f);


glColor3f(1.0f,0.0f,1.0f);
glVertex3f( 0.5f, 0.5f,-0.5f);
glVertex3f( 0.5f, 0.5f, 0.5f);
glVertex3f( 0.5f,-0.5f, 0.5f);
glVertex3f( 0.5f,-0.5f,-0.5f);

glEnd();

            glPopMatrix ();

            SwapBuffers (hDC);

            theta += 1.0f;
            Sleep (1);
        }
    }

    /* shutdown OpenGL */
    DisableOpenGL (hWnd, hDC, hRC);

    /* destroy the window explicitly */
    DestroyWindow (hWnd);

    return msg.wParam;
}


/********************
 * Window Procedure
 *
 ********************/

LRESULT CALLBACK
WndProc (HWND hWnd, UINT message,
         WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
    case WM_CREATE:
        return 0;
    case WM_CLOSE:
        PostQuitMessage (0);
        return 0;

    case WM_DESTROY:
        return 0;

    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_ESCAPE:
            PostQuitMessage(0);
            return 0;
        }
        return 0;

    default:
        return DefWindowProc (hWnd, message, wParam, lParam);
    }
}


/*******************
 * Enable OpenGL
 *
 *******************/

void
EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;

    /* get the device context (DC) */
    *hDC = GetDC (hWnd);

    /* set the pixel format for the DC */
    ZeroMemory (&pfd, sizeof (pfd));
    pfd.nSize = sizeof (pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW |
      PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    iFormat = ChoosePixelFormat (*hDC, &pfd);
    SetPixelFormat (*hDC, iFormat, &pfd);

    /* create and enable the render context (RC) */
    *hRC = wglCreateContext( *hDC );
    wglMakeCurrent( *hDC, *hRC );

}


/******************
 * Disable OpenGL
 *
 ******************/

void
DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent (NULL, NULL);
    wglDeleteContext (hRC);
    ReleaseDC (hWnd, hDC);
}
```

mfg KrokantKrockete


----------



## Shab (10. Dezember 2012)

Hallo, 
kann mir jemand sagen wie ich so eine 3d "ähnliche" Version von einem Objekt ( z.B. ein Rechteck) mit Opengl zeichnen kann? 
Ich weiss nicht genau wonach ich in google suchen soll.
Danke im Voraus


----------



## ibafluss (10. Dezember 2012)

Schau dir am besten dazu einmal die NeHe Tutorials an. Ich hab dir hier den Link direkt zum Kapitel gepostet, in dem die 3D-Figuren gezeichnet werden. Solltest du mit dem Code nicht zurechtkommen, lies dir einfach die Tutorials davor durch: http://nehe.gamedev.net/tutorial/3d_shapes/10035/

Lg


----------



## Shab (10. Dezember 2012)

Hallo Ibafluss, 
danke für deine schnelle Antwort.
Ich weiss ungefähr wie man 3-dimensionale Objekte zeichnet, aber relativ am Anfang dieser Thema, hat baum77 ein Bild von einem Tetris-Spiel angehänt, welches 3-dimensional aussieht, aber eigentlich nur 2-dimensional gezeichnet wurde. Ich wollte wissen wie man sowas hinkriegt? 
Danke


----------



## ibafluss (12. Dezember 2012)

Was meinst du mit es wurde 2-dimensional gezeichnet? Grundsätzlich kann man am Computer ja nur 2-dimensional zeichnen, der Bildschirm ist ja nicht 3-dimensional 
Nein Spaß beiseite, das sind ganz normale 3-dimensionale Objekte, die er da hat, die sind nicht 2-dimensional, sie gehen ja nach hinten.
Oder habe ich dich jetz falsch verstanden?

Lg


----------



## Shab (13. Dezember 2012)

hmmm ich dachte baum77 hat diesen Thread aufgemacht, weil er Hilfe beim 3d-zeichnen brauchte. 
Er hat ein Bild aufgehängt, wo er ein Würfel gezeichnet hat und man sieht ihn nur als Quadrat.
Er hat geschrieben, dass er eine "3d-ähnliche Version" schon gemacht hat,(siehe Tetris-Spiel, oben) aber um wirklich sein Spiel 3d darzustellen brauchte er Hilfe. Deshalb wollte ich wissen, wie er diese "3d-ähnliche Version" gemacht hat.
Aber kann sein, dass ich mich geirrt habe.
Trotzdem vielen Dank.


----------

