OpenGL + C++ : 3D triangulation

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • McGruber
    New Member
    • May 2007
    • 1

    OpenGL + C++ : 3D triangulation

    Hi, guys. Currently I am researching the optimised algorithms of building triangulations of 3D surfaces. And I faces the problem with visualization of the 3D triangulation. I tried to do it with OpenGL, but I couldn't set the point of view correctly. Can anybody help me?
    This is my MFC dialog for visualization:
    Code:
    #include "stdafx.h"
    #include "Terrain.h"
    #include "TerrainDisplay3D.h"
    
    #include <GL/gl.h>
    #include <GL/glaux.h>
    
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    
    #define WIDTH 550 
    #define HEIGHT 550
    #define SPEED 1
    
    CTerrainDisplay3D::CTerrainDisplay3D(CWnd* pParent /*=NULL*/)
    	: CDialog(CTerrainDisplay3D::IDD, pParent)
    {
    	//{{AFX_DATA_INIT(CTerrainDisplay3D)
    		// NOTE: the ClassWizard will add member initialization here
    	//}}AFX_DATA_INIT
    }
    
    void CTerrainDisplay3D::DoDataExchange(CDataExchange* pDX)
    {
    	CDialog::DoDataExchange(pDX);
    	//{{AFX_DATA_MAP(CTerrainDisplay3D)
    		// NOTE: the ClassWizard will add DDX and DDV calls here
    	//}}AFX_DATA_MAP
    }
    
    BEGIN_MESSAGE_MAP(CTerrainDisplay3D, CDialog)
    	//{{AFX_MSG_MAP(CTerrainDisplay3D)
    	ON_WM_TIMER()
    	ON_WM_CLOSE()
    	ON_WM_DESTROY()
    	//}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    
    /////////////////////////////////////////////////////////////////////////////
    // CTerrainDisplay3D message handlers
    
    BOOL CTerrainDisplay3D::PreCreateWindow(CREATESTRUCT &cs)
    {
    	cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
    	return CDialog::PreCreateWindow(cs);
    }
    
    BOOL CTerrainDisplay3D::OnInitDialog() 
    {
    	CDialog::OnInitDialog();
    	
    	SetWindowPos(&wndTop, 0, 0, WIDTH, HEIGHT, SWP_NOMOVE);
    	pDC = GetDC();
    	CenterWindow();
    	Init();
    	SetTimer(1,SPEED, NULL);
    		
    	return TRUE;  // return TRUE unless you set the focus to a control
    	              // EXCEPTION: OCX Property Pages should return FALSE
    }
    
    void CTerrainDisplay3D::Init()
    {
    	CRect rect;
    	HGLRC hrc;
    	if (!bSetupPixelFormat())
    		return;
    	hrc = wglCreateContext(pDC->GetSafeHdc());
    	ASSERT(hrc != NULL);
    	wglMakeCurrent(pDC->GetSafeHdc(), hrc);
    
    	GetClientRect(&rect);
    
    	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    	glShadeModel(GL_SMOOTH);
    
    	glViewport(0,0,WIDTH,HEIGHT);
    
    	glMatrixMode(GL_PROJECTION);
    	glLoadIdentity();
    
                glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
    
    	glMatrixMode(GL_MODELVIEW);
    	gluLookAt (4, 4, 5, 
    				4, 4, 0, 
    				0, 0, 0);
    
    }
    
    BOOL CTerrainDisplay3D::bSetupPixelFormat()
    {
    	static PIXELFORMATDESCRIPTOR pfd =
    	{
    		sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
    		1, // version number
    		PFD_DRAW_TO_WINDOW | // support window
    		PFD_SUPPORT_OPENGL | // support OpenGL
    		PFD_DOUBLEBUFFER, // double buffered
    		PFD_TYPE_RGBA, // RGBA type
    		24, // 24-bit color depth
    		0, 0, 0, 0, 0, 0, // color bits ignored
    		0, // no alpha buffer
    		0, // shift bit ignored
    		0, // no accumulation buffer
    		0, 0, 0, 0, // accum bits ignored
    		32, // 32-bit z-buffer
    		0, // no stencil buffer
    		0, // no auxiliary buffer
    		PFD_MAIN_PLANE, // main layer
    		0, // reserved
    		0, 0, 0 // layer masks ignored
    	};
    
    	int pixelformat;
    
    	if ((pixelformat = ChoosePixelFormat(pDC->GetSafeHdc(), &pfd)) == 0)
    	{
    		MessageBox("ChoosePixelFormat failed");
    		return FALSE;
    	}
    
    	if (SetPixelFormat(pDC->GetSafeHdc(), pixelformat, &pfd) == FALSE)
    	{
    		MessageBox("SetPixelFormat failed");
    		return FALSE;
    	}
    	return TRUE;
    }
    
    void CTerrainDisplay3D::OnTimer(UINT nIDEvent) 
    {
    	DrawScene();
    	CDialog::OnTimer(nIDEvent);
    }
    
    void CTerrainDisplay3D::DrawScene()
    {
    	glPushMatrix();
    
    	float m = WIDTH / m_triangulation.getSize();
    	int c = 0;
    	int Ax,Ay,Bx,By,Cx,Cy;
    	while (c < m_triangulation.triangles.size()){
    		Ax = m_triangulation.triangles[c].x;
    		Ay = m_triangulation.triangles[c].y;
    		c++;
    		Bx = m_triangulation.triangles[c].x;
    		By = m_triangulation.triangles[c].y;
    		c++;
    		Cx = m_triangulation.triangles[c].x;
    		Cy = m_triangulation.triangles[c].y;
    		c++;
    
    		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    		glBegin(GL_TRIANGLE_STRIP);
    			glColor3ub(255,255,255); // белый
    			glVertex3f(Ax, Ay, m_triangulation.heightField[Ax][Ay]);
    			glVertex3f(Bx, By, m_triangulation.heightField[Bx][By]);
    			glVertex3f(Cx, Cy, m_triangulation.heightField[Cx][Cy]);
    		glEnd();
    	}
    
    	glPopMatrix();
    
    	SwapBuffers(pDC->m_hDC);
    }
    
    void CTerrainDisplay3D::OnClose() 
    {
    	HGLRC hrc;
    	KillTimer(1);
    	hrc = ::wglGetCurrentContext();
    	::wglMakeCurrent(NULL, NULL);
    	if (hrc)
    		::wglDeleteContext(hrc);
    	
    	CDialog::OnClose();
    }
    
    void CTerrainDisplay3D::OnDestroy() 
    {
    	CDialog::OnDestroy();
    	
    	HGLRC hrc;
    	KillTimer(1);
    	hrc = ::wglGetCurrentContext();
    	::wglMakeCurrent(NULL, NULL);
    	if (hrc)
    		::wglDeleteContext(hrc);
    	
    }
    The problem is in Init() and DrawScene(). m_triangulation is my own class with all information about mesh,and the part with drawing is correct, I only need to set the poin of view rightly.
  • Motoma
    Recognized Expert Specialist
    • Jan 2007
    • 3236

    #2
    What exactly is the problem you are having? You mention that it is the init() funciton...What causes you to think this?

    Comment

    • luckyyyyyy
      New Member
      • Oct 2007
      • 14

      #3
      Originally posted by Motoma
      What exactly is the problem you are having? You mention that it is the init() funciton...What causes you to think this?

      I could not understand what your problem, but when you will fix your problem, please send me at email_removed@f oryourprotectio n.com. i need your program. and also if you have any other program related to NURBS curves and surfaces, please send me. i shall be very thank full to you.
      Last edited by Motoma; Oct 24 '07, 01:14 PM. Reason: Email removed for your own protection.

      Comment

      • Cucumber
        New Member
        • Sep 2007
        • 90

        #4
        This is part of my OpenGL notes I wrote back when I was learning OpenGL, hope this helps you setting up your OpenGL camera:

        In order to setup the OpenGL "camera".

        1. You must tell OpenGL where the observer is situated in the 3D world,
        to where it is looking at, and what is the "up side" of the observer
        (where would be the observer's head pointing to).

        2. You must also tell OpenGL, how wide can the observer see stuff in front of him,
        in other words, how much stuff can the observer see to its left, to its right,
        to its bottom, to its top, what is the closest thing the observer can see,
        and what is the fartest thing the observer can see.

        3. Furthermore, you must tell OpenGL exactly in what part of it canvass can it draw the scene.
        For example, what part of the screen will OpenGL use to do its drawing,
        can it use all the screen? just a little square? You must give it
        the exact coordinates of the screen where OpenGl can draw.

        These 3 sets of information are known as:
        1. The ModelView matrix.
        2. The Projection matrix.
        3. The ViewPort.

        The ModelView is where the observer is located, where it looks at, and where its heads point to.
        Using the ModelView matrix, OpenGL translates the world into the observer coordinates.
        This is like twisting the universe coordinates around the observer. The observer
        becomes the center of the Universe, cool.
        If you are a math freak, the ModelView does rotation and translation of coordinates.

        The Projection tells how much of the universe in front of the observer
        can the observer see.
        How wide is the observer vision left to right, top to bottom and near-to-far.
        Note.The left-right and top-bottom range of view is known as the Field Of View (FOV).
        Using the Projection Matrix, OpenGL can scale stuff on the Universe.
        Far away stuff gets smaller, while near stuff get bigger.
        Things at the edges of the observer's field of view also tend to become bigger.
        While things that are in the center of the observer's field of view field become smaller.
        The Projection matrix also helps OpenGl to clip objects out of the scene.
        Objects that lie completly out of the observer's field of view are not even drawn.
        If you are a math freak, the Projection does a part of the scaling of coordinates.

        Remember, The ViewPort is where OpenGL can draw inside a given destination canvas.
        For instance, if your canvas is a Window. You can tell OpenGL to use
        only a small rectangle to draw its scene rather than use the whole window.
        If you are a math freak, the ViewPort does the scaling and 3D to 2D translation of coordinates.

        This are the pseudocodes you must follow to setup the ModelView, Projection and ViewPort matrices:

        Setting up the ModelView Matrix:

        Code:
           
           glMatrixMode( GL_MODELVIEW ); // tell opengl we want to setup the modelview matrix
           glLoadIndentity( ); // clean the model view matrix
           gluLookAt(observerx,observery,observerz,lookingatx,lookingaty,lookingatz,upx,upy,upz);
        Setting Up the Projection Matrix:

        Code:
           
          glMatrixMode( GL_PROJECTION ); // tell opengl we want to set up the projection matrix
           glLoadIdentity( ); // clean the projection matrix
           glFrustum( leftview, rigthview, bottomview, topview, nearview, farview );
        Setting Up the ViewPort:

        Code:
           
           glViewPort( left, top, width, height );
        Now, an example

        Code:
          Say the observer is at 10,0,0, it is viewing at the origin, so the view
          is -1,0,0, the ceiling is at Z, so Up is 0,0,1: 
        
            ^ Up(0,0,1)                    ^ ZAxis
            |                              |
            |                              |
            o<-------------XAxis----------(Y) Origin(0,0,0)
           /|\(10,0,0)                      
            |      ----> View(-1,0,0)     (YAxis points out from the screen)
           / \
          At the closest range, the Observer can only see 2 units to the left, 2 units to the right,
          2 units to the bottom, 2 units to the top, the nearest thing it can
          see is at 1 unit from him, and he can only see as far as 1000 units from him.
        
                                                             1000 Units Far
         2 Units Left|2 Units Right                1 Unit Near     |
                  <--+-->                          <->             =
                  +-----+                            +             |
                  |     |  |2 Units Top              |             |
                  |     |  |                         |             |
                  |  O  |--+-------               0  |----||-------| Observer Cant see
                  | /|\ |  |2 Units Bottom       ||  |             | beyond 1000 units
                  |  |  |  |                      |  |             |
                  +-/-\-+                        /|  +             |
                                         Observer Cant             =
                                         see objects               |
                                         lying at less             |
                                         than 1 unit
        
                                    
          Lastly Open GL should use the whole window to paint over it
        This is the code that implements the conditions:

        Code:
           
          glMatrixMode   ( GL_MODELVIEW );
          glLoadIdentity ( );
          gluLookAt      ( 10,0,0,   -1,0,0,    0,0,1 );
          glMatrixMode   ( GL_PROJECTION );
          glLoadIdentity ( );
          glFrustum      (   -2,2,     -2,2,    1,1000 );
          RECT r;
          GetClientRect  (hwnd,&r);
          glViewPort     (0,0,r.right,r.bottom);

        Comment

        Working...