2016-10-18 3 views
0

私は、このビュー空間の背景を表すオブジェクトを含むAndroidアプリケーションにOpenGL ES 2.0 Surfaceを持っています。このオブジェクト全体の高さは、画面の下の部分を含めて、ピクセルまたはdpでどのように判断できるかを調べたいと思います。オブジェクト自体は、作成したスプライトクラスのインスタンスで、コンストラクタ内のビューパラメータを取ります。ピクセルでOpenGL ESオブジェクトの高さを見つける

最終的に、この高さのデータが必要なので、OpenGLスプライトオブジェクト全体(オフスクリーン部分を含む)と完全に同じ高さのボタンをパラレルレイアウトで作成できます。

私が試したもの:

  • スプライトが使用するテクスチャ画像の高さを使用する:これはやや明白な理由のために動作しません。画像は2048pxの高さですが、これはスプライトオブジェクトの高さではありません。これは、OpenGLビュー内に配置されています。単位は異なります(ワールド空間とアイスペースなど)
  • スプライトがインスタンス化された四角形:ユニットの不一致を回避する方法がわからないため、これは機能しません。 RectF(-3.0、-6.926641、3.0、41.07336)、ここで、-6.9 & 41は、スプライトのトップとボトムをOpenGLビューで表します。私のボタンを〜48 dpまたはpxの高さにすると、もちろん私のデバイス画面に表示されるスプライトの高さと一致しません。これは、ユニットが不一致であるため、ボタンは密度に依存しないピクセルを使用し、スプライト境界は他の単位を使用するためです。

私が求める高さの値はどのようにして見つけることができますか?私のボタンのレイアウトパラメータで簡単に1:1のマッピングができるようにするには、dpでこの値を取得することをお勧めしますが、OpenGLパイプラインからこの値をpxで取得してからdpに手動で変換しなければならないという気持ちがあります。

以下のコードは、私が無関係な論理の行を1000匹すべてあなたに溺れさせたくないためにたくさん残っています。私があなたの理解に役立つ何かを残したら、私に知らせてください。 )

OpenGLのレンダラ パブリッククラスOpenGL_GLRendererはGLSurfaceView.Renderer {

private int catNum = 0; 
private OpenGL_FloatAnimator scroller; 
private float offset = 0.0f; 
private int frameHeight, frameWidth; //height and width of the screen. Used for ortho view configuration 
private float orthoTop, orthoBottom; 

private final Context mActivityContext; 
//texture objects 

private OpenGL_TextureData catBoardTexture; 
private OpenGL_SpriteClass catBoard; //sprite objects for background shape 


/** 
* Store the model matrix. This matrix is used to move models from object space (where each model can be thought 
* of being located at the center of the universe) to world space. 
*/ 
private float[] mModelMatrix = new float[16]; 

/** 
* Store the view matrix. This can be thought of as our camera. This matrix transforms world space to eye space; 
* it positions things relative to our eye. 
*/ 
private float[] mViewMatrix = new float[16]; 

/** Store the projection matrix. This is used to project the scene onto a 2D viewport. */ 
private float[] mProjectionMatrix = new float[16]; 

/** Allocate storage for the final combined matrix. This will be passed into the shader program. */ 
private float[] mMVPMatrix = new float[16]; 

/** This will be used to pass in the transformation matrix. */ 
private int mMVPMatrixHandle; 

/** This will be used to pass in the modelview matrix. */ 
private int mMVMatrixHandle; 

/** This will be used to pass in model position information. */ 
private int mPositionHandle; 

/** This will be used to pass in model color information. */ 
private int mColorHandle; 

/** This will be used to pass in model normal information. */ 
private int mNormalHandle; 

/** This will be used to pass in the texture. */ 
private int mTextureUniformHandle; 

/** This will be used to pass in model texture coordinate information. */ 
private int mTextureCoordinateHandle; 


/** This is a handle to our per-vertex cube shading program. */ 
private int catBoardProgramHandle; 

/** 
* Initialize the model data. 
*/ 
public OpenGL_GLRenderer(final Context context) 
{ 
    mActivityContext = context; 
    scroller = new OpenGL_FloatAnimator();//screen scroll animation object 
} 

protected string getVertexShader(int resourceID) { 
    return OpenGL_RawResourceReader.readTextFileFromRawResource(mActivityContext, resourceID); 
} 

protected string getFragmentShader(int resourceID) { 
    return OpenGL_RawResourceReader.readTextFileFromRawResource(mActivityContext, resourceID); 
} 

@Override 
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) { 
    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Set the background clear color to black. 
    GLES20.glEnable(GLES20.GL_BLEND);    //Enable blending 
    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

    // Enable depth testing 
    GLES20.glEnable(GLES20.GL_DEPTH_TEST); 

    Matrix.setIdentityM(mViewMatrix, 0); 

    //*************Shader Setup**************************** 
    //set handles to catboard shader programs 
    final string vertexShader = getVertexShader(R.raw.vertex_shader); 
    final string fragmentShader = getFragmentShader(R.raw.fragment_shader); 

    //set handles to string shader programs 
    final string stringVertexShader = getVertexShader(R.raw.string_vertex_shader); 
    final string stringFragmentShader = getVertexShader(R.raw.string_fragment_shader); 

    //compile catboard shader programs 
    final int vertexShaderHandle = OpenGL_ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, vertexShader); 
    final int fragmentShaderHandle = OpenGL_ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, fragmentShader); 

    //compile string shader programs 
    final int stringVertexShaderHandle = OpenGL_ShaderHelper.compileShader(GLES20.GL_VERTEX_SHADER, stringVertexShader); 
    final int stringFragmentShaderHandle = OpenGL_ShaderHelper.compileShader(GLES20.GL_FRAGMENT_SHADER, stringFragmentShader); 

    //create and link compiled shader programs to catboard and string program handle variables 
    catBoardProgramHandle = OpenGL_ShaderHelper.createAndLinkProgram(vertexShaderHandle, fragmentShaderHandle, 
      new string[]{"a_Position", "a_Color", "a_Normal", "a_TexCoordinate"}); 

    // Load images into Texture objects 
    initializeTexture(cat); 
    stringTexture = new OpenGL_TextureData(mActivityContext, R.drawable.texture_brass_string); 
} 

//sets up orthographic projection matrix 
public void setupOrtho(int width, int height){ 
    // Create a new perspective projection matrix. The height will stay the same 
    // while the width will vary as per aspect ratio. 
    final float ratio = (float) width/height; 
    final float near = -20.0f; 
    final float far = 20.0f; 
    final float screenWidth = 6.0f; 
    final float left = -screenWidth/2.0f; 
    final float right = -left; 
    final float bottom = screenWidth/(2.0f*ratio); 
    final float top = -bottom; 
    orthoTop = top; 
    orthoBottom = bottom; 
    Matrix.orthoM(mProjectionMatrix, 0, left, right, bottom + scroller.getCurrentValue(), top+scroller.getCurrentValue(), near, far); 
} 

@Override 
public void onSurfaceChanged(GL10 glUnused, int width, int height) 
{ 
    frameHeight = height; 
    frameWidth = width; 
    GLES20.glViewport(0, 0, width, height);   //Set the OpenGL viewport to the same size as the surface. 
    // Create a new perspective projection matrix. The height will stay the same 
    // while the width will vary as per aspect ratio. 
    setupOrtho(width, height); 

    //Configure rectangles for sprites 
    float heightBound = 6.0f*catBoardTexture.imageHeight/catBoardTexture.imageWidth; //6*h*w = (width of ortho projec. * aspect ratio) 
    RectF catBoardBounds = new RectF(-3.0f, orthoTop, 3.0f, heightBound + orthoTop); 

    //Configure Sprites! 
    //scale,fit,repeat vertically, fill 
    catBoard = new OpenGL_SpriteClass(catBoardTexture.textureID, catBoardTexture.imageWidth, catBoardTexture.imageHeight, catBoardBounds,0); 
} 

}

OpenGLを実装します( - 1.0 1.0 +へ)SpriteClass

public class OpenGL_SpriteClass { 
FloatBuffer positionBuffer; 
FloatBuffer textureBuffer; 
RectF _frame; 
int _textureID; 
//SizeF _textureSize; 
Float textureWidth, textureHeight; 

int mode; // TODO: use enumeration 

boolean valid; 

//public OpenGL_SpriteClass(int textureID, SizeF textureSize, RectF frame) { 
public OpenGL_SpriteClass(int textureID, float txWidth, float txHeight, RectF frame, int modeNum) { 
    setTextureID(textureID); 
    setTextureSize(txWidth, txHeight); 
    setFrame(frame); 
    setMode(modeNum); 
} 

public void bindTexture() { 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, _textureID); 
} 

public void setMode (int modeNum){ 
    valid = false; 
    mode = modeNum; 
    bindTexture(); 
    if (modeNum == 2){ 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); 
    } 
    else{ 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 
    } 
} 

public void setFrame(RectF frame) { 
    // TODO: check if _frame is different from frame and invalidate 
    valid = false; 
    _frame = frame; 
} 

public void setTextureID(int textureID) { 
    valid = false; 
    _textureID = textureID; 
} 

/* public void setTextureSize(SizeF size) { 
    // TODO: check if _textureSize is different from size and invalidate 
    valid = false; 
    _textureSize = size; 
}*/ 
public void setTextureSize(float textWidth, float textHeight) { 
    // TODO: check if _textureSize is different from size and invalidate 
    valid = false; 
    textureWidth = textWidth; 
    textureHeight = textHeight; 
} 

public FloatBuffer getPositionBuffer() { 
    if(valid == false) { 
     generateBuffers(); 
    } 
    return positionBuffer; 
} 

public FloatBuffer getTextureBuffer() { 
    if(valid == false) { 
     generateBuffers(); 
    } 
    return textureBuffer; 
} ...} 

答えて

0

のOpenGL ES 2.0は、スクリーン空間を使用してスプライト見つけ寸法がなく画素空間寸法を使用して描画します。

画面の高さをポイント頂点シェーダの均一として渡し、その値を使用してgl_PointSizeを計算します。

は、ピクセル単位で画面の高さがonSurfaceChangedに簡単ですへのアクセスはできますが、OnSurfaceCreatedで同じことを行う、次のintを使用otのしたい場合:

context.getResources().getDisplayMetrics().heightPixels 

this blog.で、この高さを取得する方法を掲示するためのReinierに感謝

関連する問題