我正在尝试学习如何使用vaos和vbos。现在,我正在尝试渲染一个正方形,但是屏幕上没有任何渲染。我正在使用android studio和OpenGL ES 3。
这是我的MainActivity:
package com.example.karno.androidgameprojectv3;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import renderEngine.DisplayManager;
import renderEngine.MainRenderer;
public class MainActivity extends Activity {
DisplayManager gameView;
MainRenderer renderer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
renderer = new MainRenderer();
gameView = new DisplayManager(this);
gameView.setEGLContextClientVersion(3);
gameView.setRenderer(renderer);
this.setContentView(gameView);
}
@Override
protected void onDestroy(){
// Log.d("------test", "in on destroy");
renderer.loader.cleanUp();
super.onDestroy();
}
}
这是我绑定vaos和vbos的Loader类:
package renderEngine;
import android.opengl.GLES11;
import android.opengl.GLES20;
import android.opengl.GLES30;
import android.util.Log;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
public class Loader {
private int [] vaos;
private int [] vbos;
private int countVbos = -1;
private int countVaos = -1;
public Loader( int neededVAOs, int neededVBOs){
vaos = new int[neededVAOs];
vbos = new int[neededVBOs];
}
public RawModel loadToVAO(float[] position) {
int vaoID = createVAO();
storeDataInAttributeList(0, 3, position);
unbindVAO();
Log.d("looking for null---", "position = " + position);
return new RawModel(vaoID, position.length/3);
}
private int createVAO() {
countVaos++;
GLES30.glGenVertexArrays(1, vaos, 0);
GLES30.glBindVertexArray(vaos[countVaos]);
return vaos[countVaos];
}
private void storeDataInAttributeList(int attributeNumber, int coordinateSize, float[] data) {
countVbos++;
// GLES30.glGenBuffers(1, vbos);
GLES20.glGenBuffers(1, vbos,0);
// Log.d("------vbo", "vbo id = " + vbos.get(countVbos));
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, vbos[countVbos]);
FloatBuffer buffer = storeDataInFloatBuffer(data);
// Log.d("looking for null arg", "arg2 = " + vbos.get(countVbos) + ", arg3 = " + buffer);
GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER, vbos[0], buffer, GLES30.GL_STATIC_DRAW);
GLES30.glVertexAttribPointer(attributeNumber, coordinateSize, GLES30.GL_FLOAT, false, 0, 0);
GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, 0);
}
private FloatBuffer storeDataInFloatBuffer(float[] data) {
FloatBuffer buffer = FloatBuffer.allocate(data.length);
buffer.put(data);
buffer.flip();
return buffer;
}
private void unbindVAO() {
// this will unbind the VAO
GLES30.glBindVertexArray(0);
}
public void cleanUp() {
Log.d("--------", "in clean up");
for (int vao : vaos) {
GLES30.glDeleteBuffers(vao, vaos, 0);
}
countVaos = -1;
for (int vbo : vbos) {
GLES20.glDeleteBuffers(vbo, vbos,0);
}
countVbos = -1;
Log.d("--------", "cleaned up.");
}
}
MainRenderer:
package renderEngine;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.util.Log;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class MainRenderer implements GLSurfaceView.Renderer {
public Loader loader;
Renderer renderer;
RawModel model;
private static final int NEEDED_VAOS = 1;
private static final int NEEDED_VBOS = 1;
//square
float[] vertecies = {
-0.5f, 0.5f, 0f,
-0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, -0.5f, 0f,
0.5f, 0.5f, 0f,
-0.5f, 0.5f, 0f,
};
@Override
public void onDrawFrame(GL10 arg0){
// GLES20.glClearColor(0,1,0,1);
// GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
renderer.prepare();
renderer.render(model);
}
@Override
public void onSurfaceChanged(GL10 arg0, int height, int width){
}
@Override
public void onSurfaceCreated(GL10 arg0, EGLConfig config){
// Log.d("check------", "in on surface created.");
loader = new Loader(NEEDED_VAOS, NEEDED_VBOS);
renderer = new Renderer();
model = loader.loadToVAO(vertecies);
}
}
视图:
package renderEngine;
import android.content.Context;
import android.opengl.GLSurfaceView;
public class DisplayManager extends GLSurfaceView {
public DisplayManager(Context context){
super(context);
}
}
Render类:
package renderEngine;
import android.opengl.GLES11;
import android.opengl.GLES20;
import android.opengl.GLES30;
import android.util.Log;
public class Renderer {
public void prepare(){
GLES11.glClearColor(0,1,0,1);
GLES11.glClear(GLES11.GL_COLOR_BUFFER_BIT);
}
public void render(RawModel model) {
// Log.d("------render","model.getVaoID() = "+ model.getVaoID());
GLES30.glBindVertexArray(model.getVaoID());
GLES30.glEnableVertexAttribArray(0);
GLES11.glDrawArrays(GLES11.GL_TRIANGLES, 0, model.getVertexCount());
GLES20.glDisableVertexAttribArray(0);
GLES30.glBindVertexArray(0);
}
}
3d模型。
package renderEngine;
public class RawModel
{
private int vaoID;
private int vertexCount;
public RawModel(int vaoID, int vertexCount)
{
this.vaoID = vaoID;
this.vertexCount = vertexCount;
}
/**
* @return the vaoID
*/
public int getVaoID() {
return vaoID;
}
/**
* @return the vertexCount
*/
public int getVertexCount() {
return vertexCount;
}
}
在logcat中,我得到了:
2019-01-06 20:33:43.667 4618-4657 / com.example.karno.androidgameprojectv3 E / emuglGLESv2_enc:检测到超出边界的顶点属性索引。跳过相应的顶点属性。 buf = 0x7c2911e22a00
2019-01-06 20:33:43.667 4618-4657 / com.example.karno.androidgameprojectv3 E / emuglGLESv2_enc:越界顶点属性信息:clientArray? 0属性0 vbo 1 allocedBufferSize 1 bufferDataSpecified? 1个通缉犯0个通缉犯完72
任何帮助将不胜感激。
答案 0 :(得分:1)
GLES30.glBufferData
的第二个参数必须是缓冲区的大小(以字节为单位),而不是命名的缓冲区对象。
另请参见Java Code Examples for android.opengl.GLES20.glBufferData()和glBufferData
:
GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER,
buffer.capacity() * BYTES_PER_FLOAT, buffer, GLES30.GL_STATIC_DRAW);
注意glBufferData
为当前由glBindBuffer
绑定的缓冲区对象创建并初始化缓冲区对象的数据存储。