微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

OpenGL ES 在 android 上绘制一个正方形

如何解决OpenGL ES 在 android 上绘制一个正方形

我尝试在 OpenGL ES 中为 android 绘制一个正方形,但由于某种原因,我的代码崩溃了,或者只显示了 clearColor。我敢肯定,使用渲染器和 GLSurfaceView 类设置的项目是正确的,并且从文件导入顶点和片段着色器的函数工作正常。这是绘制正方形的代码(在我的渲染器类的 onDrawFrame 方法中的 draw 方法的 onSurfaceCreated 中调用构造函数):

import android.content.Context;
import android.opengl.GLES20;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

public class Square {
    int ShaderProgramID;
    private FloatBuffer vertexBuffer;
    private int vertexBufferID;
    private int vertexCount;
    private int vertexStride;
    static final int COORDS_PER_VERTEX = 3;
    static final int COLORS_PER_VERTEX = 4;
    static final int SIZE_OF_FLOAT = 4;
    static final float coords[] = {
          //x:    y:     z:            r:    g:    b:    a:
            -0.5f,0.5f,0.0f,1.0f,-0.5f,};
    public Square(Context context)  {
        String vertexShaderSrc = ReadFromfile("defaultVertexShader.glsl",context);
        String fragmentShaderSrc = ReadFromfile("defaultFragmentShader.glsl",context);

        int vertexID = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
        GLES20.glShaderSource(vertexID,vertexShaderSrc);
        GLES20.glCompileShader(vertexID);

        int fragmetID = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
        GLES20.glShaderSource(fragmetID,fragmentShaderSrc);
        GLES20.glCompileShader(fragmetID);

        ShaderProgramID = GLES20.glCreateProgram();
        GLES20.glAttachShader(ShaderProgramID,vertexID);
        GLES20.glAttachShader(ShaderProgramID,fragmetID);
        GLES20.glBindAttribLocation(ShaderProgramID,"aPos");
        GLES20.glBindAttribLocation(ShaderProgramID,1,"aColor");
        GLES20.glLinkProgram(ShaderProgramID);

        positionHandle = GLES20.glGetAttribLocation(ShaderProgramID,"a_Position");
        colorHandle = GLES20.glGetAttribLocation(ShaderProgramID,"a_Color");

        vertexBuffer = FloatBuffer.allocate(coords.length);
        vertexBuffer.put(coords);
        vertexBuffer.position(0);
        IntBuffer buffer = IntBuffer.allocate(1);
        GLES20.glGenBuffers(1,buffer);
        vertexBufferID = buffer.get(0);
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER,vertexBufferID);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,coords.length * 4,vertexBuffer,GLES20.GL_STATIC_DRAW);

        vertexCount = coords.length / (COORDS_PER_VERTEX + COLORS_PER_VERTEX);
        vertexStride = (COORDS_PER_VERTEX + COLORS_PER_VERTEX) * 4;
    }
    private int positionHandle;
    private int colorHandle;
    public void draw() {
        GLES20.gluseProgram(ShaderProgramID);


        vertexBuffer.position(0);
        GLES20.glVertexAttribPointer(positionHandle,COORDS_PER_VERTEX,GLES20.GL_FLOAT,false,vertexStride,vertexBuffer);
        GLES20.glEnabLevertexAttribArray(positionHandle);


        vertexBuffer.position(3);
        GLES20.glVertexAttribPointer(colorHandle,COLORS_PER_VERTEX,vertexBuffer);
        GLES20.glEnabLevertexAttribArray(colorHandle);


        GLES20.glDrawArrays(GLES20.GL_TRIANGLES,6);
        GLES20.gldisabLevertexAttribArray(positionHandle);
        GLES20.gldisabLevertexAttribArray(colorHandle);

    }

    public String ReadFromfile(String fileName,Context context) {
        StringBuilder ReturnString = new StringBuilder();
        InputStream fIn = null;
        InputStreamReader isr = null;
        BufferedReader input = null;
        try {
            fIn = context.getResources().getAssets()
                    .open(fileName);
            isr = new InputStreamReader(fIn);
            input = new BufferedReader(isr);
            String line = "";
            while ((line = input.readLine()) != null) {
                ReturnString.append(line + "\n");
            }
        } catch (Exception e) {
            e.getMessage();
        } finally {
            try {
                if (isr != null)
                    isr.close();
                if (fIn != null)
                    fIn.close();
                if (input != null)
                    input.close();
            } catch (Exception e2) {
                e2.getMessage();
            }
        }
        return ReturnString.toString();
    }
}

这是顶点着色器代码

attribute vec4 aPos;
attribute vec4 aColor;

varying vec4 v_Color;

void main()
{
    v_Color = a_Color;
    gl_Position = a_Position;
}

这是 Fragmentshadercode

precision mediump float;
varying vec4 v_Color;
void main()
{
    gl_FragColor = v_Color;
}

解决方法

在顶点着色器中:

attribute vec4 aPos;

position 是 4 分量向量,但在“vertexBuffer”中位置被写为 3 分量向量。所以尝试改进着色器:

attribute vec3 aPos;

还使用了“a_Position”,但未在任何地方声明,请执行以下操作:

gl_Position = vec4(a_Pos,1.0);

并在此处改进:

positionHandle = GLES20.glGetAttribLocation(ShaderProgramID,"a_Pos");

此代码可以显示着色器是否已编译,以及一个错误。

int[] compiled = new int[1];
        GLES31.glGetShaderiv(shader,GLES31.GL_COMPILE_STATUS,compiled,0);
        if (compiled[0] == 0) {
            GLES31.glDeleteShader(shader);
            throw new RuntimeException("Could not compile program: "
                    + GLES31.glGetShaderInfoLog(shader) + " | ");
        }

这是准备浮动缓冲区的正确方法:

ByteBuffer bb = ByteBuffer.allocateDirect(coords.length*4);
bb.order(ByteOrder.nativeOrder());

FloatBuffer vertexBuffer = bb.asFloatBuffer();
,

这是当前代码:

import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLES31;
import android.util.Log;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;


public class Square {
int ShaderProgramID;
private FloatBuffer vertexBuffer;
private int vertexBufferID;
private int vertexCount;
private int vertexStride;
static final int COORDS_PER_VERTEX = 3;
static final int COLORS_PER_VERTEX = 4;
static final int SIZE_OF_FLOAT = 4;
static final float coords[] = {
        //x:    y:     z:            r:    g:    b:    a:
        -0.5f,0.5f,0.0f,1.0f,-0.5f,};
public Square(Context context)  {
    String vertexShaderSrc = ReadFromfile("defaultVertexShader.glsl",context);
    String fragmentShaderSrc = ReadFromfile("defaultFragmentShader.glsl",context);

    int vertexID = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
    GLES20.glShaderSource(vertexID,vertexShaderSrc);
    GLES20.glCompileShader(vertexID);

    int fragmetID = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
    GLES20.glShaderSource(fragmetID,fragmentShaderSrc);
    GLES20.glCompileShader(fragmetID);

    ShaderProgramID = GLES20.glCreateProgram();
    GLES20.glAttachShader(ShaderProgramID,vertexID);
    GLES20.glAttachShader(ShaderProgramID,fragmetID);
    GLES20.glBindAttribLocation(ShaderProgramID,"aPos");
    GLES20.glBindAttribLocation(ShaderProgramID,1,"aColor");
    GLES20.glLinkProgram(ShaderProgramID);

    positionHandle = GLES20.glGetAttribLocation(ShaderProgramID,"aPos");
    colorHandle = GLES20.glGetAttribLocation(ShaderProgramID,"aColor");

    vertexBuffer = FloatBuffer.allocate(coords.length);
    vertexBuffer.put(coords);
    vertexBuffer.position(0);
    IntBuffer buffer = IntBuffer.allocate(1);
    GLES20.glGenBuffers(1,buffer);
    vertexBufferID = buffer.get(0);
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER,vertexBufferID);
    GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,coords.length * 4,vertexBuffer,GLES20.GL_STATIC_DRAW);

    vertexCount = coords.length / (COORDS_PER_VERTEX + COLORS_PER_VERTEX);
    vertexStride = (COORDS_PER_VERTEX + COLORS_PER_VERTEX) * 4;
}
private int positionHandle;
private int colorHandle;
public void draw() {
    GLES20.glUseProgram(ShaderProgramID);

    vertexBuffer.position(0);
    GLES20.glVertexAttribPointer(positionHandle,COORDS_PER_VERTEX,GLES20.GL_FLOAT,false,vertexStride,0);
    GLES20.glEnableVertexAttribArray(positionHandle);


    vertexBuffer.position(3);
    GLES20.glVertexAttribPointer(colorHandle,COLORS_PER_VERTEX,3);
    GLES20.glEnableVertexAttribArray(colorHandle);


    GLES20.glDrawArrays(GLES20.GL_TRIANGLES,6);
    GLES20.glDisableVertexAttribArray(positionHandle);
    GLES20.glDisableVertexAttribArray(colorHandle);

}

public String ReadFromfile(String fileName,Context context) {
    StringBuilder ReturnString = new StringBuilder();
    InputStream fIn = null;
    InputStreamReader isr = null;
    BufferedReader input = null;
    try {
        fIn = context.getResources().getAssets()
                .open(fileName);
        isr = new InputStreamReader(fIn);
        input = new BufferedReader(isr);
        String line = "";
        while ((line = input.readLine()) != null) {
            ReturnString.append(line + "\n");
        }
    } catch (Exception e) {
        e.getMessage();
    } finally {
        try {
            if (isr != null)
                isr.close();
            if (fIn != null)
                fIn.close();
            if (input != null)
                input.close();
        } catch (Exception e2) {
            e2.getMessage();
        }
    }
    return ReturnString.toString();
}
}

片段:

#version 310 es
precision mediump float;
in vec4 vColor;
void main()
{
gl_FragColor = vColor;
}

顶点:

#version 310 es
attribute vec3 aPos;
attribute vec4 aColor;
out vec4 vColor;

void main()
{
vColor = aColor;
gl_Position = vec4(aPos,1.0);
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。