OpenGL - реакция на мышь и координаты
Изучаю OpenGL MFC и все это по VisualC++.
Ничерта не могу понять. Вроде совсем простая задача. Два раза кликаю мышкой на поле, записываю 2 координаты типа CPoint передаю их для рисования линии с использованием Open GL. Линия не рисуется. Хотя должна рисоваться по двум выбранным точкам. Ниже привожу часть моего кода, а точнее один из модулей, в котором все основные события и происходят. Исходник работает без ошибок, но линия не рисуется. Что делать как грамотно это все заставить работать. И еще один схожий вопрос. Когда я вызываю функцию display() в событии нажатия на левую кнопку мыши, то сфера начинает двигаться именно вправо по пикселю на каждый клик. Че за ботва - не понимаю и за счет чего она вообще движеться. Хелп плз... Заранее благодарен. Исходник прилагаю.
// MFCView.cpp : implementation of the CMFCView class
//
#include "stdafx.h"
#include "MFC.h"
#include "MfcDoc.h"
#include "MfcView.h"
#include "MainFrm.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CPoint P[4];
int countPoint=0;
/////////////////////////////////////////////////////////////////////////////
// CMFCView
IMPLEMENT_DYNCREATE(CMfcView, CView)
BEGIN_MESSAGE_MAP(CMfcView, CView)
//{{AFX_MSG_MAP(CMFCView)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_WM_MOUSEMOVE()
ON_WM_SETCURSOR()
ON_WM_KEYDOWN()
ON_WM_LBUTTONDOWN()
//}}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()
/////////////////////////////////////////////////////////////////////////////
CMfcView::CMfcView()
{
// TODO: add construction code here
cansel=true;
}
CMfcView::~CMfcView()
{
}
void CMfcView::OnLButtonDown(UINT, CPoint Point)
{
if(countPoint <2)
{
P[countPoint]=Point;
countPoint++;
}
// задаю две точки в массив.
}
BOOL CMfcView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
return CView::PreCreateWindow(cs);
}
BOOL CMfcView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
if(!cansel)
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_CROSS));
else
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
return true;
}
/////////////////////////////////////////////////////////////////////////////
// CMFCView drawing
void CMfcView::display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glTranslated(0.01,0,0);
glColor3d(1,1,1);
auxSolidSphere( 1 );
// а вот тут пытаюсь рисовать.
glBegin(GL_LINES);
glVertex2f (P[0].x,P[0].y);
glVertex2f (P[1].x,P[1].y);
glEnd();
glFinish();
SwapBuffers(wglGetCurrentDC());
}
void CMfcView::OnDraw(CDC* pDC)
{
display();
}
/////////////////////////////////////////////////////////////////////////////
// CMFCView printing
BOOL CMfcView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CMfcView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CMfcView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CMFCView diagnostics
#ifdef _DEBUG
void CMfcView::AssertValid() const
{
CView::AssertValid();
}
void CMfcView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMfcDoc* CMfcView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMfcDoc)));
return (CMfcDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMFCView message handlers
int CMfcView::SetWindowPixelFormat(HDC hDC)
{
int m_GLPixelIndex;
PIXELFORMATDESCRIPTOR pfd;
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cRedBits = 8;
pfd.cRedShift = 16;
pfd.cGreenBits = 8;
pfd.cGreenShift = 8;
pfd.cBlueBits = 8;
pfd.cBlueShift = 0;
pfd.cAlphaBits = 0;
pfd.cAlphaShift = 0;
pfd.cAccumBits = 64;
pfd.cAccumRedBits = 16;
pfd.cAccumGreenBits = 16;
pfd.cAccumBlueBits = 16;
pfd.cAccumAlphaBits = 0;
pfd.cDepthBits = 32;
pfd.cStencilBits = 8;
pfd.cAuxBuffers = 0;
pfd.iLayerType = PFD_MAIN_PLANE;
pfd.bReserved = 0;
pfd.dwLayerMask = 0;
pfd.dwVisibleMask = 0;
pfd.dwDamageMask = 0;
m_GLPixelIndex = ChoosePixelFormat( hDC, &pfd);
if(m_GLPixelIndex==0) // Let's choose a default index.
{
m_GLPixelIndex = 1;
if(DescribePixelFormat(hDC,m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pfd)==0)
return 0;
}
if (SetPixelFormat( hDC, m_GLPixelIndex, &pfd)==FALSE)
return 0;
return 1;
}
int CMfcView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
pdc = new CClientDC(this);
if(SetWindowPixelFormat(pdc->m_hDC)==FALSE)
return -1;
hGLRC = wglCreateContext(pdc->m_hDC);
if(hGLRC == NULL)
return -1;
if(wglMakeCurrent(pdc->m_hDC, hGLRC)==FALSE)
return -1;
glEnable(GL_ALPHA_TEST);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
float pos[4] = {3,3,3,1};
float dir[3] = {-1,-1,-1};
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, dir);
return 0;
}
void CMfcView::OnDestroy()
{
if(wglGetCurrentContext()!=NULL)
wglMakeCurrent(NULL, NULL) ;
if(hGLRC!=NULL)
{
wglDeleteContext(hGLRC);
hGLRC = NULL;
}
delete pdc;
CView::OnDestroy();
}
void CMfcView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
glViewport(0,0,cx,cy);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho(-5,5, -5,5,2,12);
gluLookAt( 0,0,5, 0,0,0, 0,1,0 );
glMatrixMode( GL_MODELVIEW );
}
CMfcView::OnMouseMove(UINT, CPoint point)
{
// TODO: Add your message handler code here and/or call default
// TODO: Add your message handler code here and/or call default
char chX[10];
char chY[10];
itoa(point.x,chX,10);
itoa(point.y,chY,10);
CString csStatusX(chX);
CString csStatusY(chY);
CMainFrame *pFrm;
pFrm = (CMainFrame *)AfxGetMainWnd();
pFrm-> m_wndStatusBar.SetPaneText(1,csStatusX);
pFrm->m_wndStatusBar.SetPaneText(2,csStatusY);
//AfxMessageBox("Clicked !");
//CFrameWnd::OnMouseMove(nFlags, point);
}
void CMfcView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if(nChar==27)
{
cansel=true;
::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_ARROW));
}
//CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}
но это потому что здесь MFC код, а я всегда
чисто под WinAPI пишу и всем тоже советую,
на много это удобней.
Не сочтите за флуд - я просто раньше тоже в
своём коде ошибки долго искал, когда он был объёмный, вот как я решаю эту проблему:
Один раз хорошо попарившись - я написал отладку
периода исполнения, и теперь
я всегда вижу те баги которые не нащёл компилятор, но это под API.
Если интересует я могу выложить мой вариант
инициализации под апи, он конечно далёк от
обще принятых принципов, но работает как
часы - я не жалуюсь.