I wrote a working rubber-band class [non-filled selection rectangle] using OpenGL using MFC on Windows. However, I would like to use filled selection rectangle with some transparency but fail to make it work properly [see the lines commented out in void CjxglTracker::DrawTrackRect[]]
. Can any OpenGL experts out there help? I had to replace all parenthesis so I can post this topic. I can also email my test application if you would like to. Thanks.
The following is the code:
// h
class CjxglTracker
{
public:
CjxglTracker[void];
public:
~CjxglTracker[void];
public:
BOOL Track[CWnd* pWnd, CPoint point];
void DrawTrackRect[int x1, int y1, int x2, int y2];
void DrawTrackRect[const CRect& rect];
CRect m_rect;
BOOL m_bErase;
CWnd* m_pWnd;
};
// cpp
#include “stdafx.h”
#include <gl\gl.h>
#include “CjxglTracker.h”
CjxglTracker::CjxglTracker[void]
{
m_bErase = FALSE;
}
CjxglTracker::~CjxglTracker[void]
{
}
void CjxglTracker::DrawTrackRect[int x1, int y1, int x2, int y2]
{
CRect rectClient;
if[m_pWnd]
{
m_pWnd->GetClientRect[&rectClient];
}
//glEnable[GL_BLEND];
//glBlendFunc[GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA];
//glShadeModel[GL_FLAT];
glEnable[GL_COLOR_LOGIC_OP];
glLogicOp[GL_XOR];
if[x1 < x2]
{
glColor3f[0.0, 0.0, 1.0];
}
else
{
glColor3f[1.0, 0.0, 0.0];
}
glPolygonMode[GL_FRONT_AND_BACK, GL_LINE];
//glPolygonMode[GL_FRONT_AND_BACK, GL_FILL];
glRecti[x1, rectClient.Height[] - y1, x2, rectClient.Height[] - y2];
glPolygonMode[GL_FRONT_AND_BACK, GL_FILL];
glFlush[];
glDisable[GL_COLOR_LOGIC_OP];
//glDisable[GL_BLEND];
}
void CjxglTracker::DrawTrackRect[const CRect& rect]
{
DrawTrackRect[rect.left, rect.top, rect.right, rect.bottom];
}
BOOL CjxglTracker::Track[CWnd* pWnd, CPoint point]
{
m_pWnd = pWnd;
if [::GetCapture[] != NULL]
{
return FALSE;
}
pWnd->SetCapture[];
ASSERT[pWnd == CWnd::GetCapture[]];
pWnd->UpdateWindow[];
BOOL bMoved = FALSE;
CPoint ptOld = point;
CRect rectOld = CRect[ptOld, ptOld];
CPoint ptNew;
BOOL bStop = FALSE;
for [;;]
{
MSG msg;
VERIFY[::GetMessage[&msg, NULL, 0, 0]];
if [CWnd::GetCapture[] != pWnd]
{
break;
}
if[msg.message == WM_LBUTTONUP || msg.message == WM_MOUSEMOVE]
{
ptNew.x = GET_X_LPARAM[msg.lParam];
ptNew.y = GET_Y_LPARAM[msg.lParam];
m_rect = CRect[ptOld, ptNew];
if [bMoved]
{
m_bErase = TRUE;
DrawTrackRect[&rectOld];
}
rectOld = m_rect;
if [msg.message != WM_LBUTTONUP]
{
bMoved = TRUE;
}
if [msg.message == WM_MOUSEMOVE]
{
m_bErase = FALSE;
DrawTrackRect[&m_rect];
}
else
{
bStop = TRUE;
ASSERT[msg.message == WM_LBUTTONUP];
}
}
else if[msg.message == WM_KEYDOWN]
{
if [msg.wParam == VK_ESCAPE]
{
bStop = TRUE;
}
}
else if[msg.message == WM_RBUTTONDOWN]
{
bStop = TRUE;
}
else
{
DispatchMessage[&msg];
}
if[bStop]
{
break;
}
} // for [;;]
ReleaseCapture[];
if[!m_bErase]
{
DrawTrackRect[m_rect];
}
return TRUE;
}
// view class
void CUnicodeView::OnLButtonDown[UINT nFlags, CPoint point]
{
CPaintDC dc[this]; // device context for painting
wglMakeCurrent[dc.m_hDC, m_hRC];
glDrawBuffer[GL_FRONT];
glMatrixMode[GL_PROJECTION];
glPushMatrix[];
glLoadIdentity[];
glOrtho[0, m_nCx, 0, m_nCy, -1, 1];
glViewport[-1, -1, m_nCx + 2, m_nCy + 2];
CjxglTracker tracker;
tracker.Track[this, point];
glPopMatrix[];
glDrawBuffer[GL_BACK];
}