Почему я получаю черную сцену в OpenGL на Python?

Я строю сцену: цилиндр, а вокруг него крутятся тор и икосаэдр, которые входят в туман и выходят из тумана. Использую файл с текстурой тумана (любой). Однако на выходе получаю черную сцену - почему так?

Код:

from pygame.locals import *
import pygame
import math
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GL.shaders import compileProgram, compileShader

# создаем окно
pygame.init()
display_size = (800, 600)
pygame.display.set_mode(display_size, DOUBLEBUF | OPENGL)

# БЛОК 2: Загрузка и настройка шейдеров

# устанавливаем шейдеры
vertex_shader = """
#version 330

in vec3 position;
in vec2 texture_coords;

out vec2 new_texture_coords;

uniform mat4 model;
uniform mat4 view_matrix;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view_matrix * model * vec4(position, 1.0);
    new_texture_coords = texture_coords;
}
"""

fragment_shader = """
#version 330

in vec2 new_texture_coords;

out vec4 outcolor;

uniform sampler2D cloud_texture;
uniform vec4 fog_color;

void main()
{
    vec4 texcolor = texture(cloud_texture, new_texture_coords);
    outcolor = mix(fog_color, texcolor, texcolor.a);
}
"""

scale = 1

def vertex(x, y, z):
    """ Возвращаем координаты вершин икосаэндра """

    length = math.sqrt(x**2 + y**2 + z**2)

    return [(i * scale) / length for i in (x,y,z)]

# Создаём икосаэдр

# Золотое сечение
PHI = (1 + math.sqrt(5)) / 2

vertices = [
          vertex(-1,  PHI, 0), 
          vertex( 1,  PHI, 0), 
          vertex(-1, -PHI, 0), 
          vertex( 1, -PHI, 0), 

          vertex(0, -1, PHI), 
          vertex(0,  1, PHI), 
          vertex(0, -1, -PHI), 
          vertex(0,  1, -PHI), 

          vertex( PHI, 0, -1), 
          vertex( PHI, 0,  1), 
          vertex(-PHI, 0, -1), 
          vertex(-PHI, 0,  1),

            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 1.0,
            0.0, 1.0, 0.0,

            0.0, 1.0, 0.0,
            1.0, 0.0, 0.0,
            0.0, 0.0, 1.0,
            0.0, 0.0, 1.0,

            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 1.0,
            1.0, 0.0, 0.0,
        ]

indices = [
         # 5 полигонов вокруг нулевой точки
         0, 11, 5,
         0, 5, 1,
         0, 1, 7,
         0, 7, 10,
         0, 10, 11,

         # Полигоны вокруг
         1, 5, 9,
         5, 11, 4,
         11, 10, 2,
         10, 7, 6,
         7, 1, 8,

         # 5 полигонов вокруг третьей точки
         3, 9, 4,
         3, 4, 2,
         3, 2, 6,
         3, 6, 8,
         3, 8, 9,

         # Полигоны вокруг
         4, 9, 5,
         2, 4, 11,
         6, 2, 10,
         8, 6, 7,
         9, 8, 1
]

shader_program = compileProgram(
    compileShader(vertex_shader, GL_VERTEX_SHADER),
    compileShader(fragment_shader, GL_FRAGMENT_SHADER)
)

# получаем локации uniform-переменных в шейдерах
model_loc = glGetUniformLocation(shader_program, "model")
view_loc = glGetUniformLocation(shader_program, "view")
projection_loc = glGetUniformLocation(shader_program, "projection")
cloud_texture_loc = glGetUniformLocation(shader_program, "cloud_texture")
fog_color_loc = glGetUniformLocation(shader_program, "fog_color")

# БЛОК 3: Загрузка текстуры и установка параметров облака

# загружаем текстуру с облаком
cloud_texture = pygame.image.load('fog.png')
cloud_texture_data = pygame.image.tostring(cloud_texture, 'RGB', True)

# создаем текстуру
cloud_texture_id = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, cloud_texture_id)
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, cloud_texture.get_width(), cloud_texture.get_height(),
             0, GL_RGB, GL_UNSIGNED_BYTE, cloud_texture_data)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)

# задаем цвет тумана
fog_color = [0.4, 0.4, 0.3, 0.5]
# fog_color = [1, 1, 1, 0.5]

# задаем свойства облака
cloud_thickness = 0.1
cloud_width = 4

# БЛОК 4: Анимация и установка свойств отображения

# анимация
glMatrixMode(GL_PROJECTION)
gluPerspective(45, (display_size[0] / display_size[1]), 0.1, 50.0)

glMatrixMode(GL_MODELVIEW)
gluLookAt(0, -10, 10, 0, 0, 0, 0, 1, 0)


# БЛОК 5: Отрисовка облака и цилиндра

def draw_cloud():
    glUseProgram(shader_program)  # используем шейдерную программу

    # передаем значения uniform-переменных (матрицы) в шейдеры
  
    # устанавливает значение матрицы моделирования в шейдерную программу
    glUniformMatrix4fv(model_loc, 1, GL_FALSE, glGetFloatv(GL_MODELVIEW_MATRIX))
    
    # устанавливает значение матрицы вида в шейдерную программу
    glUniformMatrix4fv(view_loc, 1, GL_FALSE, glGetFloatv(GL_PROJECTION_MATRIX))
    
    # устанавливает значение матрицы проекции в шейдерную программу
    glUniformMatrix4fv(projection_loc, 1, GL_FALSE, glGetFloatv(GL_PROJECTION_MATRIX))
    
    # устанавливает значение цвета тумана в шейдерную программу
    glUniform4fv(fog_color_loc, 1, fog_color)
    
    # устанавливает текстуру облаков в шейдерную программу
    glUniform1i(cloud_texture_loc, 0)
    
    # включаем туман
    glEnable(GL_FOG)
    glFogfv(GL_FOG_COLOR, fog_color)
    glFogi(GL_FOG_MODE, GL_EXP2)
    glFogf(GL_FOG_DENSITY, 0.05)
    
    # Отрисовка икосаэдра
    glColor3f(1.0, 0.0, 0.0)
    glBegin(GL_TRIANGLES)
    for i in indices:
        glVertex3fv(vertices[i])
    glEnd()

    # Отрисовка цилиндра
    glColor3f(1.0, 1.0, 1.0)
    glPushMatrix()
    glTranslatef(5, 0, 0)
    quad = gluNewQuadric()
    glRotatef(90, 1, 0, 0)
    gluDisk(quad, 0.0, 0.5, 32, 32)
    gluCylinder(quad, 0.5, 0.5, 2, 32, 32)
    gluDisk(quad, 0.0, 0.5, 32, 32)
    gluDeleteQuadric(quad)
    glPopMatrix()

def end_draw_cloud():
    """
    Функция для избавления от переполнения стека матриц
    """
    glDisable(GL_FOG)  # выключаем туман
   
    
# БЛОК 6: Отрисовка сцены

def draw_scene():
    # очищаем экран
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    draw_cloud()

    pygame.display.flip()
    
# БЛОК 7: Основной цикл рендеринга

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()

    draw_scene()

    end_draw_cloud()
    
    pygame.time.wait(10)

Ответы (0 шт):