進行状況については、最後に編集を参照してください。
OpenGL ES 2.0 を学習しようとしています (Android デバイスで開発する予定です)。
Vertex シェーダーと Fragment シェーダーについて少し混乱しています。それらの目的は理解していますが、カスタム ビルド クラス (「ポイント」など) から形状を構築し、そのサイズと色を設定するか、テクスチャを適用し、オブジェクト クラスのコンストラクターで最初に両方のシェーダーが宣言および定義されていると想定している場合、これは、そのクラスの各インスタンスが独自のシェーダーのペアを持つことを意味しますか?
それが私の最初の質問です。2 つ目は、これが当てはまる場合 (各オブジェクトのシェーダー ペア) ....これでいいのでしょうか? 1 つのシェーダー ペアを使用してそのパラメーターを切り替えることは、パフォーマンスのために良い考えではないと聞いたことがありますが、すべて同じサイズと色 (またはテクスチャ) の 100 個のスプライトがある場合、それらすべてにまったく同じパラメーターを持つシェーダーの異なるペア?
正しい質問をしているといいのですが、私は ES 2.0 を長い間勉強していないので、少し混乱しています。現在、OpenGL についての理解は限られています。
編集
リクエストに応じてコードを追加します。
public class Dot {
int iProgId;
int iPosition;
float size = 10;
FloatBuffer vertexBuf;
float r = 1f;
float g = 1f;
float b = 1f;
float a = 1f;
int iBaseMap;
int texID;
Bitmap imgTexture;
//Constructor
public Dot() {
float[] vertices = {
0,0,0f
};
//Create vertex shader
String strVShader =
"attribute vec4 a_position;\n"+
"void main()\n" +
"{\n" +
"gl_PointSize = " +size+ ";\n" +
"gl_Position = a_position;\n"+
"}";
//Create fragment shader
String strFShader =
"precision mediump float;" +
"void main() " +
"{" +
"gl_FragColor = vec4(0,0,0,1);" +
"}";
iProgId = Utils.LoadProgram(strVShader, strFShader);
iPosition = GLES20.glGetAttribLocation(iProgId, "a_position");
vertexBuf = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexBuf.put(vertices).position(0);
}
私の setTexture メソッド
public void setTexture(GLSurfaceView view, Bitmap imgTexture){
this.imgTexture=imgTexture;
//Create vertex shader
String strVShader =
"attribute vec4 a_position;\n"+
"void main()\n" +
"{\n" +
"gl_PointSize = " +size+ ";\n" +
"gl_Position = a_position;\n"+
"}";
//Fragment shader
String strFShader =
"precision mediump float;" +
"uniform sampler2D u_baseMap;" +
"void main()" +
"{" +
"vec4 color;" +
"color = texture2D(u_baseMap, gl_PointCoord);" +
"gl_FragColor = color;" +
"}";
iProgId = Utils.LoadProgram(strVShader, strFShader);
iBaseMap = GLES20.glGetUniformLocation(iProgId, "u_baseMap");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glUniform1i(iBaseMap, 0);
texID = Utils.LoadTexture(view, imgTexture); //See code below
}
Utils
私のクラスの LoadTexture() メソッド:
public static int LoadTexture(GLSurfaceView view, Bitmap imgTex) {
int textures[] = new int[1];
try {
GLES20.glGenTextures(1, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_LINEAR);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, imgTex, 0);
} catch
}
return textures[0];
}
そして最後に私の描画方法:
public void drawDot(float x, float y){
float[] vertices = {
x,y,0f
};
vertexBuf = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer();
vertexBuf.put(vertices).position(0);
GLES20.glUseProgram(iProgId);
GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 0, vertexBuf);
GLES20.glEnableVertexAttribArray(iPosition);
GLES20.glDrawArrays(GLES20.GL_POINTS, 0, 1);
}
したがって、次のようなものを作成できます。
Dot dot1 = new Dot();
dot1.setSize(40);
setTexture(myBitmap); //(created earlier with BitmapFactory)
drawDot(0,0);
ありがとうございました!
編集 1: これまでの回答に感謝します。さらに調査すると、他にも数人がまったく同じ問題を抱えているようです。問題は、レンダリング ルーチンで glBindTexture を呼び出していないことです。そのため、OpenGL はロードした最後のテクスチャを使用しているだけです。これは理にかなっていると思います。
レンダリング ルーチンに次のコードを追加すると、次のようになります。
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 1);
最初のビットマップを適用して表示します
私が置く場合:
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 2);
2番目のビットマップを適用して表示します
だから、どこかに行きます!しかし、私の質問は、どのオブジェクトがそれを呼び出しているか (レンダリング ルーチン) に基づいて、使用するビットマップをレンダリング メソッドに自動的に認識させるにはどうすればよいかということです。
再度、感謝します