I have searched alot this site but couldn't exactly find what is exactly my problem. Most of the similar problems had used console and the glut library. But since I'm new to OpenGL and MFC and started it with the combination of MFC, they couldn't help me alot.
I'm customizing the class COpenGLcontrol here in codeguru for my own purposes. Here's the full customized class but if you're not interested in downloading it, no problem I will explain the parts that are related. This may take a while, so I hope you will be patient!
First of all I should tell you that my goal of drawing such a rectangle is that, I want to create two instances of the class in my program.
in the smaller window the image would always be in the zoom extent
mode but in the bigger one, the user has the ability to do different navigation tasks. So each time that for example the image is panned or zoomed in the OnDraw
function of the bigger instance the extent rectangle
will be computed and passed to the smaller window and drawn there to show that where we are on the whole of such a big image
I have followed these steps:
Modyifying the projection matrix stack and simulating a 2D scene
void COpenGLControl::OnSize(UINT nType, int cx, int cy)
{
wglMakeCurrent(hdc, hrc);
CWnd::OnSize(nType, cx, cy);
if (0 >= cx || 0 >= cy || nType == SIZE_MINIMIZED) return;
oglWindowWidth = cx;
oglWindowHeight = cy;
// Map the OpenGL coordinates.
glViewport(0, 0, oglWindowWidth, oglWindowHeight);
// Projection view
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set our current view perspective
glOrtho(-oglWindowWidth/2, oglWindowWidth/2, -oglWindowHeight/2,oglWindowHeight/2, 1, -1);
// Model view
glMatrixMode(GL_MODELVIEW);
wglMakeCurrent(NULL, NULL);
}
Modifying the modelview matrix stack and setting camera (it seems that we are looking to the negative direction of the z-axis)
void COpenGLControl::OnDraw(CDC *pDC)
{
// TODO: Camera controls
wglMakeCurrent(hdc,hrc);
glLoadIdentity();
gluLookAt(0,0,1,0,0,0,0,1,0);
glTranslatef(m_fPosX, m_fPosY, 0.0f);
glScalef(m_fZoom,m_fZoom,1.0);
setViewRectangle();
if (WantToDrawRectangle)
DrawRectangleOnTopOfTexture();
wglMakeCurrent(NULL, NULL);
}
the line setViewRectangle()
is for computing vector<int>ViewRectangle
one of the public member datas of the class and if the user wants, the vector<int>RectangleToDraw
other public member-data will be used to draw the rectangle. This is because we don't want in the big window to draw such a rectangle but in the smaller we do. And the smaller will use the data of the bigger.But I haven't still implemented how to pass these data real-time between two instances of a class!
So at time just for trying out the class, I have set the initial value of RectangleToDraw
as follows and since the window is a [0,0,573,543]
setted by glOrtho
, I think the rectangle should be drawn in center, at top of the texture. But this is not the case.
anyway
Code to apply the texture that will be called in the OnTimer
void COpenGLControl::oglDrawScene(void)
{
wglMakeCurrent(hdc, hrc);
float x0 = -ImageWidth/2; // top left corner of image
float y0 = ImageHeight/2;
float x1 = x0 + ImageWidth; // bottom right corner of image
float y1 = y0 - ImageHeight;
glBegin(GL_TRIANGLE_STRIP);
{
glTexCoord2f(0,1);glVertex2f(x0, y1);
glTexCoord2f(0,0);glVertex2f(x0, y0);
glTexCoord2f(1,1);glVertex2f(x1, y1);
glTexCoord2f(1,0);glVertex2f(x1, y0);
}
glEnd();
wglMakeCurrent(NULL, NULL);
}
Code to compute ViewRectangle
that will be passed to another instance of the class
void COpenGLControl::setViewRectangle()
{
ViewRectangle.at(0) = m_fPosX - oglWindowWidth*m_fZoomInverse/2;
ViewRectangle.at(1) = m_fPosY - oglWindowHeight*m_fZoomInverse/2;
ViewRectangle.at(2) = m_fPosX + oglWindowWidth*m_fZoomInverse/2;
ViewRectangle.at(3) = m_fPosY + oglWindowHeight*m_fZoomInverse/2;
}
Code to draw a rectangle on top of texture
void COpenGLControl::DrawRectangleOnTopOfTexture()
{
wglMakeCurrent(hdc, hrc);
glColor3f(1.0f,0.0f,0.0f);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glBegin(GL_QUADS);
glVertex3f(RectangleToDraw.at(0),RectangleToDraw.at(1),0.5);
glVertex3f(RectangleToDraw.at(0),RectangleToDraw.at(3),0.5);
glVertex3f(RectangleToDraw.at(2),RectangleToDraw.at(3),0.5);
glVertex3f(RectangleToDraw.at(2),RectangleToDraw.at(1),0.5);
glEnd();
SwapBuffers(hdc);
wglMakeCurrent(NULL, NULL);
}
even using glVertex2f
in the above function does not make any difference and in both circumstances, I encounter:
Don't get confused. The reason that the wrong drawing is applied on both windows, is that I have set in the constructor:
WantToDrawRectangle = true;
RectangleToDraw.at(0) = -100;
RectangleToDraw.at(1) = -100;
RectangleToDraw.at(2) = 100;
RectangleToDraw.at(3) = 100;
just for trying out how to draw a rectangle on top of a texture. Surely after writing the correct code, I will set them to the true mode. Just tell me
How to draw a rectangle on top of a texture preferably in such an object-oriented way that I need real-time rendering?
Since
edge flags
are deprecated in modern OpenGL, I would avoid using a polygon fill mode to draw the outlines. If I understand your screenshot correctly, you are getting lines on the interior edges of the two triangles used to draw your rectangle.Instead draw a red
GL_LINE_LOOP
that uses the 4 corners of your rectangle... this is the preferred technique for portability reasons, sinceGL_QUADS
are also deprecated.Also, your screenshot appears to be suffering from attempting to texture the outline. Disable
GL_TEXTURE_2D
before you draw your lines.