請參閱末尾編輯以獲取進度。僅使用最後綁定紋理的OpenGL ES 2.0 1
我在努力學習的OpenGL ES 2.0的過程中(我會在Android設備上進行開發)
我有點困惑的頂點和片段着色器。我理解他們的目的,但是如果我從一個定製的類(例如'point')構建一個形狀並設置其大小和顏色或應用紋理,並假定這兩個着色器都是在對象類的構造函數中初始聲明和定義的,這是否意味着該類的每個實例都擁有它自己的一對着色器?
這是我的第一個問題。我的第二個是,如果是這種情況(每個對象的着色器對).........這是要走的路嗎?我聽說有一個着色器對和切換它的參數不是一個好主意,因爲性能,但如果我有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
}
LoadTexture()從我Utils
類方法:
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);
}
所以我可以創建東西l ike so:
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);
它將應用第二位圖並顯示它
所以,找個地方!但我現在的問題是,如何讓我的渲染方法根據哪個對象調用它(渲染例程)自動知道要使用哪個位圖?
再次感謝
感謝@Esparver的答案。所以在我的實現中,對象的每個實例是否都有自己的對或着色器?或者他們會分享一對嗎?我無法弄清楚它是如何工作的!我創建了一個對象的2個實例併爲每個對象應用了一個紋理,但是當我渲染它們時,它們都顯示相同的紋理,因此我試圖瞭解它發生了什麼 - 再次感謝您的時間和幫助。 – Zippy 2013-03-05 16:47:40
你能用一些相關的代碼編輯你的問題嗎?看看你的着色器和你如何發送數據(glDrawElements調用或其他) – Esparver 2013-03-05 16:52:12
這聽起來像你沒有創建一個新的紋理對象,並在你使用第二個紋理之前進行綁定。 – jonbonazza 2013-03-05 16:53:12