首页 > 解决方案 > How to darken the light for the whole scene in PyOpenGL?

问题描述

I am making a game in PyOpenGL and I want to let the light to be darkened when the player dies. How can I do that?

I've tried several resources like Tweak the brightness/gamma of the whole scene in OpenGL and https://www.gamedev.net/forums/topic/535812-disable-opengl-lighting-completely-to-dark-scene/ with no luck.

#!/usr/local/bin/python3
import pygame
from pygame.locals import *

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *

#[...]

glEnable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING)
glShadeModel(GL_SMOOTH)
glEnable(GL_COLOR_MATERIAL)
glEnable(GL_BLEND)
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE)

glEnable(GL_LIGHT0)
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.5, 0.5, 0.5, 1])
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1])

#[...]

while True:

    #[...]

            glClearColor(0.53, 0.63, 0.98, 1) #Change background colour (sky blue)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)

    #[...]

    if health <= 0:
        pass #this is where the darkening should go
        #---Tried---
        glDisable(GL_LIGHT1)
        glDisable(GL_LIGHT2)
        glDisable(GL_LIGHT3)
        glDisable(GL_LIGHT4)
        glDisable(GL_LIGHT5)
        glDisable(GL_LIGHT6)
        glDisable(GL_LIGHT7)
        glMaterialfv(GL_FRONT, GL_SPECULAR, @mat_specular)
        glMaterialfv(GL_FRONT, GL_SHININESS, @mat_shininess)
        glLightModelfv( GL_LIGHT_MODEL_AMBIENT, @globala )

        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glDepthFunc(GL_LEQUAL)
        glEnable(GL_DEPTH_TEST)
        #---Tried---
    pygame.display.flip()

I expected the scene to be dark, but instead it returns a traceback about decorators. Even if I delete these, nothing changes on my scene.

标签: pythonopengllightingpyopenglopengl-compat

解决方案


You have to reduce the RGB values for the ambient an diffuse light ( see glLight). e.g.:

glLightfv(GL_LIGHT0, GL_AMBIENT, [0.2, 0.2, 0.2, 1])
glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.8, 0.8, 0.8, 1])

The ambient light is applied to t all surfaces independent on the position or the direction of the light. The diffus light depends on the position respectively direction of the light and the normal vector (glNormal) of the surface.

The light color is multiplied by the current color (because of glEnable(GL_COLOR_MATERIAL)) and the ambient, diffuse and specular light are summed.

The standard OpenGL Blinn-Phong light model is calcualted like this:

Ka ... ambient material
Kd ... difusse material
Ks ... specular material

La ... ambient light
Ld ... diffuse light
Ls ... specular light
sh ... shininess

N  ... norlmal vector 
L  ... light vector (from the vertex position to the light) 
V  ... view vector (from the vertex position to the eye)

Id    = max(dot(N, L), 0.0);

H     = normalize(V + L);
NdotH = max(dot(N, H), 0.0);
Is    = pow(NdotH, sh);

fs    = Ka*La + Id*Kd*Ld + Is*Ks*Ls;

推荐阅读