私は、このビュー空間の背景を表すオブジェクトを含む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;
} ...}