首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试在桌面的jogl中绘制带有Gouraud着色的模型,但却是平面的

尝试在桌面的jogl中绘制带有Gouraud着色的模型,但却是平面的
EN

Stack Overflow用户
提问于 2017-03-14 09:04:41
回答 1查看 232关注 0票数 0

我已经有了一个绘制的模型,但它有平坦的阴影(据我所知,默认情况下它应该是平滑的…)

这是初始配置:

代码语言:javascript
复制
private void SetLightningAndMaterials(){
    //float[] lightPos = {1, 1, 1, 0};
    float[] lightPos = {0, 0, 1, 0};
    float[] lightColorDiffuse = {1, 1, 1, 1};    
    float[] lightColorAmbient = {0.2f, 0.2f, 0.2f, 1};     

    gl.glShadeModel(GL.GL_SMOOTH); 

    gl.glLightfv(GL.GL_LIGHT1, GL.GL_POSITION, lightPos, 0);
    gl.glLightfv(GL.GL_LIGHT1, GL.GL_DIFFUSE, lightColorDiffuse, 0);
    gl.glLightfv(GL.GL_LIGHT1, GL.GL_AMBIENT, lightColorAmbient, 0);        

    gl.glEnable(GL.GL_LIGHT1);
    gl.glEnable(GL.GL_LIGHTING);

    gl.glMaterialfv(GL.GL_FRONT, GL.GL_AMBIENT, ambientColour, 0);   
    gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, mesh.colour, 0);

    gl.glEnable(GL.GL_LIGHTING);   
    gl.glEnable(GL.GL_LIGHT0);
    float[] noAmbient =
    { 0.1f, 0.1f, 0.1f, 1f }; // low ambient light
    float[] spec =
    { 1f, 0.6f, 0f, 1f }; // low ambient light
    float[] diffuse =
    { 0.5f, 0.5f, 0.5f, 1f };
    gl.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, noAmbient, 0);  
    gl.glLightfv(GL.GL_LIGHT0, GL.GL_SPECULAR, spec, 0);  
    gl.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, diffuse, 0);  
    gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, new float[]{0,0,10,1}, 0);
}

这就是我画模型的方式:

代码语言:javascript
复制
public void Draw(GL gl, GLU glu){      
Vec3d normal;
MassPoint vertex1, vertex2, vertex3;
int faceIndex=0;
Face surfaceFace;

for (faceIndex=0; faceIndex<surfaceFaces.size();faceIndex++){
    surfaceFace = surfaceFaces.get(faceIndex);
    surfaceFace.recalculateNormal();
    vertex1 = surfaceFace.vertex1;            
    vertex2 = surfaceFace.vertex2;            
    vertex3 = surfaceFace.vertex3;
    normal = surfaceFace.normal;   

    gl.glBegin(gl.GL_TRIANGLES); 
        gl.glNormal3d(normal.x, normal.y, normal.z);  

        gl.glMaterialfv(GL.GL_FRONT, GL.GL_DIFFUSE, colour, 0);
        gl.glVertex3d(vertex1.position.x, vertex1.position.y, vertex1.position.z);  

        gl.glVertex3d(vertex2.position.x, vertex2.position.y, vertex2.position.z);

        gl.glVertex3d(vertex3.position.x, vertex3.position.y, vertex3.position.z);

    gl.glEnd();               
}   
}   

我希望有一种简单的方法来解决这个问题,而不必创建一个着色器(我不知道如何在Java中设置这些着色器)。顺便说一下,我使用的是JOGL 1,可能是一个旧版本(导入类似于javax.media.opengl.*)。

EN

回答 1

Stack Overflow用户

发布于 2017-03-16 07:37:04

我设法解决了这个问题。为了平滑工作,绘图需要3条法线(每个顶点一条),我只传递了一条法线(每个面一条)。

以下是绘图的新代码:

代码语言:javascript
复制
public void Draw(GL gl, GLU glu) {      
    Vec3d[] normalsPerVertex = new Vec3d[3];
    MassPoint vertex1, vertex2, vertex3;

    int faceIndex=0;
    Face surfaceFace;
    for (faceIndex=0; faceIndex<surfaceFaces.size();faceIndex++){
        surfaceFace = surfaceFaces.get(faceIndex);
            vertex1=surfaceFace.vertex1;   
            normalsPerVertex[0] = vertex1.CalcNormal();
            vertex2=surfaceFace.vertex2;   
            normalsPerVertex[1] = vertex2.CalcNormal();         
            vertex3=surfaceFace.vertex3;
            normalsPerVertex[2] = vertex3.CalcNormal();

            gl.glBegin(GL.GL_TRIANGLES);  
                gl.glNormal3d(normalsPerVertex[0].x, normalsPerVertex[0].y, normalsPerVertex[0].z);  
                gl.glVertex3d(vertex1.position.x, vertex1.position.y, vertex1.position.z);  

                gl.glNormal3d(normalsPerVertex[1].x, normalsPerVertex[1].y, normalsPerVertex[1].z);  
                gl.glVertex3d(vertex2.position.x, vertex2.position.y, vertex2.position.z);

                gl.glNormal3d(normalsPerVertex[2].x, normalsPerVertex[2].y, normalsPerVertex[2].z);  
                gl.glVertex3d(vertex3.position.x, vertex3.position.y, vertex3.position.z);

            gl.glEnd();  
    }   
} 

为每个顶点计算的法线是连接到该顶点的所有面的介质。下面是实现该功能的代码:

代码语言:javascript
复制
public Vec3d CalcNormal() {
    Vec3d normalMedia = new Vec3d();
    for (Face face : facesRelated) {
        face.recalculateNormal();
        normalMedia.add(face.normal);
    }
    normalMedia.mul(1d/facesRelated.size());
    return normalMedia;
}

希望这对其他人有帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42776121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档