如何在 OpenGL 中仅为一个对象设置材质?

Posted

技术标签:

【中文标题】如何在 OpenGL 中仅为一个对象设置材质?【英文标题】:How do I set material only for one object in OpenGL? 【发布时间】:2020-04-08 08:48:10 【问题描述】:

我有两个 3D 对象,我只需要使用 glMaterial 函数在其中一个上设置材质。我怎样才能做到这一点?

#include <GLUT/glut.h>
#include <cmath>


const int width = 1200, height = 600;


float xValue = 0.0;
float position = 0.0;
float angle = 0.0;

float shininess[] =  1.0 ;
float color[] =  0.2, 0.2, 0.8 ;


void init(void);
void display(void);


int main(int argc, char** argv) 
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(width, height);
    glutInitWindowPosition(85, 75);
    glutCreateWindow("3D объекты - освещение");

    init();
    glutDisplayFunc(display);
    glutMainLoop();

    return 0;


void init(void) 
    glClearColor(0.0, 0.0, 0.0, 1.0);

    glEnable(GL_LIGHTING);

    float lightAmbient[] =  0.5, 0.5, 0.5, 0.0 ;
    float lightDiffuse[] =  0.5, 0.5, 0.5, 0.0 ;
    float lightSpecular[] =  0.5, 0.5, 0.5, 0.0 ;
    float lightPosition[] =  -10.0, 5.0, 0.0, 1.0 ;

    glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);
    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);

    glEnable(GL_LIGHT0);

    glEnable(GL_DEPTH_TEST);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glOrtho(-10.0, 10.0, -5.0, 5.0, -5.0, 5.0);


void display(void) 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0.0, 0.0, width, height);

    xValue += 0.01;
    position = 5.0*cos(xValue);
    angle = 270.0*sin(xValue);

    glLineWidth(3);

    glPushMatrix();
        glTranslatef(position, 0.0, 0.0);
        glRotatef(angle, 0, 1, 0);

        glMaterialfv(GL_FRONT, GL_AMBIENT, color);
        glMaterialfv(GL_FRONT, GL_DIFFUSE, color);
        glMaterialfv(GL_FRONT, GL_SPECULAR, color);
        glMaterialfv(GL_FRONT, GL_SHININESS, shininess);

        glutWireTorus(1, 2, 35, 35);
    glPopMatrix();

    glPushMatrix();
        glTranslatef(-position, 0.0, 0.0);
        glRotatef(angle, 0, 1, 0);

        glutSolidTorus(0.5, 3.5, 35, 35);
    glPopMatrix();

    glutSwapBuffers();
    glutPostRedisplay();

【问题讨论】:

【参考方案1】:

OpenGL 是一个状态引擎。每个状态都会保留,直到再次更改,甚至超出帧。例如,您可以在绘制对象之前启用和禁用照明:

glEnable(GL_LIGHTING);
// darw object 1

glDisable(GL_LIGHTING);
// draw object 2

在绘制对象之前,可以为每个对象单独设置材质设置:

glMaterialfv(...);
// darw object 1

glMaterialfv(...);
// draw object 2

【讨论】:

以上是关于如何在 OpenGL 中仅为一个对象设置材质?的主要内容,如果未能解决你的问题,请参考以下文章

如何在通用 UIViewController - 通用应用程序中仅为 iPAD 创建 IBOutlet

如何在UITextField中仅为UIControlEvent.allEditingEvents覆盖addTarget?

如何在我的 Spring Boot Security OAuth2 应用程序中仅为某些类启用 OAuth2?

如何设置opengl对象的大小?

如何访问以前的状态,并使用它在单个状态设置器调用中仅更新某些对象属性?

OpenGL光照设置