Search code examples
openglglslshaderopengl-compatglu

How can I draw gluQuadric with color?


struct quadricObj {
    GLUquadricObj* obj;
    GLenum drawmode{ GLU_FILL };
    GLdouble radius{1.0};
    GLint slices{20};
    GLint stacks{20};
    glm::vec3 col{ 1.0,0.0,0.0 };
    std::vector<glm::mat4> M;
    glm::mat4 world_M() {
        glm::mat4 WM(1.0f);
        std::for_each(this->M.begin(), this->M.end(), [&WM](glm::mat4& m) { WM *= m; });
        //M0*M1*M2 TRS
        return WM;
    }
    GLvoid draw() {
        gluQuadricDrawStyle(this->obj, this->drawmode);
        glUniformMatrix4fv(worldLoc, 1, GL_FALSE, glm::value_ptr(this->world_M()));
        glColor4f(this->col.r, this->col.g, this->col.b, 1.0f); // doesn't work.
        gluSphere(this->obj, this->radius, this->slices, this->stacks);
    }
};

This is my struct for use quadricObj. I think glColor4f has to work but doesn't. quadrics are staying black. How can I color quadrics in GL?

#version 330

in vec3 v_normal;
in vec2 v_texCoord;
in vec3 v_color;
in vec3 fragPos;

out vec4 gl_FragColor;

uniform vec3 lightColor;
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform float ambientLight;
uniform int shine;

void main(void)
{   
    vec3 ambient = clamp(ambientLight*lightColor,0.0,1.0);

    vec3 normalVector = normalize(v_normal);
    vec3 lightDir = normalize(lightPos-fragPos);
    float diffuseLight = max(dot(normalVector,lightDir),0.0); 
    vec3 diffuse = clamp(diffuseLight * lightColor,0.0,1.0);

    vec3 viewDir = normalize(viewPos-fragPos);
    vec3 reflectDir = reflect(-lightDir,normalVector);
    float specularLight = max(dot(viewDir,reflectDir),0.0);
    specularLight = pow(specularLight,shine);
    vec3 specular = clamp(specularLight*lightColor,0.0,1.0);

    vec3 result = (ambient+diffuse)*v_color+specular*(0.8,0.8,0.8);

    gl_FragColor = vec4(result,1.0);
}

I edit my fragment shader contain phong model. this can work with gluSphere too? or not? I'm using vertex shader too. which has inpos,col,nor,tex. and out also.


Solution

  • gluSphere cannot be used together with user defined vertex shader input variables (attribute). You are limited to a GLSL 1.20 vertex shader and the Vertex Shader Built-In Attributes. You can combine a GLSL 1.20 vertex shader with your fragment shader.

    A suitable vertex shader can look like this:

    #version 120
    
    varying vec3 v_normal;
    varying vec2 v_texCoord;
    varying vec3 v_color;
    varying vec3 fragPos;
    
    uniform mat4 worldMatrix; // the matrix with the location worldLoc
    
    void main()
    {
        v_color     = gl_Color.rgb;
        v_texCoord  = gl_MultiTexCoord0.st;
        v_normal    = mat3(worldMatrix) * gl_Normal;
        fragPos     = (worldMatrix * gl_Vertex).xyz;
        gl_Position = gl_ProjectionMatrix * worldMatrix * gl_Vertex;
    }