请参阅末尾编辑以获取进度。仅使用最后绑定纹理的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