Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 如何将按钮添加到渲染器?_Android_Opengl Es 2.0 - Fatal编程技术网

Android 如何将按钮添加到渲染器?

Android 如何将按钮添加到渲染器?,android,opengl-es-2.0,Android,Opengl Es 2.0,我在安卓工作室做了一个高度图。它的主要活动如下所示: public class MainActivity extends AppCompatActivity { private GLSurfaceView glSurfaceView; private boolean rendererSet = false; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstan

我在安卓工作室做了一个高度图。它的主要活动如下所示:

public class MainActivity extends AppCompatActivity {
private GLSurfaceView glSurfaceView;
private boolean rendererSet = false;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    glSurfaceView = new GLSurfaceView(this);

    final ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

    final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();

    final boolean supportsEs2 = configurationInfo.reqGlEsVersion >= 0x20000
            || (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1
            && (Build.FINGERPRINT.startsWith("generic")
            || Build.FINGERPRINT.startsWith("unknown")
            || Build.MODEL.contains("google_sdk")
            || Build.MODEL.contains("Emulator")
            || Build.MODEL.contains("Android SDK built for x86")));
    final FirstOpenGLProjectRenderer firstOpenGLProjectRenderer = new FirstOpenGLProjectRenderer(this);
    if(!firstOpenGLProjectRenderer.getError()) {
        if (supportsEs2) {
            glSurfaceView.setEGLContextClientVersion(2);
            glSurfaceView.setRenderer(firstOpenGLProjectRenderer);
            rendererSet = true;
        } else {
            Toast.makeText(this, "this device does not support OpenGL ES 2.0", Toast.LENGTH_LONG).show();
            return;
        }

        setContentView(glSurfaceView);

    }else{
     setContentView(R.layout.error);
    }
}

@Override
protected void onPause(){
    super.onPause();
    if(rendererSet) {glSurfaceView.onPause();}
}

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

    if(rendererSet){
        glSurfaceView.onResume();
    }
}
public static void main(String []args){}
}
我还有一个renderer类,看起来像这样:

public class FirstOpenGLProjectRenderer implements Renderer {

private float min;
private float max;
private float ratio;
private FloatBuffer vertexPositions;
private FloatBuffer vertexColors;

private int alpha = 1000;

private float[] positions;
private float[] colors;

private Context context;
private boolean error;

private ArrayList<Float> nodePositions;

private static final int BYTES_PER_FLOAT = 4;
private int program;
private static final String A_COLOR = "a_Color";
private int aColorLocation;
private static final String A_POSITION = "a_Position";
private int aPositionLocation;
private final int POSITION_COMPONENT_COUNT = 3; //x,y,z
private ArrayList<Float> triangleZList;

public FirstOpenGLProjectRenderer(Context context) {

    this.context = context;
    ArcGridReader arcGridReader = new ArcGridReader(context);
    this.nodePositions = arcGridReader.getNodePositions();
    this.triangleZList = arcGridReader.getTriangleZList();

    error = arcGridReader.getError();
    if(!error) {
        calc();
    }

}

public boolean calc(){
        positions = new float[nodePositions.size()];
        //Todo: färgerna
        colors = new float[triangleZList.size() * 3];

        min = Collections.min(triangleZList) / alpha;
        max = Collections.max(triangleZList) / alpha;
        ratio = (200 / (max - min));

        int i = 0;
        for (Float test : nodePositions) {
            positions[i] = test / alpha;
            i++;
        }
        double amount = (max/3)*alpha;
        i = 0;
        for (Float test : triangleZList) {

            if(test<=0){
                setColors(test,i,0);
                i=i+3;
            }

            if(test>0 && test<=amount){
                setColors(test,i,10);
                i=i+3;
            }
            if(test>amount && test<=(2*amount)){
                setColors(test,i,20);
                i=i+3;
            }
            if(test>(2*amount) && test<=(3*amount)){
                setColors(test,i,30);
                i=i+3;
            }
        }
        vertexPositions = ByteBuffer
                .allocateDirect(positions.length * BYTES_PER_FLOAT)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        vertexPositions.put(positions);

        vertexColors = ByteBuffer
                .allocateDirect(colors.length * BYTES_PER_FLOAT)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer();
        vertexColors.put(colors);

    return  true;

}

@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {

    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    GLES20.glEnable(GLES20.GL_CULL_FACE);
    GLES20.glEnable(GLES20.GL_DEPTH_TEST);

    String vertexShaderSource = TextResourceReader
            .readTextFileFromResource(context, R.raw.vertex_shader);

    String fragmentShaderSource = TextResourceReader
            .readTextFileFromResource(context, R.raw.fragment_shader);

    int vertexShader = ShaderHelper.compileVertexShader(vertexShaderSource);
    int fragmentShader = ShaderHelper.compileFragmentShader(fragmentShaderSource);


    program = ShaderHelper.linkProgram(vertexShader, fragmentShader);

    if (LoggerConfig.ON) {
        ShaderHelper.validateProgram(program);
    }
    glUseProgram(program);

    aColorLocation = glGetAttribLocation(program, A_COLOR);
    aPositionLocation = glGetAttribLocation(program, A_POSITION);
}

@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
    glViewport(0, 0, width, height);

}

@Override
public void onDrawFrame(GL10 glUnused) {
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);

    glUseProgram(program);

    vertexPositions.position(0);
    glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, vertexPositions);
    glEnableVertexAttribArray(aPositionLocation);

    vertexColors.position(0);
    glVertexAttribPointer(aColorLocation, POSITION_COMPONENT_COUNT, GL_FLOAT, false, 0, vertexColors);
    glEnableVertexAttribArray(aColorLocation);

    glDrawArrays(GL_TRIANGLES, 0, positions.length);

}


public void setColors (Float test, int i,int number){

    switch (number){

        case 0:

            colors[i] = 0*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            colors[i] = 0*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            colors[i] = 1*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            break;

        case 10:
            colors[i] = 0*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            colors[i] = 1*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            colors[i] = 0*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            break;

        case 20:

            colors[i] = 1*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            colors[i] = 1*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            colors[i] = 0*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            break;

        case 30:

            colors[i] = 1*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            colors[i] = 0*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            colors[i] = 0*(((test - min) / alpha) * ratio + 20) / 255f;
            i++;
            break;
    }
}

public boolean getError(){
    return error;
}
}
public类FirstOpenGLProjectRenderer实现渲染器{
私人浮动分钟;
私人浮动最大值;
私人股本流动比率;
私人展览;
私有浮动缓冲区顶点颜色;
私人intα=1000;
私人浮动[]职位;
私人浮动[]颜色;
私人语境;
私有布尔错误;
私有ArrayList节点位置;
私有静态最终整数字节/FLOAT=4;
私人int计划;
私有静态最终字符串A_COLOR=“A_COLOR”;
私家旅馆;
私有静态最终字符串A_POSITION=“A_POSITION”;
私人内部位置;
私有最终整数位置分量计数=3;//x,y,z
私人ArrayList三角列表;
public FirstOpenGLProjectRenderer(上下文){
this.context=上下文;
ArcGridReader ArcGridReader=新的ArcGridReader(上下文);
this.nodePositions=arcGridReader.getNodePositions();
this.triangleZList=arcGridReader.getTriangleZList();
error=arcGridReader.getError();
如果(!错误){
计算();
}
}
公共布尔计算(){
positions=新浮点[nodePositions.size()];
//Todo:färgerna
颜色=新的浮动[triangleZList.size()*3];
min=Collections.min(三角形列表)/alpha;
max=Collections.max(三角形列表)/alpha;
比率=(200/(最大-最小));
int i=0;
用于(浮动测试:节点位置){
位置[i]=测试/α;
i++;
}
双倍金额=(最大值/3)*α;
i=0;
用于(浮动测试:三角形列表){

如果(test0&&testamount&&test(2*amount)&&test最简单的方法是为UI(按钮、文本、编辑等)使用单独的层,并将其置于
GLSurfaceView
之上。用xml定义布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <GLSurfaceView
        android:id="@+id/gl_surface_view"
        android:background="#ff0000"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <Button
            android:id="@+id/btn_zoom_in"
            android:text="ZoomIn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

        <Button
            android:id="@+id/btn_zoom_out"
            android:text="ZoomOut"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>

</FrameLayout>
就这些

值得一提的是另一种更复杂的方法:在OpenGL中完全绘制UI,并从您的GL表面截取触摸事件:

class Surface extends GLSurfaceView{

    public Surface(Context context) {
        super(context);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }
}

我找到了更适合我的东西,我只是在mainactivity中添加了以下代码:

       ...

       setContentView(glSurfaceView);

        LinearLayout ll = new LinearLayout(this);

        Button zoomIn = new Button(this);
        zoomIn.setText("zoomIn");

        Button zoomOut = new Button(this);
        zoomOut.setText("zoomOut");

        ll.addView(zoomIn);
        ll.addView(zoomOut);

        this.addContentView(ll,new 
        ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, 
        ViewGroup.LayoutParams.FILL_PARENT));

        ...
其中this.addContentView是其中的关键部分

  • 设计xml布局。是的,按钮、铃铛和哨子。ConstraintLayout就可以了
  • LayoutInflater充气机=getLayoutInflater()
  • getWindow().addContentView(充气器.充气(R.layout.your_xml_布局,null),新建ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_父级,ViewGroup.LayoutParams.MATCH_父级))
  • 将事件添加到按钮等
  • 你完成了!现在你在GLSurfaceView上有了一个设计完美的UI
  •        ...
    
           setContentView(glSurfaceView);
    
            LinearLayout ll = new LinearLayout(this);
    
            Button zoomIn = new Button(this);
            zoomIn.setText("zoomIn");
    
            Button zoomOut = new Button(this);
            zoomOut.setText("zoomOut");
    
            ll.addView(zoomIn);
            ll.addView(zoomOut);
    
            this.addContentView(ll,new 
            ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, 
            ViewGroup.LayoutParams.FILL_PARENT));
    
            ...