Android的OpenGL ES 2.0的现场滚动 [英] Android openGL ES 2.0 scene scrolling

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

问题描述

我使用OpenGL ES 2.0的工作的一个简单的游戏为Android。游戏将会以2D,像老supermario,在这里玩家可以移动左右/上下,但没有深度。

等级会比屏幕大,所以显卡将不得不滚动。这里是哪里出了问题来了。我不知道在哪里/何时停止滚动。

为例。让我们说,背景是100x100的纹理大小的方形。比方说,关于屏幕仅存在背景随时可见的1/4。当我然后将屏幕向右,我想它停止滚动时的背景右边缘来在​​屏幕的边缘。

我现在能做的,就是停止滚动时,查看的中心是在后台的边缘。但是,这并不好,因为屏幕的3/4比空白。

我如何计算这个但从中心偏移屏幕的边缘?

注:我不想用正投影

下面是$ C $渲染器的温度。

 包com.huntedseas;

进口javax.microedition.khronos.egl.EGLConfig;
进口javax.microedition.khronos.opengles.GL10;

进口android.opengl.GLES20;
进口android.opengl.GLSurfaceView.Renderer;
进口android.opengl.Matrix;
进口android.util.Log;


公共类GameRenderer实现渲染器{
    保护LevelGenerator发生器;
    保护SquareGL squareGL;

    受保护的静态浮动的AngleX;
    受保护的静态浮动angleY​​;
    受保护的静态浮动angleZ;
    受保护的静态浮viewX = 0;
    受保护的静态浮空想的= 0;
    //私人浮动viewZ = 0;

    私人浮法[] mProjectionMatrix =新的浮动[16]; // Projekcijska matrika
    私人浮法[] mVMatrix =新的浮动[16];
    私人浮法[] mMVPMatrix =新的浮动[16];

    @覆盖
    公共无效onSurfaceCreated(GL10未使用的,EGLConfig conunused){
        GLES20.glClearColor(1.0F,1.0F,1.0F,1.0F);

        GLES20.glDisable(GLES20.GL_CULL_FACE); //后面没有扑杀面临\\要nevem人济treba达JE uklopljeno人NE
        GLES20.glDisable(GLES20.GL_DEPTH_TEST); //没有深入的测试\\  -  ||  - 
        GLES20.glEnable(GLES20.GL_BLEND); //混合
        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA,GLES20.GL_ONE_MINUS_SRC_ALPHA); //插值混合

        发电机=新LevelGenerator();
    }

    @覆盖
    公共无效onDrawFrame(GL10未使用){
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        moveView();
        Matrix.setLookAtM(mVMatrix,0,空想的,viewX,-10,空想的,viewX,0,0.0,1.0F,0.0); // set视图
        Matrix.multiplyMM(mMVPMatrix,0,mProjectionMatrix,0,mVMatrix,0); //计算视图转型

        generator.draw(mMVPMatrix);
    }

    @覆盖
    公共无效onSurfaceChanged(GL10未使用的,诠释的宽度,高度INT){
        GLES20.glViewport(0,0,宽度,高度);

        浮动率=(浮点)宽/高;
        浮到左边= -ratio;
        浮动权=比;
        浮底= -1.0F;
        浮顶= 1.0F;
        浮邻近= 1.0F;
        浮远= 20.0f;
        Log.d(比,比+左+R+右+W:+宽+H:+高);
        Matrix.frustumM(mProjectionMatrix,0,左,右,底,顶,近,远);

    }

    长lastTime = System.currentTimeMillis的();
    公共无效moveView(){
        如果((System.currentTimeMillis的() -  lastTime)> = 33){
            lastTime = System.currentTimeMillis的();
            Log.d(viewX,viewX:+ viewX +空想的:+空想的);
            如果((viewX  - 的AngleX / 10)&其中; Level1.viewXP&安培;及(viewX  - 的AngleX / 10)> Level1.viewXM)viewX  -  =的AngleX / 10;
            如果((空想的 -  angleY​​ / 10)&其中; Level1.viewYP&安培;及(空想的 -  angleY​​ / 10)> Level1.viewYM)空想的 -  = angleY​​ / 10;

            //if(Math.abs(viewX  - 的AngleX / 10)小于10)viewX- =的AngleX / 10;
            //if(Math.abs(viewY  -  angleY​​ / 10)小于10)viewY- = angleY​​ / 10;
            //if(Math.abs(viewZ  - (angleZ-5)/ 10)小于10)viewZ + =(angleZ-5)/ 10;
        }
    }


}
 

解决方案

我通过修改参数,Matrix.frustumM,使他们重新present FOV解决了这个。当你知道从中间向侧面的角度比,你可以计算出抵消tangens功能。

  GLES20.glViewport(0,0,宽度,高度);

    浮动率=(浮点)宽/高;
    浮邻近= 1.0F;
    浮远= 150.0f;
    浮FOV = 80;
    浮顶=(浮动)(Math.tan(FOV * Math.PI / 360.0f)*近);
    浮底= -top;
    浮动左=比率*底部;
    浮动权=比例*顶部;

    offsetY =(浮点)(Math.tan(Math.PI / 180 * FOV / 2)* Math.abs(cameraAway));
    offsetX = offsetY *比例; //因为我们知道X和Y之间的比例

    Matrix.frustumM(mProjectionMatrix,0,左,右,底,顶,近,远);
 

您也可以使用Matrix.perspectivM(),但它只是avaliable的API 14 +。

I'm working on a simple game for android using openGL es 2.0. Game will be in 2D, something like old supermario, where player can move left-right/up-down but no depth.

Level will be larger than screen, so graphics will have to scroll. Here is where the problem comes. I don't know where/when to stop scrolling.

Example. Lets say that background is 100x100 sized square with texture. Lets say that on screen there is only 1/4 of the background visible at any time. When I then move screen to the right, I would like it to stop scrolling when right edge of background comes at the edge of the screen.

The best I can do now, is to stop scrolling when center of "view" is at the edge of background. But this isn't good, because 3/4 of the screen are than blank.

How can I calculate this "offset" from center of view to edge of screen?

Note: I don't want to use orthographic projection.

Here is code of renderer.

package com.huntedseas;

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

import android.opengl.GLES20;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.Matrix;
import android.util.Log;


public class GameRenderer implements Renderer {
    protected LevelGenerator generator;
    protected SquareGL squareGL;

    protected static float angleX;
    protected static float angleY;
    protected static float angleZ;
    protected static float viewX = 0;
    protected static float viewY = 0;
    //private float viewZ = 0;

    private float[] mProjectionMatrix = new float[16]; //Projekcijska matrika
    private float[] mVMatrix = new float[16];
    private float[] mMVPMatrix = new float[16];

    @Override
    public void onSurfaceCreated(GL10 unused, EGLConfig conunused) {
        GLES20.glClearColor(1.0f,1.0f,1.0f,1.0f);

        GLES20.glDisable(GLES20.GL_CULL_FACE); //No culling of back faces  \\ To nevem al je treba da je uklopljeno al ne
        GLES20.glDisable(GLES20.GL_DEPTH_TEST); //No depth testing          \\  --||--
        GLES20.glEnable(GLES20.GL_BLEND); //Blending
        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA,GLES20.GL_ONE_MINUS_SRC_ALPHA); //Interpolated blending

        generator = new LevelGenerator();
    }

    @Override
    public void onDrawFrame(GL10 unused) {
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        moveView();
        Matrix.setLookAtM(mVMatrix, 0, viewY, viewX, -10, viewY, viewX, 0, 0.0f, 1.0f, 0.0f); //set view
        Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mVMatrix, 0); //calculate view transformation

        generator.draw(mMVPMatrix);     
    }

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

        float ratio = (float) width/height;
        float left =-ratio;
        float right = ratio;
        float bottom = -1.0f;
        float top = 1.0f;
        float near = 1.0f;
        float far = 20.0f;      
        Log.d("ratio","ratio: "+left+"  r: "+right+"  w: "+width+"  h: "+height);
        Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);

    }

    long lastTime = System.currentTimeMillis();
    public void moveView(){
        if((System.currentTimeMillis()-lastTime) >= 33){
            lastTime = System.currentTimeMillis();
            Log.d("viewX","viewX: "+viewX + "viewY:"+viewY);
            if( (viewX - angleX/10) < Level1.viewXP && (viewX - angleX/10) > Level1.viewXM) viewX -= angleX/10; 
            if( (viewY - angleY/10) < Level1.viewYP && (viewY - angleY/10) > Level1.viewYM) viewY -= angleY/10;

            //if(Math.abs(viewX - angleX/10) < 10) viewX-=angleX/10;
            //if(Math.abs(viewY - angleY/10) < 10) viewY-=angleY/10;
            //if(Math.abs(viewZ - (angleZ-5)/10) < 10) viewZ+=(angleZ-5)/10;
        }
    }


}

解决方案

I've solved this by modifying parameters for Matrix.frustumM so they represent FOV. Than when you know angle from middle to side, you can calculate offset with tangens function.

 GLES20.glViewport(0, 0, width, height);

    float ratio = (float) width/height;
    float near = 1.0f;
    float far = 150.0f;
    float fov = 80;
    float top = (float) (Math.tan(fov * Math.PI / 360.0f) * near);
    float bottom = -top;
    float left = ratio * bottom;
    float right = ratio * top;

    offsetY = (float) (Math.tan(Math.PI/180*fov/2) * Math.abs(cameraAway));
    offsetX = offsetY * ratio; //because we know ratio between x and y

    Matrix.frustumM(mProjectionMatrix, 0, left, right, bottom, top, near, far);

You can also use Matrix.perspectivM(), but it is only avaliable for api 14+.

这篇关于Android的OpenGL ES 2.0的现场滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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