PDA

View Full Version : rubber-band and GL_XOR



junlin_xu
01-31-2006, 05:07 AM
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 &#0124;&#0124; 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];
}

def
01-31-2006, 11:12 PM
You need to specify an alpha value to do your blending. Use
glColor4f(0.0, 0.0, 1.0, 0.5); to define a 50% transparent area.
When you insert your src inside a CODE block, you won't have to replace all parenthesis.

junlin_xu
02-01-2006, 04:05 PM
Thanks for the reply. I should have been more clear in my previous post. The transparency is there but there is flickering of ghost lines inside the transparent rectangle (with 0.5 alpha value in color4f). I am not sure if this is due to the graphics card. I am using NVidia GeForce GO 6800 (256MB).