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