Question

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. enter image description here
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:
enter image description here
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?

Was it helpful?

Solution

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, since GL_QUADS are also deprecated.

glColor3f     (1.0f, 0.0f, 0.0f);
glBegin       (GL_LINE_LOOP);
   glVertex3f (RectangleToDraw.at (0), RectangleToDraw.at (1), -1.0f);
   glVertex3f (RectangleToDraw.at (0), RectangleToDraw.at (3), -1.0f);
   glVertex3f (RectangleToDraw.at (2), RectangleToDraw.at (3), -1.0f);
   glVertex3f (RectangleToDraw.at (2), RectangleToDraw.at (1), -1.0f);
glEnd         ();

Also, your screenshot appears to be suffering from attempting to texture the outline. Disable GL_TEXTURE_2D before you draw your lines.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top