glGetUniformLocation returns -1? Texture in shader

You’ve gotta understand that with GL, API is one thing, the mathematical model that “the other guy” wanted to implement, another. The mathematical model is arguably more important.

not in my experience. There isn’t that much maths in graphics programming any more. Sure there’s a lot of frustrated mathematicians in graphics programming, determined to use their skills regardless of whether it’s an appropriate use of company time. I’ve known a few like that…secretly working on papers for their CV’s. Then come the redundancies, and their off like rats from a sinking ship, leaving people like me and omdown to deliver the projects that’ll save the company from bankruptcy.
Knowledge of the API, fast algorithms and tricks to make things asynchronous are the big things. Robustness is another. Delivering to a deadline is above all the most important skill, whether you like it or not.
Most people are just rendering lots of stuff to convince a user he’s in some environment or other. That comes down to efficient traversals, batching, pixel bandwidth consideration, and shader management. It’s surprising how many people I’ve worked with don’t think those things are priority…happy to waste cycles on removing an artefact they can only see when they switch on the debug version of the final shader.

In this instance, there’s a case to be made for both of you. Here’s the general backstory:

  1. Optics-engineer/physicist gets hired to create this simulation
  2. Guy basically has to learn OpenGL from page 1.
  3. From what I can tell, he actually does pretty damn well and gets a pretty good framework together… but documents nothing, comments nothing, and after he leaves, makes it damn near impossible to understand what does what where why how when you’re not an OpenGL programmer.
  4. 14000ish lines of code fall into my lap.

So yes, I agree completely that I need to understand his model. The problem is, with no comments or documentation, it’s been a hair-pulling, eye-straining, tiring experience because I’m having to understand his model FROM the API.

I’m glad I’m starting to get the hang of some of it, but some of this has been unbelievably tiring and frustrating. I get the feeling I’d actually have enjoyed OpenGL if I’d had… you know, started learning it in a more traditional method as opposed to falling into it head first. :slight_smile:

Definitely empathize with you. Been there. Drop into a project with a some “divas” that are too good/arrogant to leave any notes for future reference on what the heck they were thinking. Kills maintenance/deadlines. Prompts stressful (sometimes unpaid) overtime. Costs the company time/money, and frustrates some good people into leaving.

If you guys aren’t even doing requirements/design write-ups and group reviews yet, might I suggest you have some great ammo in your back pocket for making that happen, despite the “divas”.

mmm, “too good/arrogant to leave any notes for future reference”.
While I don’t want to defend ‘divas’, I do need to point out that these things usually operate in chains. omdown is now in a position where he has to write a lot of code in a very short space of time because of the previous guy. I’ll go out on a limb in saying his code won’t win any awards for documentation or robustness before he’s shunted onto another urgent project. I dare say his noble ambition to fully understand all code he introduces into the tree will have to give way to other priorities…and pretty soon he’ll be copy/pasting off the internet like his life depends on it.
As for requirements/design documentation and peer reviews, well…there generally isn’t the time for that in startup businesses. You may respond to that with the usual “you can’t afford not to implement these procedures”, but in reality there’s always a cash flow problem. Salaries have to be paid.
It’s called firefighting, and it ends in one of 3 ways:
1/ big paying long term project comes along which facilitates the introduction of procedures and doing things the right way.
2/ big paying short term project comes along with harsh penalties, which will drive the company to bankruptcy.
3/ continue firefighting with small low paying short term projects, that pay the salary bill, but never give you the leg room to get things right. Code gets reused between projects, but is neglected and hacked for each new requirement. Nobody assumes responsibility for documenting it because there simply isn’t the time.

The company ought to have insisted that the engineer produce some documentation, but they were so in awe of him that they didn’t. So it’s the company you should be angry with, not the optics engineer. I was often in situation like this, even worse, when the code was not working at all and had to do the firefighting (actually reimplementation) and even at a lower salary than the big-mouthed ‘specialist’. Maybe you should start looking around…

In my experience, it’s both. It takes line-engineers recognizing the inefficiencies of what they’re doing (e.g. not documenting) and how much its costing the team (OMG! We can’t fire him, even though he treats people like dirt and stomps all over his mgmt! Nobody else knows how this works! Or OMG! He quit! We are so screwed! Or crap, I had to work 2 weeks to get this working and it would have taken me 4 hours if I’d just had some decent documentation! …or if we memory checked our app occasionally, or…), and feeding those up. And it takes receptive management to adopt short term pain == long term gain strategies (such as documentation). Without both, you end up defaulting to hack-n-slash hero firefighting crap that burns out engineers and occasionally bites your customers in the butt.

But I do see knackered’s points. Definitely sometimes you/mgmt just have to make a call to “hack it” to make a deadline, and you’ll have to go back and fix/refactor/document it later on some other nickel, …or suffer the consequences.

Well the thing is, I don’t think he was a diva that thought he was “too good” by any means… he just had that problem that plagues too many programmers - "I’ll-remember-this-later"itis. Never considers somebody ELSE might have to read it later. hahaha.

Knackered… this is actually a bigpaying, long term project… it’s just that there was only one person working the rendering side of the code, so there was never anyone to notice the lack of documentation, comments, etc. So once he left, the whole thing became OpenGL and the Temple of Code.

Partially agree there as well… I’ve been a loud mouth about needing to put the breaks on and DOCUMENT EVERYTHING before we go anywhere further - but that still doesn’t let him off the hook for not at least going “//this is what’s going on here” once and a while. :wink: Our client suddenly wanted an update on what was going on / why things had been moving slowly (in the span between when previous guy had left and when I picked up the project) and we had literally about three days to put together a bunch of the stuff I had been begging for. lol

Yeah, and this is a problem that happens everywhere. Anytime documentation is left until “after” the code is written, it never gets done. It has to be done before and/or during. That’s one reason why code comments are so important.

…there was only one person working the rendering side of the code, so there was never anyone to notice the lack of documentation, comments, etc. So once he left, the whole thing became OpenGL and the Temple of Code.

Ouch. So you’re victim of the “OMG! He quit! We are so screwed!” problem.

Seems it always takes teams a few of these before they realize they need to start policing design/documentation.

Hm well… I had this working in my sample app, but I can’t seem to get it working in my main (large) app… right now any time I call glUniform1i to try to link the texture to the fragment shader, checking the glErrorString gives me Invalid Operation. I don’t see what I’m doing wrong, I’m doing everything the same way I did it in my standalone sample app…


     m_TextureHandler.m_Target         =  GL_TEXTURE_2D;
     m_TextureHandler.m_InternalFormat =  GL_LUMINANCE16;
     m_TextureHandler.m_Format         =  GL_LUMINANCE;
     m_TextureHandler.m_Height         =  256;
     m_TextureHandler.m_Width          =  256;

     // create a new texture .. always get ID = 4 here
     glGenTextures(1, &m_TextureHandler.m_TextureID);  

     // set the active texture -- 
     // I was using TEXTURE0 + m_TextureID (and then using the textureID
     // again below as the argument to pass to the Uniform1i, but for now
     // to eliminate another variable, just hard coding it now
     glActiveTexture(GL_TEXTURE0 + 4); // + m_TextureHandler.m_TextureID);

     // bind the texture
     glBindTexture(m_TextureHandler.m_Target, m_TextureHandler.m_TextureID);

     // create the data to write to
     float textureData[256][256];    

     // initialize the data with all 1s for debugging purposes
     for ( int i = 0; i < m_TextureHandler.m_Height; i++ ) {
          for ( int j = 0; j < m_TextureHandler.m_Width; j++ ) {
               textureData[i][j] = 1.;
          }
     }

/*   
     // Uncomment this area out to verify the results of what's written to the texture data.     
     
     for ( int i = 0; i < m_TextureHandler.m_Height; i++ ) {
          for ( int j = 0; j < m_Texture.m_Width; j++ ) {
               cout << "i:" << i << "j:" << j << ", " << textureData[i][j] << "
";
          }
     }

*/
     
     // generate the texture
     glTexImage2D( m_TextureHandler.m_Target,
                   0,
                   m_TextureHandler.m_InternalFormat,
                   m_TextureHandler.m_Width,
                   m_TextureHandler.m_Height,
                   0,
                   m_TextureHandler.m_Format,
                   GL_FLOAT,
                   textureData );

     glTexParameteri(m_TextureHandler.m_Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(m_TextureHandler.m_Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     glTexParameteri(m_TextureHandler.m_Target, GL_TEXTURE_WRAP_S, GL_CLAMP);
     glTexParameteri(m_TextureHandler.m_Target, GL_TEXTURE_WRAP_T, GL_CLAMP);


     // get the location of the TextureHandler Uniform in the HB shader
     m_TextureLocation = glGetUniformLocation(m_ShaderProgram, "TextureData");

     // now bind "TextureData" to the ActiveTexture
     glUniform1i(m_TextureLocation, 4 ); //m_TextureHandler.m_TextureID);



Is there some glaringly obvious, idiotic mistake I’m making somewhere? Because this set up works in my little side app. I’ve got an active GL context going, glewInit has been called, GL_TEXTURE_2D is enabled, the shaders have been compiled and linked and the programs are being used, glGetUniformLocation(m_ShaderProgram, “TextureData”); returns 0, I’ve double checked and added a non-used uniform and a used uniform and I get -1 and 1 respectively when I grab them… am I missing something?

EDIT

Err… strange update. If I change it to using GL_TEXTURE_n, n>15, and pass n in for the Uniform1i, it says that GL_TEXTURE_n is an invalid enumerant, and still says that Uniform1i call is an invalid operation, but it works, it shades everything properly…

Where did you call glUseProgram?

UGh. Sorry. Another dumb error. It gets called before, but gets turned off. This app switches between shaders based on what it’s shading… turns them back on later, forgot it was in between. The fact that I wasn’t getting -1 for getUnifornLocation threw me off. Sigh… sometimes I feel like I’m NEVER going to get the hang of OpenGL / GLSL. =/

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.