2016-10-18 34 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.获得这个高度

相关问题