c# - 如何更改c#中窗口窗体的原点即左上角和openGL C即中心?

标签 c# c opengl visual-studio-2012

我正在使用 C# 创建 GUI 部分来绘制多个 2D 矩形,并使用 openGl C 来生成相同的 3D 输出。我正在使用 Visual Studio Express Edition 2012 来处理这两个矩形。我面临的问题是c# 原点(0,0) 位于左上角,在 openGl 中它位于居中。因此,无论我在 2D 中绘制矩形,它都会从 openGL 中的中心绘制。我尝试从 2D 获取 X,Y 值并能够将其传递到 3D,但输出不符合要求,因为 openGl 是中心原点。

我该如何解决这个问题?我应该尝试更改 2D c# 或 3D openGL 的起源,哪个会更容易?我已经尝试过 gluOrtho2D() 对我来说效果很好。和 Glulookat() 来定位相机,但不确定如何根据我的要求准确定位相机。我在正确的路径中吗?我应该尝试更改 c# origin ?

我的 glorthocode,我试图仅定位左上角部分,即 (-x,y)

 gluOrtho2D(-0.1,0,0,0.1);

最佳答案

The problem i am facing is in c# the origin(0,0) is top-left and in openGl it is centered.

实际上在 OpenGL 中有两个起源:

  • 视口(viewport)物理设备单位原点位于视口(viewport)的左下角
  • 归一化设备坐标,可见 XY 范围为 [-1…1]×[-1…1],即原点位于中心,-1,-1 位于左下

投影矩阵用于从 View 空间变换到剪辑空间,经过所谓的“透视划分”(p_NDC = p_clip/p_clip.w) 后变成 NDC 空间。如果 p_clip.w = w 则剪辑坐标就是 NDC 坐标。

话虽这么说,您想要的是创建一个映射,将给定的坐标范围放置在视口(viewport)中,并在某些角/边缘处具有某些坐标。 glOrtho(left, right, top, bottom, near, far)这样做。 gluOrtho2D 可能是最没用的函数,因为 gluOrtho2D(l,r,b,t) = glOrtho(l,r,b,t,-1,1) .

每个参数指定哪个 View 空间坐标最终位于给定边缘。

所以让我们假设以下情况:

glOrtho(
    -3 /* = left   */,
    -5 /* = right  */,
     4 /* = bottom */,
     3 /* = top    */,
    -1 /* = near   */,
     1 /* = far    */);

这意味着坐标 (-3, 4) 位于左下角,而 (-5, 3) 位于右上角。我想你可以看到事情的发展方向。假设您希望原点位于左上角,因此 top = 0,bottom = 0;这使得底部和右侧坐标可供选择,以便满足您的需求。假设您希望 View 空间与视口(viewport)像素坐标匹配,则底部 = viewport_height,右 = viewport_width。

glOrtho(0, viewport_height, 0, viewport_width, -1, 1);

然而,由于 OpenGL 矩阵操作就地发生,并且对矩阵堆栈顶部已经存在的任何内容进行操作,如果您只是调用 glOrtho 而不准备干净的状态,那么您会看到奇怪的事情发生。因此,使用固定功能管线OpenGL绘制像素放置的2D图形的典型前言是:

glViewport(0, 0, viewport_width, viewport_height);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, viewport_height, 0, viewport_width, -1, 1);

glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

draw_2D_pixel_dimensioned_stuff();

glMatrixMode(GL_MODELVIEW);
glPopMatrix();

glMatrixMode(GL_PROJECTION);
glPopMatrix();

关于c# - 如何更改c#中窗口窗体的原点即左上角和openGL C即中心?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22600907/

相关文章:

c# - 从从 api 填充的 ListView 行单击中提取数据

c# - 如何在 C# 中解析非常大的 XML 文件?

c# - 在 linq-to-sql 中的两个日期时间之间查询

c - C中两个表达式之间的区别

C语言: The Array did not return a correct value

java - ArrayList 中的顶点缓冲区对象?

c# - 在 Web API 中正确使用 async/await

c - 获取 C 中变量的二进制表示

c++ - 我的着色器停止工作

opengl - 纹理数组访问不起作用 Opengl 3.3、GLSL 330