我正在尝试将Apple的旧版(2013年)代码从目标C转换为Swift,并进行了一些仿真所需的修改。
为了简化翻译,我将模拟分为多个部分。因此,我现在正在工作(并固定)的部分是:我只需要绘制常规的全屏纹理坐标着色器,但是我需要将其分解为网格。如果我的网格比例因子为1,那么屏幕上的每个像素都会得到一个三角形,这将构成网格。但是,如果我输入10,则每10像素会有一个三角形。本质上,这是模拟的分辨率。

我的问题是这些图像(数字表示池塘的比例因子):全屏纹理坐标绘制会绘制出这种怪异感(其中一些确实属于现代美术馆)。我真的不知道在哪里可以找到我的代码来找到这个问题,我猜是它是索引。上载到SO并不难。

所以首先要定义的是构成该模拟的所有数组: swift prettyprint-override“> var rSimWidth:Int = 0 var rSimHeight:Int = 0 var mesh:[GLfloat] = [] var tex:[GLfloat] = [] var ind:[Indicie] = [] var realWidth:Int = 0 var realHeight:Int = 0 //In this case width = 568, height = 320, mpp varies look at top of picture init(width: Int, height: Int, mpp: Int) { rSimWidth = width / mpp rSimHeight = height / mpp rSimWidth += 1; rSimHeight += 1 realWidth = width realHeight = height mesh = [GLfloat](count: rSimWidth * rSimHeight * 2, repeatedValue: 0) tex = [GLfloat](count: rSimWidth * rSimHeight * 2, repeatedValue: 0) ind = [Indicie](count: (rSimHeight-1)*(rSimWidth*2+2), repeatedValue: 0) print("Screen is (\(width) x \(height))\tPond is (\(rSimWidth) x \(rSimHeight))\tScreenSA: \(width * height)\tPond sa: \(rSimWidth * rSimHeight)\tMP: \(mpp) \((rSimWidth * rSimHeight) * mpp)") }

然后我填写索引。由于数据类型,我对此有困难。我相信对于索引,我应该使用GLushort,但是在我的系统上,最大值为65,535。此值很快被索引生成器溢出,因此我不得不将其切换为“ Int”。有一个typedef“ Indicie”,因此我可以轻松更改索引中的数据类型。我感到奇怪的是,当我在Apple代码中提高仿真分辨率时,我再也没有溢出问题。

     var index:Int = 0
    for i in 0..<rSimHeight - 1
    {
        for j in 0..<rSimWidth
        {
            if (i%2==0)//X is even
            {
                if (j == 0)
                {
                    //DEGENRATE TRIANGLE
                    ind[index] = Indicie(i*rSimWidth + j)
                    index += 1
                }

                ind[index] = Indicie(i * rSimWidth + j)
                index += 1
                ind[index] = Indicie((i + 1) * rSimWidth + j)
                index += 1
                //(114 + 1) * 569 + 101
                //

                if (j == rSimWidth - 1)
                {
                    //DEGENERATE TRIANGLE
                    ind[index] = Indicie((i+1)*rSimWidth + j)
                    index += 1
                }
            }
            else
            {
                if (j == 0)
                {
                    //DEGENRATE TRIANGLE
                    ind[index] = Indicie((i+1)*rSimWidth + j)
                    index += 1
                }

                ind[index] = Indicie((i + 1) * rSimWidth + j)
                index += 1
                ind[index] = Indicie(i * rSimWidth + j)
                index += 1

                if (j == rSimWidth - 1)
                {
                    //DEGENRATE TRIANGLE
                    ind[index] = Indicie(i*rSimWidth + j)
                    index += 1
                }
            }
        }
    }
 


如果您想查看位置和tc代码

   for yy in 0..<rSimHeight
    {let y = GLfloat(yy);
        for xx in 0..<rSimWidth
        {let x = GLfloat(xx);
            let index = (yy*rSimWidth + xx) * 2
            tex[index] = x / GLfloat(rSimWidth - 1)
            tex[index + 1] = y / GLfloat(rSimHeight - 1)

            mesh[index] = tex[index] * GLfloat(realWidth)
            mesh[index + 1] = tex[index + 1] * GLfloat(realHeight)
        }
    }
 


这里是工程图代码

      glUseProgram(shade.progId)


    let posLoc = GLuint(glGetAttribLocation(shade.progId, "pos"))
    let texLoc = GLuint(glGetAttribLocation(shade.progId, "tc"))


    glBindBuffer(GLenum(GL_ARRAY_BUFFER), texVBO);
    glBufferData(GLenum(GL_ARRAY_BUFFER), sim.tex.count * sizeof(GLfloat), sim.tex, GLenum(GL_DYNAMIC_DRAW));
    glVertexAttribPointer(texLoc, 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 2, BUFFER_OFFSET(0))
    glEnableVertexAttribArray(texLoc)

    glBindBuffer(GLenum(GL_ARRAY_BUFFER), posVBO)
    glVertexAttribPointer(posLoc, 2, GLenum(GL_FLOAT), GLboolean(GL_FALSE), 2, BUFFER_OFFSET(0))
    glEnableVertexAttribArray(posLoc)

    let uniOrtho = glGetUniformLocation(shade.progId, "matrix")
    glUniformMatrix4fv(uniOrtho, 1, GLboolean(GL_FALSE), &orthographicMatrix)


    glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), indVBO)


    glDrawElements(GLenum(GL_TRIANGLE_STRIP), GLsizei(sim.ind.count), GLenum(GL_UNSIGNED_SHORT), nil)

    glBindBuffer(GLenum(GL_ARRAY_BUFFER), 0)
    glBindBuffer(GLenum(GL_ELEMENT_ARRAY_BUFFER), 0)
    glDisableVertexAttribArray(posLoc)
    glDisableVertexAttribArray(texLoc)
 


我真的有0条线索,说明为什么这个奇怪的东西正在绘制而不是有意义的东西。

任何建议或建议都值得赞赏!

特别注意:基本上对于所有这些循环,请考虑

 for (var i = <value before ..>; i < <value after dot>; <happens automatically>)
 


编辑:这是矩阵代码

 var orthographicMatrix:[GLfloat] = []

    func buildMatrix()
    {
        orthographicMatrix = glkitmatrixtoarray(GLKMatrix4MakeOrtho(0, GLfloat(width), 0, GLfloat(height), -100, 100))
        //Storage.upScaleFactor
    }
    func glkitmatrixtoarray(mat: GLKMatrix4) -> [GLfloat]
    {
        var buildme:[GLfloat] = []
        buildme.append(mat.m.0)
        buildme.append(mat.m.1)
        buildme.append(mat.m.2)
        buildme.append(mat.m.3)
        buildme.append(mat.m.4)
        buildme.append(mat.m.5)
        buildme.append(mat.m.6)
        buildme.append(mat.m.7)
        buildme.append(mat.m.8)
        buildme.append(mat.m.9)
        buildme.append(mat.m.10)
        buildme.append(mat.m.11)
        buildme.append(mat.m.12)
        buildme.append(mat.m.13)
        buildme.append(mat.m.14)
        buildme.append(mat.m.15)
        return buildme

    }
 


现在的问题不是抽象艺术,而是矩形仅在半色调比例因子。请注意锯齿状的边缘


在苹果框架调试器中,您可以看到绘制的所有三角形的轮廓,如下所示:

这行引起了所有麻烦let index = (yy*rSimWidth + xx) * 2

测试:
我通过将3、3和1传递给初始化函数来尝试了代码。从理论上讲,这应该使一个3x3像素的正方形,但它只是一团糟。这是CPU上的所有数据,在这里(根据帧捕获的情况而定)是gpu对其的理解。


评论

您是否尝试过在glVertexAttribPointer调用中将stride设置为0?略读代码后,看起来基本上没问题:)

出于某种原因,它起作用了。不幸的是,矩形仅填充了屏幕数量的一半比例因子。

您的步幅应为0,通常仅在您具有交错缓冲区(同一VBO中的Pos&Tex)时使用。对于半屏,我需要查看您的正交矩阵。

@PaulHK添加到帖子中,我为此使用apples函数,然后将其放入一个float数组中。宽度和高度值与传递给波纹模拟的初始化值相同。

无法在任何地方看到仅会导致一半屏幕可见的地方,这可能是glViewPort设置错误的原因?

#1 楼

我认为您没有正确构建索引缓冲区。首先,您只需要1个退化顶点即可终止每个三角形带行。

对于奇数/偶数行,您也不需要任何特殊处理。您可以为每个循环发出一个三角形的条纹。

您的索引循环应类似于:的定义如下:顶点列表中的每个奇数项都是顶点0。这看起来像索引缓冲区是使用32位索引创建的,但被opengl解释为16位。因此它将读取每个索引的低16位,然后高16位。可以通过将Indicie数据类型更改为16位(短)或通过使用glDrawElements中的GL_UNSIGNED_INT而不是GL_UNSIGNED_SHORT告诉opengl索引缓冲区实际上是32位来解决此问题。

评论


$ \ begingroup $
您的代码会导致相同的问题,但是效率更高,所以,谢谢!,我已经用一些可能有用的新图表更新了帖子。
$ \ endgroup $
–J.Doe
16年9月1日在8:44

$ \ begingroup $
看起来像是被画成三角扇形,但不完全是。是否可以制作一个小的网格(例如9个点,所以rSimXXX = 3),然后手动检查/转储索引缓冲区?
$ \ endgroup $
–PaulHK
16年9月1日在8:59

$ \ begingroup $
当然,我在帖子底部添加了一个部分。让我知道您是否需要/想要更多数据。
$ \ endgroup $
–J.Doe
16年9月1日在9:40

$ \ begingroup $
好的,事情开始变得有意义了,好像您对其他所有元素都插入了0,这解释了所有尖角三角形都到达一个角。我怀疑您的Indicie(..)对象是32位,但是在glDrawElements调用中您告诉opengl索引缓冲区是16位(无符号短裤)。您可以将glDrawElements更改为接受32位整数(更改GL_UNSIGNED_SHORT-> GL_UNSIGNED_INT),也可以将Indicie对象更改为16位(我猜为int-> short,但我不熟悉swift)。
$ \ endgroup $
–PaulHK
16 Sep 1'在9:42



$ \ begingroup $
我也在上面的示例中进行了编辑,以删除多余的行尾if(...)
$ \ endgroup $
–PaulHK
16年9月1日在9:44