opengl glsl中的着色问题

时间:2013-07-14 11:13:21

标签: opengl glsl lighting

我正在加载并试图应用一些阴影的3d obj(波前)模型(通过固定管道+着色器组合以简化目的)显示错误。

现在我觉得我可以发现一些问题。 光问题:似乎不是静止的。当我使用变换旋转对象时,它似乎旋转。我正在使用gluLookAt + gluPerspective来设置我的视图矩阵,并且我已经读过如果你在应用gluLookAt之前在opengl中应用光,理论上你的灯仍然是静态的。这似乎不是这种情况。

问题2是模型着色的方式。它有点波涛而不是光滑,我甚至不确定为什么会出现这种环效应。 我已经在ShaderMaker中加载了我的网格并且还应用了我的顶点+片段着色器,一切都很完美。好像我在绘图程序中做错了。

enter image description here

我的顶点着色器:

#version 120

varying vec3 N;
varying vec3 v;
void main(void)  
{    
   v = vec3(gl_ModelViewMatrix * gl_Vertex);      
   N = normalize(gl_NormalMatrix * gl_Normal);
   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;  
}

My Fragment着色器:

#version 120

varying vec3 N;
varying vec3 v;
#define MAX_LIGHTS 2
void main (void)  
{  
   vec4 finalColour;

        vec4 amb;
        amb = vec4(0.2,0.2,0.2,1.0);

        vec4 diff;
        diff = vec4(1.0,1.0,1.0,1.0);

       vec3 L = normalize(gl_LightSource[0].position.xyz - v);  
       vec3 E = normalize(v);
       vec3 R = normalize(reflect(L,-N));  
       //vec4 Iamb = gl_FrontLightProduct[i].ambient;    
        vec4 Iamb = amb;

        //vec4 Idiff = gl_FrontLightProduct[i].diffuse * max(dot(N,L), 0.0);
       vec4 Idiff = diff * max(dot(N,L), 0.0);

        Idiff = clamp(Idiff, 0.0, 1.0);    
       vec4 Ispec = gl_FrontLightProduct[0].specular
                    * pow(max(dot(R,E),0.0),0.0*gl_FrontMaterial.shininess);
       Ispec = clamp(Ispec, 0.0, 1.0);
       finalColour += Iamb + Idiff;

   gl_FragColor = gl_FrontLightModelProduct.sceneColor + finalColour;
}

编辑:: 添加了我的绘图程序。

 [[self openGLContext] makeCurrentContext];
    [sM useProgram];


    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glClearColor(0.0f,0.0f,0.0f,1.0f);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    float aspect = (float)1024 / (float)576;

    gluPerspective(15.0, aspect, 1.0, 15.0);

    glMatrixMode(GL_MODELVIEW);
    float lpos[4] = {0.0,2.0,0.0,1.0};
    glLoadIdentity();
    glLightfv(GL_LIGHT0, GL_POSITION, lpos);

    gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);


    glTranslatef(0.0f, 0.0f, 0.0f);
    glScalef(0.5f, 0.5f, 0.5f);

    glRotatef(self.rotValue, 1.0f, 1.0f, 0.0f);



    glEnableClientState(GL_VERTEX_ARRAY);  
    glEnableClientState(GL_NORMAL_ARRAY);
    NSLog(@"%i", self.W);

    if(self.W == NO)
    {
        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    } 
    if (self.W == YES)
    {
        glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    }
    glColor3f(1.0f,0.0f,0.0f);
    glBindBuffer(GL_ARRAY_BUFFER, vBo[0]);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vBo[1]);
    glNormalPointer(GL_FLOAT, 0, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vBo[2]);
    glDrawElements(GL_TRIANGLES, object.indicesCount, GL_UNSIGNED_INT, 0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);





    GLenum err = glGetError();
    if (err != GL_NO_ERROR)
        NSLog(@"glGetError(): %i", (int)err);

    [[self openGLContext] flushBuffer];

我的着色器实际上是从在线资源中借来的。我已经制作了自己的但我想确保我使用经验丰富的人。我不打算保留它们,直到我能解决这个问题。

1 个答案:

答案 0 :(得分:0)

我想我已经找到了这个问题。还没有实现解决方案,但我很确定问题就在那里。这个问题也与我的问题非常相关:

Understanding normals indices with Wavefront Obj

问题在于我处理核心数据的方式(来自obj文件)。我很天真地相信将它们直接传递给OpenGL(通过VBO),因为我解析它们会起作用。 伴随着我的错误,这是一种幽默。 我希望我的链接不违反指南规则。 特别感谢Andreas帮助我追踪问题。 link

更新:已实施解决方案,现在我的模型会以正确的阴影呈现。

我使用顶点和法线面将波前数据(顶点+法线)重新排列成新的矢量。我也从glDrawElements切换到glDrawArrays,因为glDrawElements不支持为normal和uv向量发送不同的索引。虽然这个解决方案增加了加载时间和占用空间(因为重复的顶点没有从缓冲区中删除),但它正在工作并满足我的需求。