我的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;
} ...}