无法在安卓上使用OpenGL ES 2.0绘制三角形

3
我正在跟随 developer.android.com 上有关使用 opengl 的教程进行编码,但是我遇到了一些错误,我试图修复它们,但并没有成功。我已经创建了一个主活动,在该活动中,当您按下按钮时,意图会打开一个显示黑屏但无法显示三角形的 opengl 活动。你能告诉我问题出在哪里吗?
这是我的 MainActivity 类:
package com.eBook.test;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;

public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final Button button = (Button)findViewById(R.id.button);
    button.setOnClickListener(new OnClickListener() {
        public void onClick(View v){
            Intent intent = new Intent (MainActivity.this,   OpenGLES20Activity.class);                               
            startActivity(intent);
        }
    });


}

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

/**
 * A placeholder fragment containing a simple view.
 */
public static class PlaceholderFragment extends Fragment {

    public PlaceholderFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_main, container,
                false);
        return rootView;
    }
}

}

这个看起来没问题,现在这是我的OpenGL活动类:

package com.eBook.test;

import android.app.Activity;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Bundle;

public class OpenGLES20Activity extends Activity {

private GLSurfaceView mGLView;

class MyGLSurfaceView extends GLSurfaceView {

    public MyGLSurfaceView(Context context){
        super(context);
     // Create an OpenGL ES 2.0 context
        setEGLContextClientVersion(2);

        // Set the Renderer for drawing on the GLSurfaceView
        setRenderer(new MyRenderer());
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Create a GLSurfaceView instance and set it
    // as the ContentView for this Activity.
    mGLView = new MyGLSurfaceView(this);
    setContentView(mGLView);



}

@Override
protected void onPause() {
    mGLView.onPause();
    super.onPause();
}

@Override
protected void onResume() {
    mGLView.onResume();
    super.onResume();
}


}

那是我的渲染器类:
package com.eBook.test;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.opengl.GLES20;
import android.opengl.GLSurfaceView;

public class MyRenderer implements GLSurfaceView.Renderer {

private Triangle mTriangle;


public void onSurfaceCreated(GL10 unused, EGLConfig config) {
    // Set the background frame color
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
 // initialize a triangle
    mTriangle = new Triangle();

}


public void onDrawFrame(GL10 unused) {
    // Redraw background color

    mTriangle.draw();
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

}

public void onSurfaceChanged(GL10 unused, int width, int height) {
    GLES20.glViewport(0, 0, width, height);
}

public static int loadShader(int type, String shaderCode){

    // create a vertex shader type (GLES20.GL_VERTEX_SHADER)
    // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
    int shader = GLES20.glCreateShader(type);

    // add the source code to the shader and compile it
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);

    return shader;
}

}

还有三角形类:

package com.eBook.test;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import android.opengl.GLES20;

public class Triangle {

private FloatBuffer vertexBuffer;
private int mProgram;
private int mPositionHandle;
private int mColorHandle;


// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float triangleCoords[] = {   // in counterclockwise order:
         0.0f,  0.622008459f, 0.0f, // top
        -0.5f, -0.311004243f, 0.0f, // bottom left
         0.5f, -0.311004243f, 0.0f  // bottom right
};

// Set color with red, green, blue and alpha (opacity) values
float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };


private final String vertexShaderCode =
        "attribute vec4 vPosition;" +
        "void main() {" +
        "  gl_Position = vPosition;" +
        "}";

private final String fragmentShaderCode =
        "precision mediump float;" +
        "uniform vec4 vColor;" +
        "void main() {" +
        "  gl_FragColor = vColor;" +
        "}";


public Triangle() {



    int vertexShader = MyRenderer.loadShader(GLES20.GL_VERTEX_SHADER,   vertexShaderCode);
    int fragmentShader = MyRenderer.loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

    mProgram = GLES20.glCreateProgram();             // create empty OpenGL ES Program
    GLES20.glAttachShader(mProgram, vertexShader);   // add the vertex shader to program
    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
    GLES20.glLinkProgram(mProgram);                  // creates OpenGL ES program executables




    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(
            // (number of coordinate values * 4 bytes per float)
            triangleCoords.length * 4);
    // use the device hardware's native byte order
    bb.order(ByteOrder.nativeOrder());

    // create a floating point buffer from the ByteBuffer
    vertexBuffer = bb.asFloatBuffer();
    // add the coordinates to the FloatBuffer
    vertexBuffer.put(triangleCoords);
    // set the buffer to read the first coordinate
    vertexBuffer.position(0);

}

  public void draw() {
        // Add program to OpenGL ES environment
        GLES20.glUseProgram(mProgram);

        // get handle to vertex shader's vPosition member
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

        // Enable a handle to the triangle vertices
        GLES20.glEnableVertexAttribArray(mPositionHandle);

        // Prepare the triangle coordinate data

        int vertexStride = 3;
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                     GLES20.GL_FLOAT, false,
                                    vertexStride, vertexBuffer);

        // get handle to fragment shader's vColor member
        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

        // Set color for drawing the triangle
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);

        // Draw the triangle


        int vertexCount = 6;
        GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

        // Disable vertex array
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }



}

我不太清楚vertexCount和vertexStride应该取何值,从逻辑上讲,vertexCount可能应该是3,但vertexStride我不确定。


错误发生在哪里,它给了你什么错误? - Jimmy Smith
哦,出现了错误,因为我没有初始化vertexCount和vertexStride,所以我初始化了它们,错误消失了,但是我初始化错误了,所以我的三角形没有显示。不过Tyler Olson已经帮助了我,还是谢谢! :) - user3772487
1个回答

5
清除背景后再绘制三角形 ;)
public void onDrawFrame(GL10 unused) {
// Redraw background color

GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
mTriangle.draw();

}

没有帮助 :( 我觉得 vertexCount 和 vertexStride 有问题,也许是在某个地方出了错? - user3772487
尝试将vertexCount更改为3,将vertexStride更改为3 * COORDS_PER_VERTEX。这个人似乎已经找到了一些解决方法。 - aProperFox
没问题 :) 如果您愿意的话,能否标记一下我的答案已解决您的问题,这样其他人就不会继续尝试解决了呢? - aProperFox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接