2016-10-18 56 views
0

我的Android應用程序中有一個OpenGL ES 2.0 Surface,其中包含表示此視圖空間中背景的對象。我想知道如何確定整個對象的高度,包括屏幕下面的部分,像素或dp。該對象本身是我製作的一個精靈類的一個實例,它在構造函數中使用視圖參數。以像素爲單位查找OpenGL ES對象的高度

最終,我想要這個高度數據,這樣我就可以在一個平行佈局中創建一個與整個OpenGL精靈對象(包括屏幕外部分)完全相同高度的按鈕。

我已經試過:

  • 使用精靈使用的紋理圖像的高度:這並不適用於有些顯而易見的原因工作。圖像的高度是2048px,但這不是它在openGL視圖內放置的精靈對象的高度,單位看起來也不一樣(世界空間vs眼睛空間等)
  • 使用高度矩形精靈實例化:這不起作用,因爲我不知道如何解決單位不匹配。我向我的精靈構造函數提供的rect對象具有以下參數:RectF(-3.0,-6.926641,3.0,41.07336),其中-6.9 & 41表示我的OpenGL視圖中精靈的頂部和底部。如果我將按鈕設爲〜48 dp或px高,它當然會與我的設備屏幕上顯示的精靈高度不匹配。這又是因爲單位不匹配,按鈕使用密度獨立像素,而精靈邊界使用其他單位。

我怎樣才能找到我尋求的身高值?最好在dp中獲得這個值,以便與我的按鈕的佈局參數進行簡單的1:1映射,但是我感覺我必須從px中的OpenGL管道獲取該值,然後手動轉換爲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 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的定位使用屏幕空間精靈( - 1.0〜+ 1.0)的尺寸,但使用像素的空間尺寸繪製它們。

將屏幕高度作爲統一傳遞給點頂點着色器,並使用該值計算gl_PointSize

訪問像素的屏幕高度爲onSurfaceChanged簡單,但如果你想加時賽做相同的OnSurfaceCreated,請使用以下int

context.getResources().getDisplayMetrics().heightPixels 

感謝Reinier張貼的方式this blog.獲得這個高度

相關問題