   Cg - bind sampler to custom texture unit
  Is it possible, in Cg and OpenGL, to do something like this?Cg:uniform sampler2D diffuse;uniform sampler2D specular;---C++/OpenGL:// set a diffuse texture in texunit0// set a specular texture in texunit1cgBindSamplerToTextureUnit( "diffuse", TEXTURE_UNIT_0 );cgBindSamplerToTextureUnit( "specular", TEXTURE_UNIT_1 );Basically, the way my material system works is that I first specify which texture units are active, then I assign emissive/ambient/diffuse/etc. maps to the different texture units (e.g. emissive might use unit0, ambient and diffuse might share unit1, etc.). However, what I need to do is somehow associate Cg samplers with the texture units numbers, rather than associating them with the textures in the units.Is this possible? There are so many weird texture/sampler functions in Cg that I'm not sure what to use.EDIT:As far as I can tell, I need to callcgGLSetTextureParameter( param, gl_tex_id );cgGLEnableTextureParameter( param );But what the texture associated with gl_tex_id is bound to texture units 0 and 1? How does the sampler know which to sample from?In fact, how does multitexturing actually work? Does each texture unit contain a texture ID? Or does each texture object contain a texture unit ID? The first way seems right, but the Cg functions suggest the second way! Or maybe both refer to each other? i.e. each texture unit stores the texture bound to it, and each texture object stores which texture unit it is bound to? But then you wouldn't be able to bind the same texture object to multiple units. Anyway, could someone clarify? Thanks.[Edited by - Gumgo on May 24, 2010 1:54:43 PM]
  I don't know Cg but it should be similar to the OpenGL/GLSL.So in GL, you would need to setup the samplers.locationX=glGetUniformLocation(myShader, "diffuse");locationY=glGetUniformLocation(myShader, "specular");glUseProgram(myShader);  //Bind your shaderglUniform1i(locationX, 0);   //Sampler diffuse will be tex image unit 0glUniform1i(locationY, 1);   //Sampler specular will be tex image unit 1which is what this Cg stuff doescgBindSamplerToTextureUnit( "diffuse", TEXTURE_UNIT_0 );cgBindSamplerToTextureUnit( "specular", TEXTURE_UNIT_1 );Now that your shader is setup, while you run your code, you need to bind the shader, bind the textures, and fire a draw call.Or, bind textures, bind shader, and fire a draw call.glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, X);glActiveTexture(GL_TEXTURE1);glBindTexture(GL_TEXTURE_2D, Y);glUseProgram(myShader);  //Bind your shaderglDraw_That_Thing;   ;  Oh sorry, I was actually making up the cgBindSamplerToTextureUnit, it doesn't actually exist. :) I was just using it as an example for what I'm trying to get working.What does exist iscgGLSetTextureParameter( sampler, gl_texture_id );cgGLEnableTextureParameter( sampler );What I'm doing right now is binding the gl_texture_ids to the texture units I want them in, and then binding the samplers to the gl_texture_ids in those texture units. I have not gotten a chance to test this yet though, so I'm not sure if it works. Also, if gl_texture_id is in multiple texture units, how does the sampler "know" which one to sample from?   ;Quote:Original post by GumgoOh sorry, I was actually making up the cgBindSamplerToTextureUnit, it doesn't actually exist. :) I was just using it as an example for what I'm trying to get working.What does exist iscgGLSetTextureParameter( sampler, gl_texture_id );cgGLEnableTextureParameter( sampler );What I'm doing right now is binding the gl_texture_ids to the texture units I want them in, and then binding the samplers to the gl_texture_ids in those texture units. I have not gotten a chance to test this yet though, so I'm not sure if it works. Also, if gl_texture_id is in multiple texture units, how does the sampler "know" which one to sample from?To be honest, I'm not exactly sure what you are trying to accomplish yet, but if it's making sure the correct texture id is bound to the correct texture unit, then if you just use:cgGLSetTextureParameter( param, gl_tex_id );cgGLEnableTextureParameter( param );cg will properly figure out which texture unit it needs, without you needing to use the gl functions to do so. If this is not what you are asking, I'll try to think about your question a little more.   ;  So, OpenGL has TEXUNIT0..7 (it might have more, but I'm only using 0-7).Textures can be bound using glActiveTexture( unit ), glBindTexture( target gl_id ).So what I want to do is something like this (for example):textures (gl_ids): diffuse_ambient_map, emissive_map, specular_mapsamplers (sampler2D): ambientSampler, diffuseSampler, emissiveSampler, specularSamplerTEXUNIT0: diffuse_ambient_mapTEXUNIT1: emissive_mapTEXUNIT2: specular_mapTEXUNIT3: <none>TEXUNIT4: <none>TEXUNIT5: <none>TEXUNIT6: <none>TEXUNIT7: <none>ambientSampler -> TEXUNIT0diffuseSampler -> TEXUNIT0emissiveSampler -> TEXUNIT1specularSampler -> TEXUNIT2So, I know what you can do in the Cg source code is something likesampler2D diffuseSampler : TEXUNIT0which binds the sampler to TEXUNIT0. But what I want to do is to be able to dynamically bind a sampler to whichever TEXUNIT I want, instead of statically binding it in the source code. I'm able to dynamically bind it to to the texture ID I want, but that is different.Does that make sense?   ;  In the shader file, if you just do:uniform sampler2D diffuseSampler;It will decide which texture unit the texture is using dynamically ( I assume based on order), and if you call:cgGLSetTextureParameter( param, gl_tex_id );cgGLEnableTextureParameter( param );(NOTICE: not calling glActiveTexture or glBindTexture)the cg runtime will correctly identify which texture unit that parameter is using in that shader.It sounds like that will do what you want assuming I understand you correctly.   ;  Wait... so I don't even need to use OpenGL's texture functions, or OpenGL's texture units? In all the tutorials I see, both the OpenGL and Cg texture functions are used.   ;Quote:Original post by GumgoWait... so I don't even need to use OpenGL's texture functions, or OpenGL's texture units? In all the tutorials I see, both the OpenGL and Cg texture functions are used.I haven't been using them, and everything seems fine. I just use glBindTexture on the texture if I'm editing something of it application side. Other than that, I just use those two functions of cg to bind the texture for use with the shader.   ;  Hm, interesting. Does anyone know where I could get a bit more info about how Cg manages textures? I'd like to know how this works so I will be able to make texture binding more efficient. With OpenGL, it is clear that textures are bound when glBindTexture is called, but I'm not so sure with the Cg functions (e.g. what if 2 samplers are bound to the same texture?).   ;Quote:Original post by GumgoHm, interesting. Does anyone know where I could get a bit more info about how Cg manages textures? I'd like to know how this works so I will be able to make texture binding more efficient. With OpenGL, it is clear that textures are bound when glBindTexture is called, but I'm not so sure with the Cg functions (e.g. what if 2 samplers are bound to the same texture?).Samplers are not bound to a texture. A texture is bound to a sampler.Yes, you can bind a texture to 2 samplers. All that a sampler knows is what texture to sample from, what filtering to use, anisotropy?, mipmapping?, the base level. You can even bind the same texture to all 16 or 32 texture samplers if you want.   