android – Opengl开发GPU依赖吗?

前端之家收集整理的这篇文章主要介绍了android – Opengl开发GPU依赖吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我在opengl ES2.0中开发了一个 android应用程序.在这个应用程序中,我曾经通过GL surfaceView中的触摸事件绘制多个线条和圆圈.

由于opengl依赖于GPU,目前它在Google Nexus 7(ULP GeForce)中运行良好.

在三星Galaxy Note 2(MALI 400MP)中,我试图绘制多条线,但它清除了前一条线,并将当前线绘制为新线.

在Sony Xperia Neo V(Adreno 205)中,我试图画一条新线,它会使表面崩溃,如下图所示.

是否可以使其在所有设备上运行,或者我是否需要为单个GPU编写代码

代码

MainActivity.java

//in OnCreate method of my activity,i set the glsurfaceview and renderer

final ActivityManager activityManager =
    ( ActivityManager ) getSystemService( Context.ACTIVITY_SERVICE );
final ConfigurationInfo configurationInfo =
    activityManager.getDeviceConfigurationInfo(  );
final boolean supportsEs2 = ( configurationInfo.reqGlEsVersion >= 0x20000
                  || Build.FINGERPRINT.startsWith( "generic" ) );

if( supportsEs2 ) {
    Log.i( "JO","configurationInfo.reqGlEsVersion:"
           + configurationInfo.reqGlEsVersion + "supportsEs2:"
           + supportsEs2 );
// Request an OpenGL ES 2.0 compatible context.
    myGlsurfaceView.setEGLContextClientVersion( 2 );

    final DisplayMetrics displayMetrics = new DisplayMetrics(  );
    getWindowManager(  ).getDefaultDisplay(  ).getMetrics( displayMetrics );

// Set the renderer to our demo renderer,defined below.
    myRenderer = new MyRenderer( this,myGlsurfaceView );
    myGlsurfaceView.setRenderer( myRenderer,displayMetrics.density );
    myGlsurfaceView.setRenderMode( GLSurfaceView.RENDERMODE_CONTINUOUSLY );

    MyGLSurfaceView.java
//in this im getting the coordinates of my touch on the glSurfaceView to draw the line and //passing those points to the renderer class
        public MyGLsurfaceview( Context context ) {
        super( context );
        Log.i( "JO","MyGLsurfaceview1" );

    }

    public MyGLsurfaceview(
    Context context,AttributeSet attrs )
    {
        super( context,attrs );
        con = context;
        mActivity = new MainActivity(  );
        mActivity.myGlsurfaceView = this;
        Log.i( "JO","MyGLsurfaceview2" );
    }

    public void setRenderer(
    MyRenderer renderer,float density )
    {
        Log.i( "JO","setRenderer" );
        myRenderer = renderer;
        myDensity = density;
        mGestureDetector = new GestureDetector( con,mGestureListener );
        super.setRenderer( renderer );
        setRenderMode( GLSurfaceView.RENDERMODE_CONTINUOUSLY );

    }
    @Override public boolean onTouchEvent( MotionEvent ev ) {

        boolean retVal = mGestureDetector.onTouchEvent( ev );

        if( myline ) {

            switch ( ev.getAction(  ) ) {

            case MotionEvent.ACTION_DOWN:

                isLUp = false;

                if( count == 1 ) {
                    dx = ev.getX(  );
                    dy = ev.getY(  );
                    dx = ( dx / ( getWidth(  ) / 2 ) ) - 1;
                    dy = 1 - ( dy / ( getHeight(  ) / 2 ) );

                    firstX = dx;
                    firstY = dy;
                } else if( count == 2 ) {

                    ux = ev.getX(  );
                    uy = ev.getY(  );
                    ux = ( ux / ( getWidth(  ) / 2 ) ) - 1;
                    uy = 1 - ( uy / ( getHeight(  ) / 2 ) );

                    secondX = ux;
                    secondY = uy;

                    myRenderer.dx = firstX;
                    myRenderer.dy = firstY;
                    myRenderer.ux = secondX;
                    myRenderer.uy = secondY;

                    midX = ( firstX + secondX ) / 2;
                    midY = ( firstY + secondY ) / 2;
                    Log.e( "JO","Line:firstX" + firstX +
                           "firstY" + firstY );
                    lp = new LinePoints( firstX,firstY,secondX,secondY,midX,midY );
                    lineArray.add( lp );

                    myRenderer.isNewClick = false;
                    myRenderer.isEnteredAngle = false;
                    myRenderer.myline = true;
                    myRenderer.mycircle = false;
                    myRenderer.mydashedline = false;
                    myRenderer.eraseCircle = false;
                    myRenderer.eraseLine = false;
                    myRenderer.eraseSelCir = false;
                    myRenderer.angle = angle;
                    myRenderer.length = length;
                    requestRender(  );
                    count = 0;

                }
                count++;

                break;
            case MotionEvent.ACTION_MOVE:

                isLUp = true;

                break;

            case MotionEvent.ACTION_UP:

                if( isLUp ) {

                    ux = ev.getX(  );
                    uy = ev.getY(  );
                    ux = ( ux / ( getWidth(  ) / 2 ) ) - 1;
                    uy = 1 - ( uy / ( getHeight(  ) / 2 ) );
                    Log.i( "JO","line2:" + ux + "," + uy );

                    secondX = ux;
                    secondY = uy;
                    myRenderer.dx = firstX;
                    myRenderer.dy = firstY;
                    myRenderer.ux = secondX;
                    myRenderer.uy = secondY;

                    midX = ( firstX + secondX ) / 2;
                    midY = ( firstY + secondY ) / 2;
                    Log.e( "JO",midY );
                    lineArray.add( lp );

                    myRenderer.isNewClick = false;
                    myRenderer.isEnteredAngle = false;
                    myRenderer.myline = true;
                    myRenderer.mycircle = false;
                    myRenderer.mydashedline = false;
                    myRenderer.mysnaptoedge = false;
                    myRenderer.mysnaptoMiddle = false;
                    myRenderer.eraseCircle = false;
                    myRenderer.eraseLine = false;
                    myRenderer.eraseSelCir = false;
                    count = 1;
                    requestRender(  );
                }

                break;

            }
        }
    }
}

MyRenderer.java

//renderer class to render the line to the glsurfaceview
Lines line;
public MyRenderer(
    MainActivity mainActivity,MyGLsurfaceview myGlsurfaceView )
{
    Log.i( "JO","MyRenderer" );
    this.main = mainActivity;
    myGlsurface = myGlsurfaceView;

}

public void onDrawFrame(
    GL10 gl )
{
    line.draw( dx,dy,ux,uy );
}

@Override public void onSurfaceCreated(
    GL10 gl,EGLConfig config )
{
    Log.i( "JO","onSurfaceCreated" );
// Set the background frame color
    GLES20.glClearColor( 0.0f,0.0f,1.0f );
// Create the GLText
    glText = new GLText( main.getAssets(  ) );

// Load the font from file (set size + padding),creates the texture
// NOTE: after a successful call to this the font is ready for
// rendering!
    glText.load( "Roboto-Regular.ttf",14,2,2 );  // Create Font (Height: 14
// Pixels / X+Y Padding
// 2 Pixels)
// enable texture + alpha blending
    GLES20.glEnable( GLES20.GL_BLEND );
    GLES20.glBlendFunc( GLES20.GL_ONE,GLES20.GL_ONE_MINUS_SRC_ALPHA );
}

@Override public void onSurfaceChanged(
    GL10 gl,int width,int height )
{
// Adjust the viewport based on geometry changes,// such as screen rotation
    GLES20.glViewport( 0,width,height );

    ratio = ( float ) width / height;

    width_surface = width;
    height_surface = height;

/*
* // this projection matrix is applied to object coordinates // in the
* onDrawFrame() method Matrix.frustumM(mProjMatrix,-ratio,ratio,* -1,1,3,7);
*/
// Take into account device orientation
    if( width > height ) {
        Matrix.frustumM( mProjMatrix,-1,10 );
    } else {
        Matrix.frustumM( mProjMatrix,-1 / ratio,1 / ratio,10 );
    }

// Save width and height
    this.width = width; // Save Current Width
    this.height = height;   // Save Current Height

    int useForOrtho = Math.min( width,height );

// TODO: Is this wrong?
    Matrix.orthoM( mVMatrix,-useForOrtho / 2,useForOrtho / 2,0.1f,100f );
}

Line.java

//Line class to draw line

public class Lines
{

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

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

    final FloatBuffer vertexBuffer;
    final int mProgram;
    int mPositionHandle;
    int mColorHandle;

// number of coordinates per vertex in this array
    final int COORDS_PER_VERTEX = 3;
    float lineCoords[] = new float[6];
    final int vertexCount = lineCoords.length / COORDS_PER_VERTEX;
    final int vertexStride = COORDS_PER_VERTEX * 4; // bytes per vertex
// Set color with red,green,blue and alpha (opacity) values
    float lcolor[] = { 1.0f,1.0f,1.0f };

    public Lines(
         )
    {

// initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(
// (number of coordinate values * 4 bytes per float)
                                  lineCoords.
                                  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(  );

// prepare shaders and OpenGL program
        int vertexShader =
            MyRenderer.loadShader( GLES20.GL_VERTEX_SHADER,vertexShaderCode );
        int fragmentShader =
            MyRenderer.loadShader( GLES20.GL_FRAGMENT_SHADER,fragmentShaderCode );

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

    public void draw(
    float dX,float dY,float uX,float uY )
    {

        lineCoords[0] = dX;
        lineCoords[1] = dY;
        lineCoords[2] = 0.0f;
        lineCoords[3] = uX;
        lineCoords[4] = uY;
        lineCoords[5] = 0.0f;
        Log.i( "JO","lineCoords:" + lineCoords[0] + "," + lineCoords[1] +
               "," + lineCoords[3] + "," + lineCoords[4] );

        vertexBuffer.put( lineCoords );
        vertexBuffer.position( 0 );
// Add program to OpenGL 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
        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,lcolor,0 );
        GLES20.glLineWidth( 3 );
// Draw the triangle
        GLES20.glDrawArrays( GLES20.GL_LINES,vertexCount );

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

}

解决方法

好的,这里又一次:^ 1

OpenGL is not a scene graph. OpenGL does not maintain a scene,knows about objects or keeps tracks of geometry. OpenGL is a drawing API. You give it a canvas (in form of a Window or a PBuffer) and order it to draw points,lines or triangles and OpenGL does exactly that. Once a primitive (=point,line,triangle) has been drawn,OpenGL has no recollection about it whatsoever. If something changes,you have to redraw the whole thing.

重绘场景的正确步骤是:

>禁用模板测试,以便以下步骤在整个窗口上运行.
>使用glClear(位)清除帧缓冲区,其中位是位掩码,指定要清除画布的哪些部分.渲染新帧时,您要清除所有内容,因此位= GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
>设置视口,构建适当的投影矩阵
>为场景中的每个对象加载正确的模型视图矩阵,设置制服,选择顶点数组并进行绘图调用.
>通过冲洗管道完成渲染.如果使用单个缓冲窗口glFinish(),如果使用双缓冲窗口调用SwapBuffers.在更高级别框架的情况下,这可以由框架执行.

重要事项在双缓冲窗口上完成绘图后,您不能继续发送绘图操作,因为通过执行缓冲区交换,您绘制的后台缓冲区的内容是未定义的.因此,您必须重新开始绘图,从清除帧缓冲区开始(步骤1和2).

您的代码遗漏的正是这两个步骤.另外我的印象是你正在执行OpenGL绘图调用,直接对输入事件做出反应,可能在输入事件处理程序中.不要这样做!而是使用输入事件添加到要绘制的基元列表(在您的情况下为行),然后发送重绘事件,这使框架调用绘图函数.在绘图功能中迭代该列表以绘制所需的线条.

重绘整个场景在OpenGL中是规范的!

[1](geesh,我已经厌倦了每隔3个左右写一次这个问题……)

原文链接:https://www.f2er.com/android/309527.html

猜你在找的Android相关文章