特定の状況では、ユーザーが画像をズームインしているときに、最も短いエッジが画面全体を占めるまでテクスチャを拡張したい場合があります (標準のギャラリーで見られるように)。ただし、OpenGL シェーダーへの入力は ImageView からのマトリックスであるため、特定の変換を配置するだけでなく、さまざまな空間の補正計算を行う必要があります。
編集:
頂点シェーダー コードは単純化されており、次のようになります。
private final String vertexShader_ =
"attribute vec4 a_position;\n" +
"attribute vec4 a_texCoord;\n" +
"varying vec2 v_texCoord;\n" +
"void main() {\n" +
" gl_Position = a_position;\n" +
" v_texCoord = a_texCoord.xy;\n" +
"}\n";
ここで、a_position は以下の verticesData_ を参照します。画面にロードするとき、画像の位置は、ディスプレイの幅と占有する画面の部分からの計算に基づいて正確になります。
さらに、次のフラグメント シェーダー コードがあります。
private final String fragmentShader_ =
"precision mediump float;\n" +
"varying vec2 v_texCoord;\n" +
"uniform sampler2D texture;\n" +
"uniform mat3 transform;\n" +
"void main() {\n" +
" vec2 uv = (transform * vec3(v_texCoord, 1.0)).xy;\n" +
" gl_FragColor = texture2D( texture, uv );\n" +
"}\n";
ここで、mat3 変換の入力は、ImageView からの入力です。基本的に、OpenGLSurfaceView の下に ImageView があります。これははるかに低い解像度の画像であり、ユーザーがスワイプすると、SurfaceView が非表示になり、ユーザーが SurfaceView にいたのと同じ位置で ImageView がその下に表示されます。
ただし、後でこのテクスチャを拡張したい場合、予期しない結果になることに気付きます。
前後にパンすると、画面が移動すると予想される場所に移動します。したがって、マトリックスからの x 座標と y 座標の変換は問題ありません。ただし、ズームインすると、画像が破れます。テクスチャの境界が画面のサイズを超えて大きくなった場合にのみ、ティアリングが発生します。以下に見られるように、高さは成長するときに余分なピクセルを導入していませんが、幅は進行するにつれて引き裂かれています.
適切な行列を渡すために、ImageView から OpenGL SurfaceView への値が反転され、転置されました。これは、適切な変換のためにスペースが必要だったためです。倍率は、アクティビティがリッスンしているリスナーに渡されます。
@Override
public void onTranslation(float imageScaleF, float[] matrixTranslationF)
{
currentScaleForImage_ = imageScaleF;
//If we are currently using the entire screen, then there is not need anymore to resize the texture itself.
if(surfaceViewWidth_ * imageScaleF > displayViewWidth_ && surfaceViewHeight_ * imageScaleF > displayViewHeight_)
{
}
else //Expand the size of the texture to be displayed on the screen.
{
maximumScaleForImage_ = imageScaleF;
photoViewRenderer_.updateTextureSize(imageScaleF);
photoSurfaceView_.requestRender();
}
matrixTranslationF = updateTranslationBasedOnTextureSize(matrixTranslationF);
photoViewRenderer_.updateTranslationOfTexture(matrixTranslationF);
photoSurfaceView_.requestRender();
}
しかし、上記の次のコードでは、スクロールする画像の部分が常に短くなり、翻訳を更新するためにそこの行のコメントを外してスケールに基づいて修正しようとすると、涙が発生します。そのため、この時点で、以下のユーザーの入力により、私はより良い位置にいるように見えますが、私はまだ一歩離れており、この機能の範囲内にあると思います. 以下の更新されたコードは、ImageView の行列と OpenGL テクスチャ/座標との間の適切な変換を提供するために必要な修正を行いました。
private float[] updateTranslationBasedOnTextureSize(float[] matrixTranslationsF)
{
if(scaleDirection_ == ScaleDirection.WIDTH)
{
matrixTranslationsF[0] = matrixTranslationsF[0] * maximumScaleForImage_;
}
else if(scaleDirection_ == ScaleDirection.HEIGHT)
{
matrixTranslationsF[4] = matrixTranslationsF[4] * maximumScaleForImage_;
}
return matrixTranslationsF;
}
以下に示すように、最初の繰り返しで写真に裂け目が生じていました。または、2 つのスペース間の変換が不適切なため、写真が切り取られていました。
幅は維持されているように見えるので、標準の範囲外の値で何かが起こる可能性があることを示唆していますが、何を試したらよいかわかりません。