I'm building a scene: a cylinder, and a torus and an icosahedron spin around it, enter the fog and exit the fog. Using a file with a fog texture (any). However, I get a black scene at the exit - why is that?
Code:
# BLOCK 1: Imports and Window settings
from pygame.locals import *
import pygame
import math
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GL.shaders import compileProgram, compileShader
# creating a window
pygame.init()
display_size = (800, 600)
pygame.display.set_mode(display_size, DOUBLEBUF | OPENGL)
# BLOCK 2: Loading and configuring shaders
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):
""" Returning the coordinates of the vertices of the icosahedron """
length = math.sqrt(x**2 + y**2 + z**2)
return [(i * scale) / length for i in (x,y,z)]
# Create an icosahedron
# The Golden Ratio
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 polygons around the zero point
0, 11, 5,
0, 5, 1,
0, 1, 7,
0, 7, 10,
0, 10, 11,
# Polygons around
1, 5, 9,
5, 11, 4,
11, 10, 2,
10, 7, 6,
7, 1, 8,
# 5 polygons around the third point
3, 9, 4,
3, 4, 2,
3, 2, 6,
3, 6, 8,
3, 8, 9,
# Polygons around
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)
)
# we get the locations of uniform variables in shaders
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")
# BLOCK 3: Loading texture and setting cloud parameters
# загружаем текстуру с облаком
cloud_texture = pygame.image.load('fog.png')
cloud_texture_data = pygame.image.tostring(cloud_texture, 'RGB', True)
# create a texture
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)
# setting the color of the fog
fog_color = [0.4, 0.4, 0.3, 0.5]
# setting the properties of the cloud
cloud_thickness = 0.1
cloud_width = 4
# BLOCK 4: Animation and setting display properties
# animation
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)
# BLOCK 5: Rendering the cloud and cylinder
def draw_cloud():
glUseProgram(shader_program) # using a shader program
# passing values of uniform variables (matrices) to shaders
# sets the value of the modeling matrix to the shader program
glUniformMatrix4fv(model_loc, 1, GL_FALSE, glGetFloatv(GL_MODELVIEW_MATRIX))
# sets the value of the view matrix to the shader program
glUniformMatrix4fv(view_loc, 1, GL_FALSE, glGetFloatv(GL_PROJECTION_MATRIX))
# sets the value of the projection matrix to the shader program
glUniformMatrix4fv(projection_loc, 1, GL_FALSE, glGetFloatv(GL_PROJECTION_MATRIX))
# sets the value of the fog color to the shader program
glUniform4fv(fog_color_loc, 1, fog_color)
# sets the texture of clouds in the shader program
glUniform1i(cloud_texture_loc, 0)
# glEnable(GL_FOG) # turning on the fog
# glFogfv(GL_FOG_COLOR, fog_color)
# glFogi(GL_FOG_MODE, GL_LINEAR)
# glFogf(GL_FOG_START, 2.0)
# glFogf(GL_FOG_END, 10.0)
# turning on the fog
glEnable(GL_FOG)
glFogfv(GL_FOG_COLOR, fog_color)
glFogi(GL_FOG_MODE, GL_EXP2)
glFogf(GL_FOG_DENSITY, 0.05)
# Drawing an icosahedron
glColor3f(1.0, 0.0, 0.0)
glBegin(GL_TRIANGLES)
for i in indices:
glVertex3fv(vertices[i])
glEnd()
# Drawing a cylinder
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():
"""
Function to get rid of matrix stack overflow
"""
glDisable(GL_FOG) # turning off the fog
# BLOCK 6: Rendering the scene
def draw_scene():
# clearing the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
draw_cloud()
pygame.display.flip()
# BLOCK 7: Main Rendering cycle
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)
```