【问题标题】:OpenGL Lines with textures带有纹理的 OpenGL 线条
【发布时间】:2013-10-10 10:43:22
【问题描述】:

我想在 OpenGL 中创建一个电闪电。为此我写了这个函数:

public Blitz()
{
    points = new float[STEPS * 3];

    for(int i = 0; i < STEPS; i += 3)
    {
        points[i]     = (float) (startX + i * (endX - startX) / STEPS);
        points[i + 1] = (float) (startY + i * (endY - startY) / STEPS);
        points[i + 2] = 0;
    }

    // ...
    vertexBuffer.put(points);
    vertexBuffer.position(0);

}

public void update()
{
    for(int i = 0; i < STEPS; i += 3)
    {
        float rnd = random(); // creates rnd float

        if(points[i] + rnd < startX + 5 && points[i] + rnd > startX - 5)
        {
            points[i] += rnd;
        }
    }

    vertexBuffer.clear();
    vertexBuffer.put(points);
    vertexBuffer.position(0);
}

public void render()
{
    texture.bind();

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);

    gl.glLineWidth(10);
    gl.glDrawArrays(GL10.GL_LINE_STRIP, 0, STEPS);
}

这是我用于纹理的纹理类:

public class Texture 
{
    private GL10 gl;

    FloatBuffer texCoords;
    private int textureID;

    public Texture(GL10 gl, Bitmap bmp)
    {   
        this.gl = gl;

        int[] TextureIDs = new int[1];
        gl.glGenTextures(1, TextureIDs, 0);     
        textureID = TextureIDs[0];

        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GL10.GL_RGBA, bmp, 0);

        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);

        ByteBuffer buffer = ByteBuffer.allocateDirect( 4 * 2 * 4 );
        buffer.order(ByteOrder.nativeOrder());
        texCoords = buffer.asFloatBuffer(); 
        texCoords.put(0);
        texCoords.put(0);

        texCoords.put(0);
        texCoords.put(1);

        texCoords.put(1);
        texCoords.put(1);

        texCoords.put(1);
        texCoords.put(0);       
        texCoords.rewind();
    }

    public void bind()
    {   
        gl.glEnable(GL10.GL_BLEND);
        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_SRC_ALPHA);

        gl.glEnable(GL10.GL_TEXTURE_2D);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texCoords);
    }

    public void dispose()
    {
        int[] textures = {textureID};
        gl.glDeleteTextures(1, textures, 0);
        textureID = 0;              
    }
}

使用普通颜色效果很好,但如果我想把这个纹理放在线条上,它会得到这个结果:

你有什么想法吗?我的错误是什么?

【问题讨论】:

  • 我在这段代码中没有看到单个 OpenGL API 调用,您所做的只是展示了如何计算几个点。此外,您仍然必须像处理三角形一样对线图元进行纹理映射,而且我没有看到任何纹理坐标。
  • 我添加了我的纹理类

标签: android opengl-es


【解决方案1】:

你的错误是,你假设,一条 OpenGL 线能够绘制一个纹理,其中一个坐标垂直于线方向变化。 OpenGL 根本无法做到这一点,因为纹理坐标是顶点属性,一条线段只有两个顶点。这意味着,任何纹理坐标的变化都只能沿着这条线,而不是垂直于它。

解决方案不是画一条线,而是一条四边形或三角形条带,其顶点被拉伸到线的两侧。使用在屏幕平行空间中运行的着色器最容易做到这一点。

【讨论】:

  • 哦,好吧,我认为这很容易,因为我是 OpenGL 的新手。当然,我知道如何绘制三角形,但是绘制背后的逻辑和随机坐标要复杂得多。不是有一个函数可以让我将纹理旋转到线条的当前角度吗?
  • @Cilenco:不,没有这样的功能。一条线段仅由两个顶点组成,并且仅在顶点处分配了一些纹理坐标。并不是说理论上您可以使用片段着色器来确定每个渲染像素到线中心的距离并将其用作纹理坐标。但这要求您首先在顶点着色器中对基于像素的屏幕空间进行整个转换。这不是太难。 /// 无论如何,OpenGL 并不是一个旨在“易于”使用的 API。它或多或少是一支复杂的铅笔,可以在操作系统提供的画布上绘图。
  • @Cilenco:图片的实际质量取决于你使用铅笔的技巧。
  • 谢谢,但我还有一个问题:如何删除从最后一点到 0|0 的行?
  • @Cilenco:很难从您的代码中看出,因为缺少与该问题相关的部分(可能)。但是,如果我必须做出有根据的猜测,您的代码中有一个错误的错误,即您通过 1 个元素太短来计算数组长度,或者您向 OpenGL 传递的长度参数太大了 1,然后OpenGL将未初始化的内存作为实际数据。
猜你喜欢
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 2017-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-17
  • 1970-01-01
相关资源
最近更新 更多