I'm following a tutorial series where we make a cube with a texture on it in Python OpenGL. For some reason when I run the code it produces a blank screen, most peculiar. Please help me I'm so lost and there's a deadline coming up.
On a previous one I had to add some window hints and a vertex array object which this tutorial did not include for some silly reason. Is there anything i need to change/add to this because i am really stuck.
import glfw
from OpenGL.GL import *
from OpenGL.GL.shaders import compileProgram, compileShader
import numpy as np
import pyrr
from PIL import Image
vertex_src = """
# version 330
layout(location = 0) in vec3 a_position;
layout(location = 1) in vec3 a_color;
layout(location = 2) in vec2 a_texture;
uniform mat4 rotation;
out vec3 v_color;
out vec2 v_texture;
void main()
{
gl_Position = rotation * vec4(a_position, 1.0);
v_color = a_color;
v_texture = a_texture;
//v_texture = 1 - a_texture; //Flips the texture vertically and horizontally
//v_texture = vec2(a_texture.s, 1 - a_texture.t); //Flips the texture vertically
}
"""
fragment_src = """
#version 330
in vec3 v_color;
in vec2 v_texture;
out vec4 out_color;
uniform sampler2D s_texture;
void main()
{
out_color = texture(s_texture, v_texture); // * vec4(v_color, 1.0f);
}
"""
#glfw callback functions
def window_resize(window, width, height):
glViewport(0, 0, width, height)
#initialising glfw library
if not glfw.init():
raise Exception("glfw cannot be initialised")
glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3)
glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 2)
glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, GL_TRUE)
glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
#creating the window
window = glfw.create_window(1280, 720, "My OpenGL Window", None, None)
#Check if window was created
if not window:
glfw.terminate()
raise Exception("glfw window cannot be created!")
glfw.set_window_pos(window, 400, 200)
glfw.set_window_size_callback(window, window_resize)
glfw.make_context_current(window)
vertices = [
-0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 0.0, 0.0,
0.5, -0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 0.0,
0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0,
-0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 1.0,
-0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 0.0,
0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0,
0.5, 0.5, -0.5, 0.0, 0.0, 1.0, 1.0, 1.0,
0.5, 0.5, -0.5, 1.0, 1.0, 1.0, 0.0, 1.0,
0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 0.0,
0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0,
0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0,
0.5, -0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 1.0,
-0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 0.0,
-0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0,
-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0,
-0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 1.0,
-0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 0.0,
0.5, -0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0,
0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0,
-0.5, -0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 1.0,
0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 0.0, 0.0,
-0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0,
-0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 1.0,
0.5, 0.5, 0.5, 1.0, 1.0, 1.0, 0.0, 1.0,
]
indices = [
0, 1, 2, 2, 3, 0,
4, 5, 6, 6, 7, 4,
8, 9, 10, 10, 11, 8,
12, 13, 14, 14, 15, 12,
16, 17, 18, 18, 19, 16,
20, 21, 22, 22, 23, 20
]
vertices = np.array(vertices, dtype=np.float32)
indices = np.array(indices, dtype=np.uint32)
shader = compileProgram(compileShader(vertex_src, GL_VERTEX_SHADER), compileShader(fragment_src, GL_FRAGMENT_SHADER))
VBO = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, VBO)
glBufferData(GL_ARRAY_BUFFER, vertices.nbytes, vertices, GL_STATIC_DRAW)
#Vertex array object
VAO = glGenVertexArrays(1)
glBindVertexArray(VAO)
glEnableVertexAttribArray(0)
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertices.itemsize * 8, ctypes.c_void_p(0))
glEnableVertexAttribArray(1)
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertices.itemsize * 8, ctypes.c_void_p(12))
glEnableVertexAttribArray(2)
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, vertices.itemsize * 8, ctypes.c_void_p(24))
texture = glGenTextures(1)
glBindTexture(GL_TEXTURE_2D, texture)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
image = Image.open("my_pic.png")
image = image.transpose(Image.FLIP_TOP_BOTTOM)
img_data = image.convert("RGBA").tobytes()
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width, image.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data)
glUseProgram(shader)
glClearColor(0, 0.1, 0.3, 1)
glEnable(GL_DEPTH_TEST)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
rotation_loc = glGetUniformLocation(shader, "rotation")
while not glfw.window_should_close(window):
glfw.poll_events()
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
rot_x = pyrr.Matrix44.from_x_rotation(0.5 * glfw.get_time())
rot_y = pyrr.Matrix44.from_y_rotation(0.8 * glfw.get_time())
glUniformMatrix4fv(rotation_loc, 1, GL_FALSE, pyrr.matrix44.multiply(rot_x, rot_y))
glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, None)
glfw.swap_buffers(window)
glfw.terminate()
glDrawElements
render primitives specified by the indexes in the index buffer. You missed the Index buffers (GL_ELEMENT_ARRAY_BUFFER
). Since the index buffer is stated in the vertex array object, the VAO must be created and bound before it can be created and bound:
AO = glGenVertexArrays(1)
glBindVertexArray(VAO)
IBO = glGenBuffers(1)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO)
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, indices, GL_STATIC_DRAW)