OpenGL (mit Glut) 3D Würfel

baum77

Grünschnabel
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
 
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.
Code:
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
 
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.
Code:
 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
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.
 

Anhänge

  • tetris.JPG
    tetris.JPG
    27,6 KB · Aufrufe: 1.024
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();
 

Anhänge

  • test.JPG
    test.JPG
    2,6 KB · Aufrufe: 5.122
Zuletzt bearbeitet:
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)
 
Zum Beispiel so:
Code:
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.
 
Habe einen auf deinem Code basierenden sich drehenden Würfel geschrieben:

C++:
/**************************
 * 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
 
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
 
Zurück