Jump to content

  • Log In with Google      Sign In   
  • Create Account


Handle unknown number of texture in a generic context


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 cifa   Members   -  Reputation: 203

Like
0Likes
Like

Posted 29 May 2014 - 07:25 PM

Ok I'm sorry for the terrible title, but I'm up for suggestion for a better one :) 

 

I am trying to write a small framework for a project I have to do soon. I never did nothing more than "one cpp file" OpenGL stuff up to now, so I was trying to come up with a decent class structure as required to do what I have to do. 

What is related to the following question is pretty basic: 

 

- Mesh class that has 

      - ShaderProgram class (with a tables to link attributes/uniforms IDs and more user-friendly names) instance that is "used" when rendering the mesh.

      - Various attributes (VBO etc.)

      - A render function.

 

I had the plan to add a textures vector in Mesh class to relate all the textures that may be useful (e.g. normal map, occlusion, diffuse etc.) to the mesh they belong to (I have no re-use of texture for different models).

The big problem is that for the application I had to do at the end, there's no certainty on how many texture should I use for the Mesh, I could potentially have just diffuse and normal maps or I can have a dozen of texture maps needed for various parameters.  That'd be fine if all the ShaderProgram will use all those textures, but that's not the case, I may need the same Mesh to be drawn with a fairly complex fragment shader or just drawing it's alpha matte.  

How can I handle such situation? There's any way I can achieve such degree generality? Also I'm a tad confused, so I'm afraid this question came up like a mess, I'm sorry about that and I'm extremely happy to clarify anything unclear. 

 

Thank you very much



Sponsor:

#2 LorenzoGatti   Crossbones+   -  Reputation: 2586

Like
0Likes
Like

Posted 30 May 2014 - 02:37 AM

You are confusing assets, which include all possible texture images and shader programs that could be used with a mesh, with actual OpenGL entities that are used for rendering (shader objects, and the texture objects they use). Your Mesh class sits in the middle between these two worlds, and it should handle creating OpenGL textures from images, shaders from text, etc. as sub-tasks of rendering itself in a certain way. All assets for all cases need to be associated with hte mesh, while in actual rendering you only need specific draw calls, specific shaders and only the textures they use.

Asset textures are your own read-only objects, OpenGL textures are integer IDs (presumably wrapped by entirely different classes). Even if they have a 1:1 correspondence in theory, the two kinds of texture have independent lifecycles (on disk/in memory; nonexistent/uninitialized/ready) and their only point of contact is calling glTexSubImage2D etc. when a Mesh needs to be rendered with that texture and it isn't already available from previous frames.


Produci, consuma, crepa

#3 haegarr   Crossbones+   -  Reputation: 3897

Like
0Likes
Like

Posted 30 May 2014 - 03:07 AM


The big problem is that for the application I had to do at the end, there's no certainty on how many texture should I use for the Mesh, I could potentially have just diffuse and normal maps or I can have a dozen of texture maps needed for various parameters.  That'd be fine if all the ShaderProgram will use all those textures, but that's not the case, I may need the same Mesh to be drawn with a fairly complex fragment shader or just drawing it's alpha matte.  
How can I handle such situation? There's any way I can achieve such degree generality? ...

If the rendering pipeline supports several steps, e.g. the geometry pass and the lighting pass for a deferred renderer, or various display modes for objects in an editor, or whatever, then one needs a couple of related resources for each step. A list of resources compiled for each render call can be used to manage the state set-up of the render call. This usually includes the mesh, textures, shaders, and model belonging uniforms set-up.

 

If you want make things a bit more flexible, shader objects itself may declare what kind of textures they need. If the textures then are stored with a semantic, they can be picked from the model by the rendering sub-system itself.



#4 L. Spiro   Crossbones+   -  Reputation: 12788

Like
2Likes
Like

Posted 30 May 2014 - 04:07 AM

The big problem is that for the application I had to do at the end, there's no certainty on how many texture should I use for the Mesh, I could potentially have just diffuse and normal maps or I can have a dozen of texture maps needed for various parameters.  That'd be fine if all the ShaderProgram will use all those textures, but that's not the case, I may need the same Mesh to be drawn with a fairly complex fragment shader or just drawing it's alpha matte.

#1: Enumerate the types of textures you can have. Diffuse, normal maps, specular maps, etc. There is a finite amount of textures and usages of them, and at the end of the day your shader needs to know what to do with the textures it’s passed.

#2: For any given type of render, you must already have a way to determine which textures are in use for that render. Without this, you would have bigger problems than what you have now.

#3: After determining what textures you need to pass to the shader, create a shader key with that information (and in more advanced systems it can contain which type of lighting you want to use, shadows on or off, etc.) and pass that to a kind of shader manager.

#4: The shader manager uses the key to see if that shader already has been generated and compiled or not. If not, it generates it and compiles it. If so, it returns the already-generated shader.

#0: Make shaders “generatable”. There are 2 common ways to go about this.
-> #A: Stitching. Parts of the shader are in different files and using your custom system based on the flags related to which textures you need, which light equation you need, etc., you can stitch together a final shader for that specific combination of modifications.
-> #B: Permutation. It’s the same shader file, but using macros and #ifdef’s you can remove are add parts based on macros sent to the compiler unit.

At work we use #A but I personally use #B.
#A has advantages most seen in gigantic companies that produce AAA games, whereas #B is more manageable by individuals such as you and me, so for now I would recommend #B.



As I mentioned, the model has a way to know which textures to use and as such it generates a shader key.
The flags set in the shader key translate to macros that are passed to the model’s shader file and it is recompiled using #B for each unique shader key. Existing shader keys, again, are hash-mapped and quickly realized to be existing, resulting in minimal overhead even if done every frame. But you don’t need to do a hash look-up every frame because you can also easily see if the last render used the same shader key and if so immediately use the same shader that you used last time without even going to the shader manager (or whatever you have).


L. Spiro

Edited by L. Spiro, 30 May 2014 - 04:08 AM.

It is amazing how often people try to be unique, and yet they are always trying to make others be like them. - L. Spiro 2011
I spent most of my life learning the courage it takes to go out and get what I want. Now that I have it, I am not sure exactly what it is that I want. - L. Spiro 2013
I went to my local Subway once to find some guy yelling at the staff. When someone finally came to take my order and asked, “May I help you?”, I replied, “Yeah, I’ll have one asshole to go.”
L. Spiro Engine: http://lspiroengine.com
L. Spiro Engine Forums: http://lspiroengine.com/forums




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS