Java OpenGL ES在android上绘制正方形

Java OpenGL ES在android上绘制正方形,java,android,opengl-es,opengl-es-2.0,gpu,Java,Android,Opengl Es,Opengl Es 2.0,Gpu,我试图在OpenGL ES for android中绘制一个正方形,但由于某种原因,我的代码崩溃了,或者只显示了clearColor。我确信,带有renderer和GLSurfaceView类的项目设置是正确的,并且从文件导入顶点和片段着色器的函数可以正常工作。这是绘制正方形的代码(构造函数在我的渲染器类的onDrawFrame方法中的draw方法的onSurfaceCreated中调用): 导入android.content.Context; 导入android.opengl.GLES20;

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

导入android.content.Context;
导入android.opengl.GLES20;
导入java.io.BufferedReader;
导入java.io.InputStream;
导入java.io.InputStreamReader;
导入java.nio.FloatBuffer;
导入java.nio.IntBuffer;
公共课广场{
int ShaderProgramID;
私有浮动缓冲区顶点缓冲区;
私有int vertexBufferID;
私人帐户;
私人垂直跨步;
每个顶点的静态最终整数坐标=3;
每个顶点的静态最终整数颜色=4;
静态最终整数大小\u的\u浮点=4;
静态最终浮点坐标[]={
//x:y:z:r:g:b:a:
-0.5f,0.5f,0.0f,1.0f,0.0f,0.0f,1.0f,
-0.5f,-0.5f,0.0f,0.0f,1.0f,0.0f,1.0f,
0.5f,-0.5f,0.0f,0.0f,0.0f,1.0f,1.0f,
-0.5f,0.5f,0.0f,1.0f,0.0f,0.0f,1.0f,
0.5f,-0.5f,0.0f,0.0f,0.0f,1.0f,1.0f,
0.5f、0.5f、0.0f、1.0f、1.0f、1.0f、1.0f、,
};
公共广场(背景){
字符串vertexShaderSrc=ReadFromfile(“defaultVertexShader.glsl”,上下文);
字符串fragmentShaderSrc=ReadFromfile(“defaultFragmentShader.glsl”,上下文);
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,0,“aPos”);
GLES20.glBindAttribLocation(ShaderProgramID,1,“aColor”);
GLES20.glLinkProgram(ShaderProgramID);
positionHandle=GLES20.glGetAttriblLocation(ShaderProgramID,“a_位置”);
colorHandle=GLES20.glGetAttribLocation(ShaderProgramID,“a_Color”);
vertexBuffer=FloatBuffer.allocate(coords.length);
vertexBuffer.put(坐标);
顶点缓冲区位置(0);
IntBuffer buffer=IntBuffer.allocate(1);
GLES20.glGenBuffers(1,buffer);
vertexBufferID=buffer.get(0);
GLES20.glBindBuffer(GLES20.GL_数组_BUFFER,vertexBufferID);
GLES20.glBufferData(GLES20.GL_数组_BUFFER,coords.length*4,vertexBuffer,GLES20.GL_静态_DRAW);
vertexCount=coords.length/(每个顶点的坐标+每个顶点的颜色);
顶点跨步=(每个顶点的坐标+每个顶点的颜色)*4;
}
私人内特定位手柄;
私有int色柄;
公众抽签(){
GLES20.glUseProgram(ShaderProgramID);
顶点缓冲区位置(0);
GLES20.glVertexAttribute指针(位置句柄、每个顶点的坐标、GLES20.GL浮点、false、vertexStride、vertexBuffer);
GLES20.GlenableVertexAttributeArray(位置手柄);
顶点缓冲区位置(3);
GLES20.glVertexAttribute指针(颜色句柄、每个顶点的颜色、GLES20.GL浮点、false、vertexStride、vertexBuffer);
GLES20.GlenableVertexAttributeArray(colorHandle);
GLES20.GlDrawArray(GLES20.GL_三角形,0,6);
GLES20.GLDisableVertexAttributeArray(位置句柄);
GLES20.GLDisableVertexAttributeArray(colorHandle);
}
公共字符串ReadFromfile(字符串文件名、上下文){
StringBuilder ReturnString=新建StringBuilder();
InputStream fIn=null;
InputStreamReader isr=null;
BufferedReader输入=null;
试一试{
fIn=context.getResources().getAssets()
.open(文件名);
isr=新的输入流读取器(fIn);
输入=新的BufferedReader(isr);
字符串行=”;
而((line=input.readLine())!=null){
ReturnString.append(第+行“\n”);
}
}捕获(例外e){
e、 getMessage();
}最后{
试一试{
如果(isr!=null)
isr.close();
如果(fIn!=null)
fIn.close();
如果(输入!=null)
input.close();
}捕获(异常e2){
e2.getMessage();
}
}
返回ReturnString.toString();
}
}
这是VertexShaderCode:

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;
位置是4分量向量,但在“vertexBuffer”中,位置写为3分量向量。因此,请尝试改进着色器:

attribute vec3 aPos;
此外,使用了“a_位置”,但未在任何地方声明,因此:

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.0f, 0.0f, 1.0f,
        -0.5f,-0.5f, 0.0f,         0.0f, 1.0f, 0.0f, 1.0f,
         0.5f,-0.5f, 0.0f,         0.0f, 0.0f, 1.0f, 1.0f,
        -0.5f, 0.5f, 0.0f,         1.0f, 0.0f, 0.0f, 1.0f,
         0.5f,-0.5f, 0.0f,         0.0f, 0.0f, 1.0f, 1.0f,
         0.5f, 0.5f, 0.0f,         1.0f, 1.0f, 1.0f, 1.0f,

};
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, 0, "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, GLES20.GL_FLOAT,        false, vertexStride, 3);
    GLES20.glEnableVertexAttribArray(colorHandle);


    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 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);
}

顶点现在看起来像这样:属性vec3 aPos;属性vec4颜色;可变vec4颜色;void main(){v_Color=aColor;gl_Position=aPos;}但它仍在崩溃。我还确保只使用aPos和aColor,而不在codegl_Position=vec4(a_Pos,1.0)中的任何位置使用a_Pos或a_Color;我修复了所有错误,现在着色器已成功编译,但应用程序仍会显示哪一行崩溃?第76行:GLES20.GlvertexAttributePointer(positionHandle、COORDS_PER_VERTEX、GLES20.GL_FLOAT、false、vertexStride、vertexBuffer);