在OpenGL中的2D纹理顶部渲染轮廓为红色的矩形 [英] Render an outlined red rectangle on top a 2D texture in OpenGL

查看:121
本文介绍了在OpenGL中的2D纹理顶部渲染轮廓为红色的矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我搜索了很多该网站,但找不到确切的问题.大多数类似的问题都使用了控制台和glut库.但是由于我是OpenGL和MFC的新手,并且是通过MFC的组合启动它的,所以他们帮了我很多.

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!

首先,我应该告诉你,绘制这样一个矩形的目的是,我想在程序中创建该类的两个实例.
在较小的窗口中,图像将始终处于zoom extent模式,而在较大的窗口中,用户具有执行不同导航任务的能力.因此,例如,每次在较大实例the extent rectangleOnDraw函数中平移或缩放图像时,都会对其进行计算并将其传递到较小的窗口并在其中绘制以显示如此大的形象

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

我已按照以下步骤操作:
修改投影矩阵堆栈并模拟2D场景

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);
}  

修改modelview矩阵堆栈并设置摄影机(似乎我们正在寻找z轴的负方向)

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);
}  

线setViewRectangle()用于计算该类的公共成员数据之一,如果用户需要,将使用vector<int>RectangleToDraw其他公共成员数据绘制矩形.这是因为我们不希望在大窗口中绘制这样的矩形,而在较小的窗口中绘制.而较小的将使用较大的数据.但是我仍然没有实现如何在一个类的两个实例之间实时传递这些数据! 因此,在尝试类的时候,我将RectangleToDraw的初始值设置如下,并且由于窗口是由glOrtho设置的[0,0,573,543],因此我认为应该在矩形的中心绘制矩形.纹理.但是事实并非如此.
无论如何
代码以应用将在OnTimer中调用的纹理

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);
}  

计算ViewRectangle的代码,该代码将传递给该类的另一个实例

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;
}  

在纹理顶部绘制矩形的代码

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);
}  

即使在上述功能中使用glVertex2f也没有任何区别,在两种情况下,我都会遇到:

不要感到困惑.在两个窗口上都应用了错误的图形的原因是,我在构造函数中进行了设置:

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;  

仅用于尝试如何在纹理顶部绘制矩形.当然,在编写正确的代码后,我会将它们设置为true模式.告诉我

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

如何最好以一种需要实时渲染的面向对象的方式在纹理的顶部绘制矩形?

推荐答案

由于在现代OpenGL中已弃用edge flags,因此我避免使用多边形填充模式绘制轮廓.如果我正确地理解了您的屏幕截图,则可能是在用于绘制矩形的两个三角形的内部边缘上出现了线条.

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.

相反,绘制一个使用矩形4个角的红色GL_LINE_LOOP ...由于可移植性的原因,这是首选的技术,因为GL_QUADS也已被弃用.

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         ();

此外,您的屏幕快照似乎正试图对轮廓进行纹理化处理.在绘制线条之前,请先禁用GL_TEXTURE_2D.

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

这篇关于在OpenGL中的2D纹理顶部渲染轮廓为红色的矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆