【问题标题】:Render an outlined red rectangle on top a 2D texture in OpenGL在 OpenGL 中的 2D 纹理顶部渲染一个带轮廓的红色矩形
【发布时间】:2013-08-30 21:36:32
【问题描述】:

我已经搜索了很多这个网站,但无法准确找到我的问题。大多数类似的问题都使用了控制台和 glut 库。但是由于我是 OpenGL 和 MFC 的新手,并且是从 MFC 的组合开始的,所以他们帮不了我很多。

我正在为自己的目的自定义类 COpenGLcontrol here in codeguruHere's the full customized class 但如果你没兴趣下载,没问题我会解释相关的部分。这可能需要一段时间,所以我希望你能耐心等待!

首先我应该告诉你,我绘制这样一个矩形的目标是,我想在我的程序中创建该类的两个实例。
在较小的窗口中,图像始终处于zoom extent 模式,但在较大的窗口中,用户可以执行不同的导航任务。因此,每次例如图像被平移或放大时,较大实例 the extent rectangleOnDraw 函数将被计算并传递到较小的窗口并在那里绘制以显示 我们在整体上的位置这么大的图

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

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矩阵栈并设置camera(好像我们在看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>ViewRectangle,如果用户需要,vector<int>RectangleToDraw 其他公共成员数据将用于绘制矩形。这是因为我们不希望在大窗口中绘制这样的矩形,但在较小的窗口中我们会这样做。而较小的将使用较大的数据。但我还没有实现如何在一个类的两个实例之间实时传递这些数据!
所以在尝试上课的时候,我将RectangleToDraw的初始值设置如下,并且由于窗口是glOrtho设置的[0,0,573,543],我认为矩形应该绘制在中心,在顶部纹理。但事实并非如此。
无论如何
应用将在 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的代码将被传递给该类的另一个实例

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 也没有任何区别,在这两种情况下,我都会遇到:

不要混淆。两个窗口都画错的原因是我在构造函数中设置的:

WantToDrawRectangle = true;  
RectangleToDraw.at(0) = -100;
RectangleToDraw.at(1) = -100;
RectangleToDraw.at(2) = 100;
RectangleToDraw.at(3) = 100;  

只是为了尝试如何在纹理上绘制一个矩形。当然,在编写正确的代码后,我会将它们设置为 true 模式。告诉我吧

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

【问题讨论】:

  • 你使用的OpenGL是什么版本的?

标签: opengl mfc textures rectangles texture2d


【解决方案1】:

由于 edge flags 在现代 OpenGL 中已被弃用,我会避免使用多边形填充模式来绘制轮廓。如果我正确理解您的屏幕截图,您会在用于绘制矩形的两个三角形的内部边缘上得到线条。

改为使用矩形的 4 个角绘制红色 GL_LINE_LOOP...这是出于便携性原因的首选技术,因为 GL_QUADS 也已被弃用。

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

【讨论】:

  • 听取了您的建议,但在每次缩放时只绘制了一个比图像大的实心红色矩形。
  • @sepideh:这没有任何意义,你用GL_LINE_LOOP吗?
  • 是的,看来我应该学习 glut 库,先用 glut 做图纸,然后再学习这个程序的经验!
  • @sepideh:哦,我想发生的事情是你忘记将glColor3f (...) 设置回正常的值(可能是1.0f、1.0f、1.0f)并重新启用GL_TEXTURE_2D。请记住,OpenGL 是一个相当简单的状态机,它具有使用“当前”状态和绑定然后修改的烦人特性。旧版 OpenGL 中始终存在 Attribute Stacks(例如 glPushAttrib (...)glPopAttrib (...))。
  • @sepideh:嗯,你现在正在学习不推荐使用的 OpenGL,glBegin (...)、glEnable (GL_TEXTURE_2D) 等这些东西在现代 OpenGL 中都是无效的。如果你想学习现代 OpenGL,arcsynthesis.org/gltut 似乎很受欢迎。它具有更高的学习曲线,因为没有着色器您无法做任何事情,并且您一直使用的这个 MFC OpenGL 控制类最终必须重新编写才能获得 OpenGL 核心上下文。但如果可以避免的话,最好不要学习旧的 API。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多