• Advertisement
Sign in to follow this  

OpenGL ES max active textures in OpenGL ES 2.0

Recommended Posts

I've been making pretty good use of texture atlases in my current game, but as I find myself forced to use another texture (to enable generating tex coords for point sprites), I'm wondering if there may be a better way than currently batching by texture, and calling glBind before each batch.

Instead is it more efficient to pre-bind a whole set of textures to all the available active texture slots, then simply only read from the ones I'm interested in in the fragment shaders (or call glUniform to change the active texture used by the frag shader). Is there any performance penalty to have a load of textures bound, but not being used?

Is this a practical way to work on GLES 2.0, and are there any typical figures for how many active texture slots should be available on mobiles? I'm getting the impression the minimum is 8.

This may make a difference as I'm having to do several render passes on some frames.

Share this post


Link to post
Share on other sites
Advertisement

So, the maximum number of active textures is not the same for every device, you'll need to check it using GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:

https://www.khronos.org/registry/OpenGL-Refpages/es2.0/xhtml/glActiveTexture.xml

As for binding all those texture, do you really need to bind all of them if your not using all of them? As far as i know this *could* be a hit to performance, the drivers may move the resources to a more accessible location for the shader when they are bound. I don't think this is the right approach.

I think your original method of tiling the textures is a better approach if you want to bind less often.

Another way you can do it is to dynamically create these huge textures. basically each sprite you have can be their own resource, then you copy those resources into the larger texture that you will bind and use for that frame. you can keep them in that texture until you need more space for new sprites to be rendered in the frame, then just overwrite "tiles" in that texture that you are no longer using.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By Cat's machete
      I need to pass 24 vec3, to a shader
      However glUniform3fv requires an array of GLfloat,
      Since my vec3 structure looks like:
      struct vec3{float x; float y; float z;};
      Can i just pass that safely, to float parray[24 * 3] using memcpy?
      Dont bother about GLfloat and float sizes i just gave pseudocode i just need to know if sent array will have first vertex at position 0 second one will be in pos 3, thrid one in 6 and so on, cause im not sure when even float and GLfloat match the sizes i could get some extra bytes anywhere,
       
      And another question is how then i define an uniform in shader?
      uniform vec3 box[24];. ?
       
      Cheers
    • By EddieK
      Hi I am having this problem where I am drawing 4000 squares on screen, using VBO's and IBO's but the framerate on my Huawei P9 is only 24 FPS. Considering it has 8-core CPU and a pretty powerful GPU, I don't think it is not capable of drawing 4000 textured squares at 60FPS.
      I checked the DMMS and found out that most of the time spent was by the put() method of the FloatBuffer, but the strange thing is that if I'm drawing these squares outside of the view frustum, the FPS increases. And I'm not using frustum culling. 
      If you have any ideas what could be causing this, please share them with me. Thank you in advance.
    • By EddieK
      Hi, so I am trying to implement packed VBO's with indexing on OpenGL but I have run across problems. It worked fine when I had separate buffers for vertex positions, colors and texture coordinates. But when I tried to put everything into a single packed buffer, it completely glitched out. Here's the code which I am using:
      this.vertexData.position(0); this.indexData.position(0); int stride = (3 + 4 + 2) * 4; GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]); GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexData.capacity()*4, vertexData, GLES20.GL_STATIC_DRAW); ShaderAttributes attributes = graphicsSystem.getShader().getAttributes(); GLES20.glEnableVertexAttribArray(positionAttrID); GLES20.glVertexAttribPointer(positionAttrID, dimensions, GLES20.GL_FLOAT, false, stride, 0); GLES20.glEnableVertexAttribArray(colorAttrID); GLES20.glVertexAttribPointer(colorAttrID, 4, GLES20.GL_FLOAT, false, stride, dimensions * 4); GLES20.glEnableVertexAttribArray(texCoordAttrID); GLES20.glVertexAttribPointer(texCoordAttrID, 2, GLES20.GL_FLOAT, false, stride, (dimensions + 4) * 4); GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, buffers[3]); GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexData.capacity()*2, indexData, GLES20.GL_STATIC_DRAW); GLES20.glDrawElements(mode, count, GLES20.GL_UNSIGNED_SHORT, 0); The data in vertex buffer is ordered like this:
      Vertex X, vertex Y, vertex Z, Color r, color g, color b, color a, Tex coord x, tex coord z and so on... (And I am pretty certain that the buffer I'm using is in this order)
      This is the version of the code which worked fine:
      this.vertexData.position(0); this.vertexColorData.position(0); this.vertexTexCoordData.position(0); this.indexData.position(0); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[0]); GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexPositionData.capacity()*4, vertexPositionData, GLES20.GL_STATIC_DRAW); ShaderAttributes attributes = graphicsSystem.getShader().getAttributes(); GLES20.glEnableVertexAttribArray(positionAttrID); GLES20.glVertexAttribPointer(positionAttrID, 4, GLES20.GL_FLOAT, false, 0, 0); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[1]); GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexColorData.capacity()*4, vertexColorData, GLES20.GL_STATIC_DRAW); GLES20.glEnableVertexAttribArray(colorAttrID); GLES20.glVertexAttribPointer(colorAttrID, 4, GLES20.GL_FLOAT, false, 0, 0); GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, buffers[2]); GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER, vertexTexCoordData.capacity()*4, vertexTexCoordData, GLES20.GL_STATIC_DRAW); GLES20.glEnableVertexAttribArray(textCoordAttrID); GLES20.glVertexAttribPointer(textCoordAttrID, 4, GLES20.GL_FLOAT, false, 0, 0); */ GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, buffers[3]); GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexData.capacity()*2, indexData, GLES20.GL_STATIC_DRAW); GLES20.glDrawElements(mode, count, GLES20.GL_UNSIGNED_SHORT, 0); This is the output of the non working code:

      From this picture I can see that some of the vertex positions are good, but for some reason every renderable object from the game has a at least one vertex position of value 0
      Thank in advance,
      Ed
    • By AhmedSaleh
      I'm trying to write a leather material shader. I have a normal map, bump map (grayscaled), specular map, diffuse map, cube maps.
      I have done the following

       
      #version 100 precision highp int; precision highp float; uniform sampler2D diffuseColorMap; uniform sampler2D ambientOcclusionMap; uniform sampler2D normalMap; uniform sampler2D specularMap; uniform sampler2D bumpMap; uniform samplerCube envMap; varying vec2 texCoord[2]; varying vec3 viewWorld; uniform float reflectionFactor; uniform float diffuseFactor; uniform float opacity; varying vec3 eyeVector; varying mat3 world2Tangent; varying vec3 lightVec; varying vec3 halfVec; varying vec3 eyeVec; void main() {   vec3 normalTangent = 2.0 * texture2D (normalMap, texCoord[0]).rgb - 1.0;        vec4 x_forw = texture2D( bumpMap, texCoord[0]+vec2(1.0/2048.0, 0.0));     vec4 x_back = texture2D( bumpMap, texCoord[0]-vec2(1.0/2048.0, 0.0));     vec4 y_forw = texture2D( bumpMap, texCoord[0]+vec2(0.0, 1.0/2048.0));     vec4 y_back = texture2D( bumpMap, texCoord[0]-vec2(0.0, 1.0/2048.0));     vec3 tangX = vec3(1.0, 0.0, 3.0*(x_forw.x-x_back.x));     vec3 tangY = vec3(0.0, 1.0, 3.0*(y_forw.x-y_back.x));     vec3 heightNormal = normalize(cross(tangX, tangY));     heightNormal = heightNormal*0.5 + 0.5;            float bumpAngle = max(0.0, dot(vec3(0.0,0.0,1.0),heightNormal ));       vec3 normalWorld = normalize(world2Tangent *heightNormal);      vec3 refDir = viewWorld - 2.0 * dot(viewWorld,normalWorld) * normalWorld;     // compute diffuse lighting                 vec4 diffuseMaterial = texture2D (diffuseColorMap, texCoord[0]);         vec4 diffuseLight  =  vec4(1.0,1.0,1.0,1.0);                  // In doom3, specular value comes from a texture           vec4 specularMaterial =  texture2D (specularMap, texCoord[0])  ;         vec4 specularLight = vec4(1.0,1.0,1.0,1.0);         float shininess = pow (max (dot (halfVec,heightNormal), 0.0), 2.0)  ;         vec4 reflection = textureCube(envMap, refDir);         //gl_FragColor=diffuseMaterial * diffuseLight * lamberFactor ;         //gl_FragColor+=specularMaterial * specularLight * shininess ;         //gl_FragColor+= reflection*0.3;     gl_FragColor = diffuseMaterial*bumpAngle ;  }  
      My question is how would I use the bump map (Grayscale) to the result of the reflection or what's wrong in my shader ?
       
       
       

    • By lonewolff
      Hi Guys,
      I have been struggling for a number of hours trying to make a directional (per fragment) lighting shader. 
      I have been following this tutorial in the 'per fragment' section of the page - http://www.learnopengles.com/tag/per-vertex-lighting/ along with tutorials from other sites.
      This is what I have at this point.
      // Vertex shader varying vec3 v_Normal; varying vec4 v_Colour; varying vec3 v_LightPos; uniform vec3 u_LightPos; uniform mat4 worldMatrix; uniform mat4 viewMatrix; uniform mat4 projectionMatrix; void main() { vec4 object_space_pos = vec4(in_Position, 1.0); gl_Position = worldMatrix * vec4(in_Position, 1.0); gl_Position = viewMatrix * gl_Position; // WV gl_Position = projectionMatrix * gl_Position; mat4 WV = worldMatrix * viewMatrix; v_Position = vec3(WV * object_space_pos); v_Normal = vec3(WV * vec4(in_Normal, 0.0)); v_Colour = in_Colour; v_LightPos = u_LightPos; } And 
      // Fragment varying vec3 v_Position; varying vec3 v_Normal; varying vec4 v_Colour; varying vec3 v_LightPos; void main() { float dist = length(v_LightPos - v_Position); vec3 lightVector = normalize(v_LightPos - v_Position); float diffuse_light = max(dot(v_Normal, lightVector), 0.1); diffuse_light = diffuse_light * (1.0 / (1.0 + (0.25 * dist * dist))); gl_FragColor = v_Colour * diffuse_light; } If I change the last line of the fragment shader to 'gl_FragColor = v_Colour;' the model (a white sphere) will render to the screen in solid white, as expected.
      But if I leave the shader as is above, the object is invisible.
      I am suspecting that it is something to do with this line in the vertex shader, but am at a loss as to what is wrong.
      v_Position = vec3(WV * object_space_pos); If I comment the above line out, I get some sort of shading going on which looks like it is trying to light the subject (with the normals calculating etc.)
      Any help would be hugely appreciated.
      Thanks in advance
  • Advertisement