Archived

This topic is now archived and is closed to further replies.

adi

object move help

Recommended Posts

adi    122
hello, i am moving an object in opengl with gluUnProject command using a mouse. but the problem is that the object is only moving along the z-axis. how ot move it along all the axes. thanx in advance.

Share this post


Link to post
Share on other sites
adi    122
here is the source code

// og5View.cpp : implementation of the COg5View class
//

#include "stdafx.h"
#define BUFSIZE 512
#include "og5.h"

#include "og5Doc.h"
#include "og5View.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

GLfloat ambientLight[] = { 0.3f, 0.3f,0.3f, 1.0f };
GLfloat diffuseLight[] = { 0.7f, 0.7f,0.7f, 1.0f };
GLfloat lightPos[] = {-50.0f, 50.0f,100.0f, 1.0f };
GLdouble posx,posy,posz,potx,poty,potz,m,n,o;


/////////////////////////////////////////////////////////////////////////////
// COg5View

IMPLEMENT_DYNCREATE(COg5View, CView)

BEGIN_MESSAGE_MAP(COg5View, CView)
//{{AFX_MSG_MAP(COg5View)
ON_WM_DESTROY()
ON_WM_SIZE()
ON_WM_PAINT()
ON_COMMAND(ID_CREATE_CUBE, OnCreateCube)
ON_WM_CREATE()
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COg5View construction/destruction

COg5View::COg5View()
{
// TODO: add construction code here
m_hGLContext = NULL;
m_GLPixelIndex = 0;
m_pShape = gluNewQuadric();
}

COg5View::~COg5View()
{
}

BOOL COg5View:reCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
return CView:reCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// COg5View drawing

void COg5View::OnDraw(CDC* pDC)
{
COg5Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}

/////////////////////////////////////////////////////////////////////////////
// COg5View printing

BOOL COg5View::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}

void COg5View::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}

void COg5View::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// COg5View diagnostics

#ifdef _DEBUG
void COg5View::AssertValid() const
{
CView::AssertValid();
}

void COg5View::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}

COg5Doc* COg5View::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(COg5Doc)));
return (COg5Doc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// COg5View message handlers

BOOL COg5View::SetWindowPixelFormat(HDC hDC)
{
PIXELFORMATDESCRIPTOR pixelDesc;

pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pixelDesc.nVersion = 1;

pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_DRAW_TO_BITMAP |
PFD_SUPPORT_OPENGL |
PFD_SUPPORT_GDI |
PFD_STEREO_DONTCARE;

pixelDesc.iPixelType = PFD_TYPE_RGBA;
pixelDesc.cColorBits = 32;
pixelDesc.cRedBits = 8;
pixelDesc.cRedShift = 16;
pixelDesc.cGreenBits = 8;
pixelDesc.cGreenShift = 8;
pixelDesc.cBlueBits = 8;
pixelDesc.cBlueShift = 0;
pixelDesc.cAlphaBits = 0;
pixelDesc.cAlphaShift = 0;
pixelDesc.cAccumBits = 64;
pixelDesc.cAccumRedBits = 16;
pixelDesc.cAccumGreenBits = 16;
pixelDesc.cAccumBlueBits = 16;
pixelDesc.cAccumAlphaBits = 0;
pixelDesc.cDepthBits = 32;
pixelDesc.cStencilBits = 8;
pixelDesc.cAuxBuffers = 0;
pixelDesc.iLayerType = PFD_MAIN_PLANE;
pixelDesc.bReserved = 0;
pixelDesc.dwLayerMask = 0;
pixelDesc.dwVisibleMask = 0;
pixelDesc.dwDamageMask = 0;

m_GLPixelIndex = ChoosePixelFormat( hDC, &pixelDesc);
if (m_GLPixelIndex==0) // Let''s choose a default index.
{
m_GLPixelIndex = 1;
if (DescribePixelFormat(hDC, m_GLPixelIndex,
sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc)==0)
{
return FALSE;
}
}

if (SetPixelFormat( hDC, m_GLPixelIndex, &pixelDesc)==FALSE)
{
return FALSE;
}

return TRUE;

}

BOOL COg5View::CreateViewGLContext(HDC hDC)
{
m_hGLContext = wglCreateContext(hDC);
if (m_hGLContext == NULL)
{
return FALSE;
}

if (wglMakeCurrent(hDC, m_hGLContext)==FALSE)
{
return FALSE;
}

return TRUE;
}

void COg5View::OnDestroy()
{
if(wglGetCurrentContext()!=NULL)
{
// make the rendering context not current
wglMakeCurrent(NULL, NULL) ;
}

if (m_hGLContext!=NULL)
{
wglDeleteContext(m_hGLContext);
m_hGLContext = NULL;
}

// Now the associated DC can be released.

CView::OnDestroy();

// TODO: Add your message handler code here

}

void COg5View::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);

// TODO: Add your message handler code here
m_WHRatio=(GLdouble)cx/(GLdouble)cy;;
glViewport (0, 0, cx, cy);
InitOpenGL();
}

void COg5View::OnPaint()
{
CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here
glClearColor(1.0,1.0,1.0,1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/*glMatrixMode(GL_PROJECTION);
glLoadIdentity();*/

//drawing the coodinate axis.
glDisable(GL_DEPTH_TEST);
CCoordinateAxis(2,2,2).Display();
glEnable(GL_DEPTH_TEST);

RenderScene();
}

void COg5View::OnCreateCube()
{
// TODO: Add your command handler code here
COg5View::OnPaint();
}

int COg5View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

// TODO: Add your specialized creation code here
HWND hWnd = GetSafeHwnd();
HDC hDC = ::GetDC(hWnd);

if (SetWindowPixelFormat(hDC)==FALSE)
return 0;
if (CreateViewGLContext(hDC)==FALSE)
return 0;

return 0;
}
//do some initialization for the OpenGL
void COg5View::InitOpenGL()
{

glLineWidth(0.05);
glEnable(GL_LINE_SMOOTH);

glFrontFace(GL_CW);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);

glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
glEnable(GL_LIGHT0);

glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);

glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);

glEnable(GL_NORMALIZE);

}
void COg5View::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
mouseDown=TRUE;
m=0,n=0,o=0;
int xPos = point.x;// horizontal position of cursor
int yPos = point.y;// vertical position of cursor

ProcessSelection(xPos, yPos);
CView::OnLButtonDown(nFlags, point);
}
const BUFFER_LENGTH=64;
void COg5View:rocessSelection(int xPos, int yPos)
{
// Space for selection buffer
GLuint selectBuff[BUFFER_LENGTH];

// Hit counter and viewport storeage
GLint hits, vport[4];

// Setup selection buffer
glSelectBuffer(BUFFER_LENGTH, selectBuff);

// Get the viewport
glGetIntegerv(GL_VIEWPORT, vport);

// Switch to projection and save the matrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();

// Change render mode
glRenderMode(GL_SELECT);

// Establish new clipping volume to be unit cube around
// mouse cursor point (xPos, yPos) and extending two pixels
// in the vertical and horzontal direction
glLoadIdentity();

// Since OpenGL measures
// window coordinates starting at the bottom of the window, and Windows
// measures starting at the top, we need to account for this by
// subtracting the y coordinate from the height of the window. This has
// the effect of reversing the coordinate system (y starts at top)

gluPickMatrix(xPos,vport[3]-yPos, 2,2, vport);

// Apply perspective matrix
//gluPerspective(45.0f, m_WHRatio, 1.0, 425.0);

// Draw the scene
RenderScene();

// Collect the hits
hits = glRenderMode(GL_RENDER);

// If a single hit occured, display the info.
if(hits == 1)
ProcessPlanet(selectBuff);

// Restore the projection matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();

// Go back to modelview for normal rendering
glMatrixMode(GL_MODELVIEW);

}

void COg5View:rocessPlanet(GLuint *pSelectBuff)
{
char cMessage[64];

// How many names on the name stack
count = pSelectBuff[0];

// Bottom of the name stack
id = pSelectBuff[3];


// Select on earth or mars, whichever was picked
switch(id)
{

case SPHERE:
strcpy(cMessage,"Success: Selected Sphere.");
break;

case CUBE:
strcpy(cMessage,"Success: Selected Cube");

break;

// If nothing was clicked we shouldn''t be here!
default:
strcpy(cMessage,"Error - Nothing was clicked on!");
break;
}


// Display the message about planet and moon selection
//AfxMessageBox(cMessage,0,0);
}
void COg5View::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if((mouseDown==TRUE)&&((id==1)||(id==3)))
{
GLdouble modelMatrix[16];
glGetDoublev(GL_MODELVIEW_MATRIX,modelMatrix);
GLdouble projMatrix[16];
glGetDoublev(GL_PROJECTION_MATRIX,projMatrix);
GLint viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
gluUnProject(point.x,point.y,0,modelMatrix,projMatrix,viewport,&posx,&posy,&posz);

if(m_OldPoint!=point)
{gluUnProject(m_OldPoint.x,m_OldPoint.y,0,modelMatrix,projMatrix,viewport,&potx,&poty,&potz);}
else
{poty=0.0,potz=0.0,potx=0.0;}
Invalidate();
RenderScene();
}
m_OldPoint=point;

CView::OnMouseMove(nFlags, point);
}

void COg5View::OnLButtonUp(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
mouseDown=FALSE;
glPushMatrix();

CView::OnLButtonUp(nFlags, point);
}
void COg5View::RenderScene()
{
// TODO: Add your message handler code here
// glMatrixMode(GL_MODELVIEW);
glInitNames();
glPushName(0);

glPushMatrix(); /* save the current transformation state */


glLoadName(SPHERE);
glColor3f(1.0,0.0,0.0);
if((mouseDown==TRUE)&&(id==1))
{
m=m+posx-potx;
n=n+posx-potx;
o=o+posz-potz;
glTranslatef(m,n,o);
}
gluSphere(m_pShape,0.2, 50, 50);
glPopMatrix();

glPushMatrix();
glLoadName(CUBE);
glColor3f(0.0,1.0,0.0);
glRotatef(20,1.0,1.0,1.0);
glTranslatef(0.7,0,0);
if((mouseDown==TRUE)&&(id==3))
{
m=m+posx-potx;
n=n+posx-potx;
o=o+posz-potz;
glTranslatef(m,n,o);
}
auxSolidCube(0.3);
glPopMatrix ();/* restore the previous transformation state*/

glFlush();
// Do not call CView::OnPaint() for painting messages
}


quote:
Original post by gerogerber
what about posting some source code?


Share this post


Link to post
Share on other sites
gerogerber    147
First of all you need invert the second parameter you pass to gluUnProject() like this:
newy = viewport[3] - point.y - 1
This is because the mouse coordinates start at the UPPER left of the window and the viewport coordinates at the LOWER left. And gluUnProject expects the viewport coordinates (red book p.152).

Then you do your translation like this:
m=m+posx-potx;
n=n+posx-potx;
o=o+posz-potz;
So I think the second line is obviously wrong.

Also call
glLoadIdentity() after glMatrixMode(GL_MODELVIEW) in RenderScene().

So lets see what happens now ;-)

Gero Gerber

Share this post


Link to post
Share on other sites
adi    122
thank you very much sir for your information.
i am highly grateful to you.
BTW, i am moved one object and kept other fixed. now if i move
the other one, the first one reverts to its default position by virtue of the code in RenderScene().my question is how to save the positional info after moving first object so that it is not affected by the motion of 2nd object.

Share this post


Link to post
Share on other sites
adi    122
yes, because when either has to move, the code in RenderScene()
places other in the default position.now how to save the translated sphere and then move the cube that is the question.

Share this post


Link to post
Share on other sites
gerogerber    147
Ok, you should add some global variables where you store the position, rotation and scaling for each object. If you move object1, you update the variables for object1. But each time you render you have to translate, rotate and scale so that the current transformation is applied:

glPushMatrix();
if((mouseDown==TRUE)&&(id==1))
{
update transformation variables like posx, posy, poz
}
glTranslatef(posx,posy,posz);
gluSphere(m_pShape,0.2, 50, 50); /*for example*/
glPopMatrix();

Hope this helps you out,
Gero Gerber

Share this post


Link to post
Share on other sites