【问题标题】:How to texture a random convex quad in openGL如何在openGL中纹理随机凸四边形
【发布时间】:2014-08-03 20:53:41
【问题描述】:

好的,所以我开始查找有关 openGL 的教程以制作我的世界模组。我仍然不太了解它,因为我认为在进行我想要的小修改时我真的不应该这样做,但这让我很头疼。我想要做的就是能够正确地将纹理映射到不规则的凹四边形。

像这样:

在我尝试在游戏中运行代码之前,我进入了 openGL 以弄清楚如何做到这一点。我已经读到我需要进行透视正确的转换,并且我已经让它适用于梯形,但是对于我的生活,如果两对边都不是,我无法弄清楚该怎么做平行线。我看过这个:http://www.imagemagick.org/Usage/scripts/perspective_transform,但我真的不知道这个人所说的“8 个常量”来自哪里,或者它是否会对我有所帮助。我也被告知要做calculations with matrices,但我不知道 openGL 有多少可以处理或不处理。

我查看了几篇关于此的帖子,我需要的答案就在其中的某个地方,但我无法对它们做出正面或反面。我永远找不到帖子告诉我应该在 glTexCoord4f() 方法中放入哪些参数才能进行透视正确的变换。

如果您认为“了解 Q 坐标”页面可以解决我的问题,恐怕我已经看过它了,但它让我失望了。

我有什么遗漏吗?我觉得这应该容易得多。我发现很难相信 openGL 和它所有的花里胡哨的东西,除了矩形之外什么都没有。

所以,我希望我没有因为我的无知而激怒你,在此先谢谢你。

编辑:我想我需要明确一点,当您的四边形视图不正交时,我知道 openGL 会为您进行透视变换。我知道只是改变z坐标或我的fov。我正在寻找平滑纹理非矩形四边形,而不是在某个 fov 中放置矩形。

【问题讨论】:

  • 哦,废话。忘了说它是我的世界,所以这是用 Java 编写的,我也有 LWJGL。
  • > 我很难相信 openGL 和它所有的花里胡哨的东西,除了矩形之外什么都没有。相信它。它除了三角形之外什么都没有。 :)

标签: opengl texture-mapping perspective


【解决方案1】:

OpenGL 将为您进行透视正确变换。我相信您只是面临四边形与三角形插值的问题。仿射变换和透视正确变换之间的差异与 3D 几何有关,其中图像空间中的插值是非线性的。想想看一条路:等间距的线条在远处显得更加频繁。无论如何,回到三角形与四边形......

以下是一些相关的帖子:

【讨论】:

  • 重心插值。好的,我会调查的。谢啦。我想我早些时候看到了这个,但我没有他和我有同样的问题。我看到“着色器”这个词并想,“完全不同的难题,继续前进。”我有一些术语要查找...不要费心向我解释它,我相信它并不复杂,我会在自己的时间找到。
  • 我在看那个“不简单”的答案,我有点追随它,但我不知道“out”、“layout”和“in”是什么。我猜这是它不是 java 的结果,但就像我说的,我没有经验。
  • @BenDenison 它们是在 OpenGL 3 中引入的(我认为),但是使用 in/outvarying 的新写法。 layout 在这里用于指定数组的绑定位置(可能对内存局部性很重要,但原因之一是here)并强制使用glGetAttribLocation 获得的值。您可以在链接之前使用glBindAttribLocation
【解决方案2】:

您应该知道的第一件事是 没有 使用 OpenGL 很容易。这是一个非常复杂的状态机,有很多怪癖和开发人员的糟糕界面。

也就是说,我认为您混淆了很多不同的东西。要绘制带有透视校正的纹理矩形,您只需在适当设置投影矩阵后在 3D 空间中绘制一个纹理矩形。

首先,您需要设置所需的投影。根据您的描述,您需要创建透视投影。在 OpenGL 中,您通常有 2 个您关心的主要矩阵 - 投影和模型视图。投影矩阵有点像你的“相机”。

您如何执行上述操作取决于您使用的是 Legacy OpenGL(低于 3.0 版)还是 Core Profile(现代,3.0 或更高版本)OpenGL。 This page 描述了两种方法,具体取决于您使用的方法。

void BuildPerspProjMat(float *m, float fov, float aspect, float znear, float zfar)
{
    float xymax = znear * tan(fov * PI_OVER_360);
    float ymin = -xymax;
    float xmin = -xymax;

    float width = xymax - xmin;
    float height = xymax - ymin;

    float depth = zfar - znear;
    float q = -(zfar + znear) / depth;
    float qn = -2 * (zfar * znear) / depth;

    float w = 2 * znear / width;
    w = w / aspect;
    float h = 2 * znear / height;

    m[0]  = w;
    m[1]  = 0;
    m[2]  = 0;
    m[3]  = 0;

    m[4]  = 0;
    m[5]  = h;
    m[6]  = 0;
    m[7]  = 0;

    m[8]  = 0;
    m[9]  = 0;
    m[10] = q;
    m[11] = -1;

    m[12] = 0;
    m[13] = 0;
    m[14] = qn;
    m[15] = 0;
}

下面是如何在 OpenGL 1 / OpenGL 2 代码中使用它:

float m[16] = {0};
float fov=60.0f; // in degrees
float aspect=1.3333f;
float znear=1.0f;
float zfar=1000.0f;
BuildPerspProjMat(m, fov, aspect, znear, zfar);
glMatrixMode(GL_PROJECTION);
glLoadMatrixf(m);

// okay we can switch back to modelview mode
// for all other matrices
glMatrixMode(GL_MODELVIEW);

对于真正的 OpenGL 3.0 代码,我们必须使用 GLSL 着色器和统一变量来传递和利用变换矩阵:

float m[16] = {0};
float fov=60.0f; // in degrees
float aspect=1.3333f;
float znear=1.0f;
float zfar=1000.0f;
BuildPerspProjMat(m, fov, aspect, znear, zfar);
glUseProgram(shaderId);
glUniformMatrix4fv("projMat", 1, GL_FALSE, m);
RenderObject();
glUseProgram(0);

由于我没有使用过 Minecraft,我不知道它是否给你一个投影矩阵供你使用,或者你是否有其他信息来构建它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多