OpenGL ES 2.0的上下文中的Andr​​oid [英] OpenGL ES 2.0 Context in Android

查看:159
本文介绍了OpenGL ES 2.0的上下文中的Andr​​oid的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的OpenGL在Android和我已经阅读大量文件样本,我有点明白了。但是,试图做任何事情复杂之前,我想画一个简单的2D白色矩形,黑色bacground。仅此而已。

我被困在此错误:没有当前上下文,这似乎是我打电话从非OpenGL的<东西调用的OpenGL ES API code>发。问题是,我不知道是什么原因来自OpenGL 调用。因此,这里是我的code

// ==============活动================== //

 公共类MainActivity延伸活动{

公共静态字符串变量= MainActivity.class.getSimpleName();

MyGLSurfaceView表面;

@覆盖
保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow()。setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
    );

    表面=新MyGLSurfaceView(本);
    的setContentView(面);
}

@覆盖
保护无效的onPause(){
    super.onPause();
    surface.onPause();
}

@覆盖
保护无效onResume(){
    super.onResume();
    surface.onResume();
}

}
 

// ==================== GLSurfaceView ======================== //

 公共类MyGLSurfaceView扩展GLSurfaceView {

MyGLSurfaceRenderer渲染器;

公共MyGLSurfaceView(上下文的背景下){
    超(上下文);

    setEGLContextClientVersion(2);

    渲染器=新MyGLSurfaceRenderer(本);
    setRenderer(渲染);
}

}
 

// ==================渲染========================== //

 公共类MyGLSurfaceRenderer实现GLSurfaceView.Renderer {

大大方方=新广场();

公共MyGLSurfaceRenderer(MyGLSurfaceView面){

}

@覆盖
公共无效onDrawFrame(GL10 GL){
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    square.draw();
}

@覆盖
公共无效onSurfaceChanged(GL10 GL,诠释的宽度,高度INT){
    // TODO自动生成方法存根

}

@覆盖
公共无效onSurfaceCreated(GL10 GL,EGLConfig配置){
    GLES20.glClearColor(0.0,0.0,0.0,1.0F);

}

}
 

// ====================广场======================== //

 公共类方{

私人FloatBuffer vertexBuffer;
私人ShortBuffer drawListBuffer;

//此数组中每个顶点的坐标数量
静态最终诠释COORDS_PER_VERTEX = 3;
静浮squareCoords [] = {-0.5f,0.5F,0.0,//左上
                                -0.5f,-0.5f,0.0,//左下
                                 0.5F,-0.5f,0.0,//右下
                                 0.5F,0.5F,0.0}; // 右上

私人短DRAWORDER [] = {0,1,2,0,2,3}; //为了绘制顶点
浮色[] = {0.63671875f,0.76953125f,0.22265625f,1.0F};


私人最终字符串vertexShader code =
        属性vec4 vPosition; +
        无效的主要(){+
        GL_POSITION = vPosition; +
        };

私人最终字符串fragmentShader code =
    precision mediump浮动; +
    统一vec4 vColor; +
    无效的主要(){+
    gl_FragColor = vColor; +
    };

INT mProgram;

静态最终诠释vertexStride = COORDS_PER_VERTEX * 4;
静态最终诠释vertexCount = 4;

市民广场(){
    //初始化为形状坐标顶点字节的缓冲区
    ByteBuffer的BB = ByteBuffer.allocateDirect(squareCoords.length * 4); //(#坐标值* 4%的浮动字节)
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(squareCoords);
    vertexBuffer.position(0);

    //初始化字节的缓冲区的抽奖名单
    ByteBuffer的DLB = ByteBuffer.allocateDirect(drawOrder.length * 2); //(#坐标值的每个短* 2字节)
    dlb.order(ByteOrder.nativeOrder());
    drawListBuffer = dlb.asShortBuffer();
    drawListBuffer.put(DRAWORDER);
    drawListBuffer.position(0);


    INT vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,vertexShader code);
    INT fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShader code);

    mProgram = GLES20.glCreateProgram(); //创建空的OpenGL ES项目
    GLES20.glAttachShader(mProgram,vertexShader); //添加顶点着色器程序
    GLES20.glAttachShader(mProgram,fragmentShader); //添加片段着色器进行编程
    GLES20.glLinkProgram(mProgram); //创建OpenGL ES的可执行程序
}

公共静态INT loadShader(整型,字符串着色器code){

    //创建一个顶点着色器类型(GLES20.GL_VERTEX_SHADER)
    //或片段着色器类型(GLES20.GL_FRAGMENT_SHADER)
    INT着色器= GLES20.glCreateShader(类型);

    //添加源$ C ​​$ C到着色器和编译
    GLES20.glShaderSource(着色,着色器code);
    GLES20.glCompileShader(着色);

    返回着色器;
}

公共无效平局(){
    //添加程序OpenGL ES的环境
    GLES20.glUseProgram(mProgram);

    //得到处理到顶点着色器的vPosition成员
    INT mPositionHandle = GLES20.glGetAttribLocation(mProgramvPosition);

    //启用句柄三角形顶点
    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // prepare三角坐标数据
    GLES20.glVertexAttribPointer(mPositionHandle,COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT,假的,
                                 vertexStride,vertexBuffer);

    //得到处理,以片段着色器的vColor成员
    INT mColorHandle = GLES20.glGetUniformLocation(mProgramvColor);

    //设置颜色绘制三角形
    GLES20.glUniform4fv(mColorHandle,1,颜色,0);

    //绘制三角形
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES,0,vertexCount);

    //禁用顶点数组
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
 

解决方案

该问题可能是这一行:

 广场万=新广场();
 

由于它被调用setRenderer之前初始化。该构造广场调用GLES20方法,这可能是造成问题的原因。尝试调用后实例化setRenderer(渲染);或onSurfaceCreated方法中。

I'm new to OpenGL on Android and I have read heavily documented samples, and I kinda understand it. But before trying to do anything complex, I want to draw a simple 2D white rectangle on a black bacground. Nothing else.

I'm stuck at this error: call to OpenGL ES API with no current context, which seems to be that I'm calling something from the non-OpenGL Thread. The thing is that I'm not sure what is called from the OpenGL Thread. So here's my code

//============== Activity ==================//

public class MainActivity extends Activity {

public static String TAG = MainActivity.class.getSimpleName();

MyGLSurfaceView surface;

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

    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
    );

    surface = new MyGLSurfaceView(this);
    setContentView(surface);
}

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

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

}

//==================== GLSurfaceView ========================//

public class MyGLSurfaceView extends GLSurfaceView {

MyGLSurfaceRenderer renderer;

public MyGLSurfaceView(Context context) {
    super(context);

    setEGLContextClientVersion(2);

    renderer = new MyGLSurfaceRenderer(this);
    setRenderer(renderer);
}

}

//================== Renderer ==========================//

public class MyGLSurfaceRenderer implements GLSurfaceView.Renderer {

Square square = new Square();

public MyGLSurfaceRenderer(MyGLSurfaceView surface) {

}

@Override
public void onDrawFrame(GL10 gl) {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
    square.draw();
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
    // TODO Auto-generated method stub

}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

}

}

//==================== Square ========================//

public class Square {

private FloatBuffer vertexBuffer;
private ShortBuffer drawListBuffer;

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

private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
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;" +
    "}";

int mProgram;

static final int vertexStride = COORDS_PER_VERTEX * 4;
static final int vertexCount = 4;

public Square() {
    // initialize vertex byte buffer for shape coordinates
    ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4); // (# of coordinate values * 4 bytes per float)
    bb.order(ByteOrder.nativeOrder());
    vertexBuffer = bb.asFloatBuffer();
    vertexBuffer.put(squareCoords);
    vertexBuffer.position(0);

    // initialize byte buffer for the draw list
    ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2); // (# of coordinate values * 2 bytes per short)
    dlb.order(ByteOrder.nativeOrder());
    drawListBuffer = dlb.asShortBuffer();
    drawListBuffer.put(drawOrder);
    drawListBuffer.position(0);


    int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
    int fragmentShader = 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
}

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;
}

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

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

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

    // Prepare the triangle coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                                 GLES20.GL_FLOAT, false,
                                 vertexStride, vertexBuffer);

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

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

    // Draw the triangle
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

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

解决方案

The problem may be this line:

Square square = new Square();

Because it gets initialized before the call to "setRenderer". The constructor for Square calls GLES20 methods, which could be causing the problem. Try instantiating it after the call to "setRenderer(render);" or inside the "onSurfaceCreated" method.

这篇关于OpenGL ES 2.0的上下文中的Andr​​oid的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆