1

I'm calling glMaterialfv() before glDrawArrays() and then I set everything back to default values but it doesn't seem to have any effect on my material. I know that glMaterial() should be called between glBegin() and glEnd() so how do I do it without calling those functions? Here's my rendering function:

 glPushMatrix(); {
    glScalef(scale.x, scale.y, scale.z);
    glTranslatef(translate.x, translate.y, translate.z);
    glRotatef(rot_angle, rotation.x, rotation.y, rotation.z);

    glEnableClientState(GL_VERTEX_ARRAY);
    //glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    //glColorPointer(4, GL_FLOAT, 0, colors.data());
    glVertexPointer(3, GL_FLOAT, 0, verts.data());
    glNormalPointer(GL_FLOAT, 0, norms.data());
    glTexCoordPointer(2, GL_FLOAT, 0, texcoords.data());

    glMaterialfv(GL_FRONT, GL_AMBIENT, ambient.data());         // set ambient to what is defined in scene
    glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse.data());         // set diffuse to what is defined in scene
    glMaterialfv(GL_FRONT, GL_SPECULAR, specular.data());       // set specular to what is defined in scene
    glMaterialfv(GL_FRONT, GL_EMISSION, emission.data());       // set emission to what is defined in scene
    glMaterialfv(GL_FRONT, GL_SHININESS, shininess.data());     // set shininess to what is defined in scene

    glColor4f(R, G, B, A);
    glBindTexture(GL_TEXTURE_2D, *texture);
    glDrawArrays(primitive, 0, verts.size() / 3);
    glBindTexture(GL_TEXTURE_2D, NULL);
    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

    glMaterialfv(GL_FRONT, GL_AMBIENT, ambient_def);        // set ambient to default values
    glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse_def);        // set diffuse to default values
    glMaterialfv(GL_FRONT, GL_SPECULAR, specular_def);      // set specular to default values
    glMaterialfv(GL_FRONT, GL_EMISSION, emission_def);      // set emission to default values
    glMaterialfv(GL_FRONT, GL_SHININESS, shininess_def);    // set shininess to default value

    glDisableClientState(GL_VERTEX_ARRAY);
    //glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
} glPopMatrix();
matzar
  • 287
  • 2
  • 19
  • 1
    First, you seem to mostly be using deprecated functionality here. I highly recommend looking into learning OpenGL 4, using shaders with uniforms to accomplish the desired effects. To answer your question, I think you might be missing a definition of a light source (see glLight()). Alternatively, you can also try to implement a shader (which is also better with regards to what I mentioned previously about using OpenGL 4). In that case you have full control over what the final colour looks like, and avoid shenanigans related to how the default pipeline works. – Bartvbl Nov 30 '16 at 13:19
  • 2
    Since glBegin()/glEnd() represent a draw call, you should not use the glMaterial() functions within such a block. As a matter of fact, glBegin()/glEnd() are so hopelessly deprecated nowadays that they should never, ever be used in newly written programs. – Bartvbl Nov 30 '16 at 13:20
  • Yeah, I've heard about it but for now I tried to do it the old way to see how it looks like. I have my light defined. It looks something like this: // Light 1 setLightAmbient(0.2, 0.2, 0.2, 0.2, Light_Ambient_1); setLightDiffuse(0.6, 0.6, 0.6, 1, Light_Diffuse_1); // Light colour setLightPosition(0, 4, 0, 1, Light_Position_1); setLightSpecular(0.5, 0.5, 0.5, 1.0, Light_Specular_1); – matzar Nov 30 '16 at 13:25
  • I've heard that I can make my own Frame-buffer so would that be what I'd have to use for my own shader? – matzar Nov 30 '16 at 13:27
  • Thanks for letting me know about glBegin/glEnd! I didn't know that. – matzar Nov 30 '16 at 13:29
  • 1
    Framebuffers are something different than shaders. The most important task of shaders is that they define how vertices are transformed (translated, scaled, rotated, etc), and what the colours of individual pixels become. They are essentially small programs that run on the GPU while you are rendering geometry. I'd highly recommend reading through this page here: http://learnopengl.com/#!Getting-started/Shaders – Bartvbl Nov 30 '16 at 13:30
  • 1
    A Framebuffer is essentially a "virtual screen" you can draw to, just as if you were drawing to your actual screen. The difference is that what youi draw to an alternate framebuffer is not immediately visible on screen. However, the point of them is that you can do things like using the resulting image as a texture in your scene. If you for example want to render a bathroom mirror, you can render the bathroom from the point of view of the mirror to a texture, then display it on the bathroom wall so that it appears to be a reflection of the scene. – Bartvbl Nov 30 '16 at 13:35
  • Alright I see. I'll read the article. Cheers! – matzar Nov 30 '16 at 13:37
  • They also have information about materials and lighting there. Do take a look at those as well =) – Bartvbl Nov 30 '16 at 13:38
  • Thanks for the comment about the frame-buffer. It really helped me to understand it. Cheers! – matzar Nov 30 '16 at 13:39
  • Will do! Cheers! ^^ – matzar Nov 30 '16 at 13:40

0 Answers0