1
\$\begingroup\$

First off, this is a Uni assignment, but the lecturer is stumped too.

With the shader active, I get nothing, just black. With the shader disabled (fixed function pipeline) I get a rainbow pattern which is not the texture. Uncommenting the code block labeled with the comment //this does the texturing correctly but can't be used by the shader does as the comment states. My friends and I believe that I'm not loading the texture into OpenGL correctly, what am I doing wrong?

Here is the fragment shader:

const float     lightWeighting = 0.75;
const float     textureWeighting = 0.25;


const float     PI = 3.14;
const float     lightIntensity = 1.0;
const float     constFudge = 0.025;
const float     linearFudge = 0.025;
const float     quadraticFudge = 0.05;

float rend  = 250.0;
float rstart = 50.0;


uniform float       Intensity;
uniform sampler2D   grabTexture;
//varying   sampler2D   HeatValues

varying vec3        Normal;
varying vec3        Vertex;
varying vec2        texCoord;

void main(void)
{   
  vec3 pigPos = Vertex;
  vec3 normPigPos = normalize(pigPos);


  vec3 lightPos = vec3(gl_LightSource[0].position.xyz);

  vec3 normLightPos = normalize(lightPos);




  float effectiveIntesity;


  vec3 normNormal = normalize(vec3(Normal.xyz));

  vec3 t = vec3(pigPos - lightPos);

  float distToLight = length(t);

  float d = dot(normNormal.xyz, normLightPos.xyz);
  if(d > 0.0)//facing the light
  {
    float falloff;

    if( distToLight < rstart )
      falloff = 1.0;
    else
    if( distToLight > rend )
      falloff = 0.0;
      else
      {
      falloff = rend-distToLight / rend-rstart;
      }

    effectiveIntesity = d*lightIntensity * falloff;




    effectiveIntesity = d*lightIntensity * (1.0/(constFudge + (linearFudge*distToLight) +(quadraticFudge*distToLight*distToLight)));

  }
  else
  {
    effectiveIntesity = 0.0;
  }

  //TODO: change the colour of the pixel
  vec4 lightingColour = vec4(vec4( 1.0 ) * effectiveIntesity); //TODO: improve

  //gl_FragColor = lightingColour;

  //texturing stuff
  //http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/
  vec4 textureColour = vec4(texture2D(grabTexture, texCoord.xy)); // TODO: why is this blank?

  vec4 col = vec4(textureColour.rgb, 1.0);
  col.r *= 1.0;
  col.g *= 1.0;

  gl_FragColor = (col);

  //gl_FragColor = (lightingColour * lightWeighting) + (textureColour.rgb * textureWeighting);

  //simple check to make sure that shader compiles
  vec3 lP = vec3(abs(gl_LightSource[0].position.x/100), abs(gl_LightSource[0].position.y/100), abs(gl_LightSource[0].position.z/100));
  vec4 r = vec4( lP.x, lP.y, lP.z, 1.0 );
  gl_FragColor = r;

  gl_FragColor = (lightingColour * lightWeighting) + (r * textureWeighting);
}

Here is what I do to load textures:

GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
float color[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, color);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, x, y, 0, GL_RGB, GL_UNSIGNED_BYTE, rawLoadedTexture);
glBindTexture(GL_TEXTURE_2D, tex); 

Using the texture:

glEnable(GL_TEXTURE_2D);

//this does the texturing correctly but can't be used by the shader
/*glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, rawLoadedTexture);*/

glActiveTexture(pigObj.id_texture); //the shader can use this texture
glBindTexture(GL_TEXTURE_2D, pigObj.id_texture);

cShader *pList = graphics.ShaderInfo.getList();
glUseProgram( pList[1].program()); //shader on: no pig // fixed, was vertex shader being empty, replaced it with intensity.vert
                  //shader off: ambient light only (tiny amount of diffuse or an illusion?)
extern NA_MathsLib na_maths;
float intensity = (float) na_maths.dice(100);

glUniform1i(pList[1].get_grabLoc(), pigObj.id_texture);
glUniform1f(pList[1].intensity(), intensity);
//glUniform1f(pList[1].get_heatValues(), heatValuesPsudoTexture);

//glutSolidSphere(2, 15, 2);
pigObj.render();

glDisable(GL_TEXTURE_2D);
glUseProgram(0); //disable pig heatlamp shader
\$\endgroup\$
  • 2
    \$\begingroup\$ please ask one question per question you submit to the site. \$\endgroup\$ – Almo Jul 15 '17 at 14:37
  • 1
    \$\begingroup\$ Also, please include the code in your question rather than linking to it. The link will eventually be stale and future users won't understand the question. \$\endgroup\$ – user1118321 Jul 15 '17 at 15:27
  • \$\begingroup\$ Fixed both issues \$\endgroup\$ – Lupus590 Jul 15 '17 at 16:16
  • \$\begingroup\$ fixed the above \$\endgroup\$ – Lupus590 Jul 15 '17 at 19:08
  • \$\begingroup\$ You shouldn't add any kind of "Solved" marks to the title. The site already has a way to indicate that a question has an accepted answer. \$\endgroup\$ – HolyBlackCat Jul 15 '17 at 21:13
1
\$\begingroup\$

Your problem is here:

glActiveTexture(pigObj.id_texture); //the shader can use this texture

glActiveTexture() takes a value of GL_TEXTURE*, not the ID of your texture. It's the texture unit in which your texture is going to be bound (or is already bound). So for texture unit 0, you'd do:

glActiveTexture(GL_TEXTURE0);

You then need to also pass the texture unit index as the uniform for the sampler, rather than your texture ID.

This is by far one of the most confusing aspects of texturing in OpenGL! And because all OpenGL constants are #defines instead of proper named types, it's really hard to have the compiler catch this type of error. See the docs for glActiveTexture() for more info.

\$\endgroup\$
  • \$\begingroup\$ Thank you, I also had to uncomment the block (erroniously) labelled //this does the texturing correctly but can't be used by the shader. \$\endgroup\$ – Lupus590 Jul 15 '17 at 19:43
  • \$\begingroup\$ Can you explain, when you say, "it's the texture unit in which your texture is going to be bound", do you mean literally the GLSL texture unit retrieved from the fragment shader? If so, are you implying that GL_TEXTURE0 somehow is aware of the first texture unit specified in shader program, and that GL_TEXTURE1 will somehow be the second? \$\endgroup\$ – netpoetica Oct 24 at 2:10
  • \$\begingroup\$ There are several things at play here. When you call glBindTexture(), OpenGL uses the active texture unit as the one that you'll bind to. It uses the target of that texture unit that you passed in to glBindTexture() In your shader you'll have some uniform, usually, like uniform sampler2D myTexture. In your CPU code, you need to set the shader's myTexture uniform by calling glUniform1i(myTextureLocation, 0) for example. The 0 is GL_TEXTURE0, the 1st texture unit. \$\endgroup\$ – user1118321 Oct 24 at 2:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.