安卓系统上的openGl-es在右上角显示一个正方形



我写了一段代码,应该在屏幕上画一个带有颜色渐变的正方形,但出于某种原因,它也在屏幕右上角画了一个蓝色正方形。蓝色方块有时会改变它的颜色,当我改变代码中的东西时,这与它完全无关,例如我的渲染器中的一行代码,我在那里读取以像素为单位的屏幕大小。有时,当我截屏时,它也会消失。这是代码:

import android.content.Context;
import android.opengl.GLES30;
import android.util.Log;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
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, 1.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f,         0.0f, 0.0f, 1.0f, 1.0f
};
public Square(Context context)  {
String vertexShaderSrc = ReadFromfile("defaultVertexShader.glsl", context);
String fragmentShaderSrc = ReadFromfile("defaultFragmentShader.glsl", context);
int vertexID = GLES30.glCreateShader(GLES30.GL_VERTEX_SHADER);
GLES30.glShaderSource(vertexID, vertexShaderSrc);
GLES30.glCompileShader(vertexID);
Log.d("Golden", GLES30.glGetShaderInfoLog(vertexID));
int fragmetID = GLES30.glCreateShader(GLES30.GL_FRAGMENT_SHADER);
GLES30.glShaderSource(fragmetID, fragmentShaderSrc);
GLES30.glCompileShader(fragmetID);
Log.d("Golden", GLES30.glGetShaderInfoLog(fragmetID) );
ShaderProgramID = GLES30.glCreateProgram();
GLES30.glAttachShader(ShaderProgramID, vertexID);
GLES30.glAttachShader(ShaderProgramID, fragmetID);
GLES30.glBindAttribLocation(ShaderProgramID, 0, "aPos");
GLES30.glBindAttribLocation(ShaderProgramID, 1, "aColor");
GLES30.glLinkProgram(ShaderProgramID);
positionHandle = GLES30.glGetAttribLocation(ShaderProgramID, "aPos");
colorHandle = GLES30.glGetAttribLocation(ShaderProgramID, "aColor");
//vertexBuffer = FloatBuffer.allocate(coords.length);
//vertexBuffer = ByteBuffer.allocate(coords.length*4).asFloatBuffer();
//vertexBuffer.put(coords);
//vertexBuffer.position(0);
ByteBuffer bb = ByteBuffer.allocateDirect(coords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(coords);
vertexBuffer.position(0);
IntBuffer buffer = IntBuffer.allocate(1);
GLES30.glGenBuffers(1, buffer);
vertexBufferID = buffer.get(0);
GLES30.glBindBuffer(GLES30.GL_ELEMENT_ARRAY_BUFFER, vertexBufferID);
GLES30.glBufferData(GLES30.GL_ELEMENT_ARRAY_BUFFER, coords.length * 4, vertexBuffer, GLES30.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() {
GLES30.glUseProgram(ShaderProgramID);
vertexBuffer.position(0);
GLES30.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES30.GL_FLOAT, false, vertexStride, vertexBuffer);
GLES30.glEnableVertexAttribArray(positionHandle);

vertexBuffer.position(3);
GLES30.glVertexAttribPointer(colorHandle, COLORS_PER_VERTEX, GLES30.GL_FLOAT, false, vertexStride, vertexBuffer);
GLES30.glEnableVertexAttribArray(colorHandle);

GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, coords.length);
GLES30.glDisableVertexAttribArray(positionHandle);
GLES30.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 300 es
precision mediump float;
in vec4 vColor;
out vec4 oColor;
void main()
{
oColor = vColor;
}

顶点着色器:

#version 300 es
in vec3 aPos;
in vec4 aColor;
out vec4 vColor;
void main()
{
vColor = aColor;
gl_Position = vec4(aPos,1.0);
}

必须将顶点绑定到GL_ARRAY_BUFFERtraget,而不是GL_ELEMENT_ARRAY_BUFFERtarget:

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

参见glVertexAttribPointer:

如果非零命名缓冲区对象绑定到GL_ARRAY_BUFFER target(请参见glBindBuffer(,则指针将被视为缓冲区对象数据存储的字节偏移量。

在您的情况下,步长为28字节((3+4(*4(。顶点的偏移为0字节,颜色属性的偏移为12字节(3*4(:

GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vertexBufferID);
GLES30.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, 
GLES30.GL_FLOAT, false, 7*4, 0);
GLES30.glVertexAttribPointer(colorHandle, COLORS_PER_VERTEX, 
GLES30.GL_FLOAT, false, 7*4, 3*4);
GLES30.glEnableVertexAttribArray(positionHandle);
GLES30.glEnableVertexAttribArray(colorHandle);

glDrawArrays的最后一个参数是顶点数,而不是数组中的浮点数:

GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, coords.length / 7);

GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, coords.length / 7);

在glDrawArrays中,必须有要绘制的顶点数,而不是顶点缓冲区的长度。

GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, vertexCount);

最新更新