Android GLES 2绘制线条闪烁和奇怪的效果

Android GLES 2绘制线条闪烁和奇怪的效果,第1张

概述我试图在 Android中使用gles 2绘制一些3d线.但它导致了一些奇怪的效果.旋转场景/相机时会发生闪烁.但不仅如此,还有一些线在2d(有时点)中随机绘制.这是截图: 虽然此图像完全没有问题(使用不同的摄像机角度): 我也尝试使用GLES 1来绘制这些线并且它工作(没有闪烁或随机线).也许它与着色器代码有关?顶点着色器取自android gles示例,非常简单. 更新: 经过多次尝试,我发现 我试图在 Android中使用gles 2绘制一些3d线.但它导致了一些奇怪的效果.旋转场景/相机时会发生闪烁.但不仅如此,还有一些线在2d(有时点)中随机绘制.这是截图:

虽然此图像完全没有问题(使用不同的摄像机角度):

我也尝试使用GLES 1来绘制这些线并且它工作(没有闪烁或随机线).也许它与着色器代码有关?顶点着色器取自androID gles示例,非常简单.

更新:
经过多次尝试,我发现这只发生在相机偏航(y轴旋转)超过90度时.在0-90偏航的范围内,线条正常显示.
我究竟做错了什么?
我正在使用androID v4.4.2在galaxy Tab S上运行该程序.

以下是用于重现错误图像的完整代码:

主要活动:

package com.mycompany.BUG_test;import androID.opengl.GLSurfaceVIEw;import androID.support.v7.app.ActionBaractivity;import androID.os.Bundle;public class OpenGLES20Activity extends ActionBaractivity {    private GLSurfaceVIEw mGLVIEw = null;    @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if ( mGLVIEw == null ) {            mGLVIEw = new MyGLSurfaceVIEw(this);        }        setContentVIEw(mGLVIEw);    }}

表面视图:

package com.mycompany.BUG_test;import androID.content.Context;import androID.opengl.GLSurfaceVIEw;import androID.vIEw.MotionEvent;class MyGLSurfaceVIEw extends GLSurfaceVIEw {    private final Myglrenderer mRenderer;    public MyGLSurfaceVIEw(Context context) {        super(context);        setEGLContextClIEntVersion(2);        mRenderer = new Myglrenderer();        setRenderer(mRenderer);    }    private final float touch_SCALE_FACTOR = 360.0f;    private float mPrevIoUsX;    private float mPrevIoUsY;    @OverrIDe    public boolean ontouchEvent(MotionEvent e) {        float x = e.getX();        float y = e.getY();        int action_type = e.getAction();        if ( action_type ==  MotionEvent.ACTION_MOVE ) {            float dx = x - mPrevIoUsX;            float dy = y - mPrevIoUsY;            final float div_mag = 10;            float min_dx = dx;            if ( min_dx > (getRootVIEw().getWIDth()/div_mag) ) {min_dx = (getRootVIEw().getWIDth()/div_mag);}            if ( min_dx < -(getRootVIEw().getWIDth()/div_mag) ) {min_dx = -(getRootVIEw().getWIDth()/div_mag);}            float min_dy = dy;            if ( min_dy > (getRootVIEw().getHeight()/div_mag) ) {min_dy = (getRootVIEw().getHeight()/div_mag);}            if ( min_dy < -(getRootVIEw().getHeight()/div_mag) ) {min_dy = -(getRootVIEw().getHeight()/div_mag);}            float new_yaw = (  mRenderer.cam_yaw - (min_dx * touch_SCALE_FACTOR / getRootVIEw().getWIDth())  ) % 360;            float new_pitch = mRenderer.cam_pitch + (min_dy * touch_SCALE_FACTOR / getRootVIEw().getHeight());            if ( new_pitch > 89 ) {                new_pitch = 89;            }            if ( new_pitch < -89 ) {                new_pitch = -89;            }            synchronized (mRenderer.CAM_LOCK) {                mRenderer.cam_yaw = new_yaw;                mRenderer.cam_pitch = new_pitch;            }            System.out.println("Yaw=" + new_yaw + "   Pitch=" + new_pitch);        }        mPrevIoUsX = x;        mPrevIoUsY = y;        return true;    }}

最重要的部分,GL渲染器:

package com.mycompany.BUG_test;import androID.opengl.GLES20;import androID.opengl.GLSurfaceVIEw;import androID.opengl.Matrix;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.floatBuffer;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;public class Myglrenderer implements GLSurfaceVIEw.Renderer {    private final String vertexshadercode =            "uniform mat4 uMVPMatrix;" +            "attribute vec4 vposition;" +            "voID main() {" +            "   gl_position = uMVPMatrix * vposition;" +            "}";    private final String fragmentshadercode =            "precision mediump float;" +            "uniform vec4 vcolor;" +            "voID main() {" +            "   gl_Fragcolor = vcolor;" +            "}";    private int mProgram;    private int mMVPMatrixHandle;    private int mpositionHandle;    private int mcolorHandle;    private final float[] mProjectionMatrix = new float[16];    private final float[] mVIEwMatrix = new float[16];    float vIEwaspect;    float fovy = 45;    float fovx = 45;    final Object CAM_LOCK = new Object();    float cam_pos_x = 0;    float cam_pos_y = 0;    float cam_pos_z = 0;    float fcs_pos_x = 0;    float fcs_pos_y = 0;    float fcs_pos_z = 0;    //Try Yaw=246.22672   Pitch=21.992342 with cam_focus_range = 175 to get visible error.    float cam_pitch = 21.992342f;    float cam_yaw = 246.22672f;    float cam_focus_range = 175;    final float line_gap = 100;    final float line_length = 6000;    private final int COORDS_PER_VERTEX = 3;    private final int vertexStrIDe = COORDS_PER_VERTEX * 4; // 4 bytes per vertex    private floatBuffer vertexBuffer;    private int vertexCount = 0;    public Myglrenderer() {        float[] GMrklines = new float[(int)( (line_length / line_gap) + 1 ) * 2 * 2 * COORDS_PER_VERTEX ];        int __P = 0;        for (int ln=0; ln<( (line_length / line_gap) + 1 ); ln++) {            GMrklines[__P++] = (float)(line_length /2);                             //x            GMrklines[__P++] = 0;                                                   //y            GMrklines[__P++] = (float)(line_gap *ln - line_length /2);              //z            vertexCount++;            GMrklines[__P++] = (float)(-line_length /2);                            //x            GMrklines[__P++] = 0;                                                   //y            GMrklines[__P++] = (float)(line_gap *ln - line_length /2);              //z            vertexCount++;            GMrklines[__P++] = (float)(line_gap *ln - line_length /2);              //x            GMrklines[__P++] = 0;                                                   //y            GMrklines[__P++] = (float)(line_length /2);                             //z            vertexCount++;            GMrklines[__P++] = (float)(line_gap *ln - line_length /2);              //x            GMrklines[__P++] = 0;                                                   //y            GMrklines[__P++] = (float)(-line_length /2);                            //z            vertexCount++;        }        System.out.println("Vertex count=" + vertexCount);        {            ByteBuffer bb = ByteBuffer.allocateDirect(GMrklines.length * 4);            bb.order(ByteOrder.nativeOrder());            vertexBuffer = bb.asfloatBuffer();            vertexBuffer.put(GMrklines);            vertexBuffer.position(0);        }    }    @OverrIDe    public voID onSurfaceCreated(GL10 unused,EGLConfig config) {        int vertexShader = Myglrenderer.loadShader(GLES20.GL_VERTEX_SHADER,vertexshadercode);        int fragmentShader = Myglrenderer.loadShader(GLES20.GL_FRAGMENT_SHADER,fragmentshadercode);        mProgram = GLES20.glCreateProgram();        GLES20.glAttachShader(mProgram,vertexShader);        GLES20.glAttachShader(mProgram,fragmentShader);        GLES20.gllinkProgram(mProgram);        GLES20.gluseProgram(mProgram);        mMVPMatrixHandle = GLES20.glGetUniformlocation(mProgram,"uMVPMatrix");        mpositionHandle = GLES20.glGetAttribLocation(mProgram,"vposition");        mcolorHandle = GLES20.glGetUniformlocation(mProgram,"vcolor");        GLES20.gluniform4fv(mcolorHandle,1,new float[]{0.3f,0.3f,1},0);        GLES20.glClearcolor(0.0f,0.0f,1.0f);        GLES20.glEnable( GLES20.GL_DEPTH_TEST );        GLES20.glDepthFunc( GLES20.GL_LEQUAL );        GLES20.gllinewidth(4);    }    @OverrIDe    public voID onDrawFrame(GL10 unused) {        float _cam_pos_x;        float _cam_pos_y;        float _cam_pos_z;        float _fcs_pos_x;        float _fcs_pos_y;        float _fcs_pos_z;        float _cam_pitch;        float _cam_yaw;        synchronized (CAM_LOCK) {            _cam_pos_x = cam_pos_x;            _cam_pos_y = cam_pos_y;            _cam_pos_z = cam_pos_z;            _fcs_pos_x = fcs_pos_x;            _fcs_pos_y = fcs_pos_y;            _fcs_pos_z = fcs_pos_z;            _cam_pitch = cam_pitch;            _cam_yaw = cam_yaw;        }        GLES20.glClear(GLES20.GL_color_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);        _fcs_pos_x = 0;        _fcs_pos_y = 0;        _fcs_pos_z = 0;        _cam_pos_y = (float) ( _fcs_pos_y + (cam_focus_range * Math.sin( Math.toradians(_cam_pitch) )));        double cam_to_focus_horz = cam_focus_range * Math.cos( Math.toradians(_cam_pitch) );        _cam_pos_x = (float) ( _fcs_pos_x + (cam_to_focus_horz * Math.cos( Math.toradians(_cam_yaw) )));        _cam_pos_z = (float) ( _fcs_pos_z + (cam_to_focus_horz * Math.sin( Math.toradians(_cam_yaw) )));        Matrix.setLookAtM(mVIEwMatrix,_cam_pos_x,_cam_pos_y,_cam_pos_z,_fcs_pos_x,_fcs_pos_y,_fcs_pos_z,0);        {            float[] mMVPMatrix = new float[16];            Matrix.multiplyMM(mMVPMatrix,mProjectionMatrix,mVIEwMatrix,0);            GLES20.gluniformMatrix4fv(mMVPMatrixHandle,false,mMVPMatrix,0);            GLES20.glEnabLevertexAttribarray(mpositionHandle);            GLES20.glVertexAttribPointer(mpositionHandle,COORDS_PER_VERTEX,GLES20.GL_float,vertexStrIDe,vertexBuffer);            GLES20.glDrawArrays(GLES20.GL_lines,vertexCount);            GLES20.gldisabLevertexAttribarray(mpositionHandle);        }    }    @OverrIDe    public voID onSurfaceChanged(GL10 unused,int wIDth,int height) {        if (height <= 0) { // avoID a divIDe by zero error!            height = 1;        }        vIEwaspect = (float) wIDth / (float) height;        fovx = fovy * vIEwaspect;        GLES20.glVIEwport(0,wIDth,height);        glu_perspective(mProjectionMatrix,fovy,vIEwaspect,1.0f,8000.0f);    }    public static int loadShader(int type,String shadercode) {        int shader = GLES20.glCreateShader(type);        GLES20.glShaderSource(shader,shadercode);        GLES20.glCompileShader(shader);        int[] _param = new int[4];        GLES20.glGetShaderiv(shader,GLES20.GL_COMPILE_STATUS,_param,0);        System.out.println("Shader no : " + shader);        System.out.println("Compile status = " + _param[0] + "   (GL_TRUE=" + GLES20.GL_TRUE + ")");        System.out.println("ERR : " + GLES20.glGetShaderInfolog(shader));        return shader;    }    voID glu_perspective(float[] RetMtx,int offset,float fovY,float aspect,float zNear,float zFar)    {        float fW,fH;        fH = (float) (Math.tan(fovY / 360 * Math.PI) * zNear);        fW = fH * aspect;        Matrix.frustumM(RetMtx,offset,-fW,fW,-fH,fH,zNear,zFar );    }}
解决方法 我遇到了同样的问题,特别是三星设备(我有3个显示相同的问题).
事实证明,使用GL_liNE_STRIP或GL_lines绘制线条会导致您在屏幕截图中显示的人工制品和闪烁.但是,只有当线路穿过摄像机平面时,并且只有当线路的第一个坐标位于摄像机平面后面且第二个坐标位于摄像机平面前方时.当它反过来时 – 没问题.

在我看来,这根本没有意义,因此似乎是一个驱动程序问题 – 代码中没有错误.

作为一种解决方法,我让顶点着色器检测到这个星座,然后翻转顶点.通过检查矩阵的z-缩放分量[2] [2]的符号来完成检测.在我的例子中,顶点是{0,1}和{0,-1} – 因此可以通过否定顶点值来轻松完成翻转.

// Vertex shader snippetcposition = vposition;voMatrix = vIEwMatrix * objMatrix;if ( voMatrix [2][2] < 0.0 ) cposition = -vposition;

我希望这会有所帮助(即使答案很晚).

总结

以上是内存溢出为你收集整理的Android GLES 2绘制线条闪烁和奇怪的效果全部内容,希望文章能够帮你解决Android GLES 2绘制线条闪烁和奇怪的效果所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1125432.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-30
下一篇2022-05-30

发表评论

登录后才能评论

评论列表(0条)

    保存