Specify the needed opengl version centrally
This commit is contained in:
parent
7161406ff3
commit
8c76596f5c
@ -6,29 +6,9 @@ import glfw
|
|||||||
import OpenGL.GL as gl
|
import OpenGL.GL as gl
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from kitty.shaders import ShaderProgram, array
|
from kitty.shaders import ShaderProgram, array, GL_VERSION
|
||||||
from kitty.fonts import set_font_family, render_cell, cell_size
|
from kitty.fonts import set_font_family, render_cell, cell_size
|
||||||
|
|
||||||
vertex_shader = """
|
|
||||||
# version 410
|
|
||||||
in vec2 vertex;
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
gl_Position = vec4(vertex, 0, 1);
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
fragment = """
|
|
||||||
# version 410
|
|
||||||
out vec4 final_color;
|
|
||||||
|
|
||||||
void main(void)
|
|
||||||
{
|
|
||||||
final_color = vec4(1.0);
|
|
||||||
}
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def key_callback(key, action):
|
def key_callback(key, action):
|
||||||
""" Sample keyboard callback function """
|
""" Sample keyboard callback function """
|
||||||
@ -45,16 +25,37 @@ def gl_get_unicode(k):
|
|||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
def on_resize(window, w, h):
|
class Renderer:
|
||||||
gl.glViewport(0, 0, w, h)
|
|
||||||
|
def __init__(self, w, h):
|
||||||
|
self.w, self.h = w, h
|
||||||
|
self.do_layout()
|
||||||
|
self.program = rectangle_texture()
|
||||||
|
print(gl.glGetIntegerv(gl.GL_MAX_VERTEX_UNIFORM_COMPONENTS))
|
||||||
|
print(gl.glGetIntegerv(gl.GL_MAX_UNIFORM_BLOCK_SIZE))
|
||||||
|
print(gl.glGetIntegerv(gl.GL_MAX_ARRAY_TEXTURE_LAYERS))
|
||||||
|
|
||||||
|
def on_resize(self, window, w, h):
|
||||||
|
gl.glViewport(0, 0, w, h)
|
||||||
|
self.w, self.h = w, h
|
||||||
|
self.do_layout()
|
||||||
|
|
||||||
|
def do_layout(self):
|
||||||
|
# Divide into cells
|
||||||
|
cell_width, cell_height = cell_size()
|
||||||
|
self.cells_per_line = self.w // cell_width
|
||||||
|
self.lines_per_screen = self.h // cell_height
|
||||||
|
|
||||||
|
def render(self):
|
||||||
|
rectangle_texture(self.program)
|
||||||
|
|
||||||
|
|
||||||
def _main():
|
def _main():
|
||||||
# These Window hints are used to specify
|
# These Window hints are used to specify
|
||||||
# which opengl version to use and other details
|
# which opengl version to use and other details
|
||||||
# for the opengl context that will be created
|
# for the opengl context that will be created
|
||||||
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 4)
|
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, GL_VERSION[0])
|
||||||
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, 1)
|
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, GL_VERSION[1])
|
||||||
glfw.glfwWindowHint(glfw.GLFW_OPENGL_PROFILE,
|
glfw.glfwWindowHint(glfw.GLFW_OPENGL_PROFILE,
|
||||||
glfw.GLFW_OPENGL_CORE_PROFILE)
|
glfw.GLFW_OPENGL_CORE_PROFILE)
|
||||||
glfw.glfwWindowHint(glfw.GLFW_OPENGL_FORWARD_COMPAT, True)
|
glfw.glfwWindowHint(glfw.GLFW_OPENGL_FORWARD_COMPAT, True)
|
||||||
@ -65,7 +66,6 @@ def _main():
|
|||||||
raise SystemExit("glfwCreateWindow failed")
|
raise SystemExit("glfwCreateWindow failed")
|
||||||
glfw.glfwMakeContextCurrent(window)
|
glfw.glfwMakeContextCurrent(window)
|
||||||
glfw.glfwSwapInterval(1)
|
glfw.glfwSwapInterval(1)
|
||||||
glfw.glfwSetFramebufferSizeCallback(window, on_resize)
|
|
||||||
|
|
||||||
# If everything went well the following calls
|
# If everything went well the following calls
|
||||||
# will display the version of opengl being used
|
# will display the version of opengl being used
|
||||||
@ -74,21 +74,19 @@ def _main():
|
|||||||
print('GLSL Version: %s' % (gl_get_unicode(gl.GL_SHADING_LANGUAGE_VERSION)))
|
print('GLSL Version: %s' % (gl_get_unicode(gl.GL_SHADING_LANGUAGE_VERSION)))
|
||||||
print('Renderer: %s' % (gl_get_unicode(gl.GL_RENDERER)))
|
print('Renderer: %s' % (gl_get_unicode(gl.GL_RENDERER)))
|
||||||
|
|
||||||
|
r = Renderer(1024, 1024)
|
||||||
|
glfw.glfwSetFramebufferSizeCallback(window, r.on_resize)
|
||||||
try:
|
try:
|
||||||
gl.glClearColor(0.5, 0.5, 0.5, 0)
|
gl.glClearColor(0.5, 0.5, 0.5, 0)
|
||||||
rectangle_texture(window)
|
while not glfw.glfwWindowShouldClose(window):
|
||||||
|
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
|
||||||
|
r.render()
|
||||||
|
glfw.glfwSwapBuffers(window)
|
||||||
|
glfw.glfwWaitEvents()
|
||||||
finally:
|
finally:
|
||||||
glfw.glfwDestroyWindow(window)
|
glfw.glfwDestroyWindow(window)
|
||||||
|
|
||||||
|
|
||||||
def triangle_vertices(width=0.8, height=0.8):
|
|
||||||
return array(
|
|
||||||
0.0, height,
|
|
||||||
-width, -height,
|
|
||||||
width, -height,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def rectangle_vertices(left=-0.8, top=0.8, right=0.8, bottom=-0.8):
|
def rectangle_vertices(left=-0.8, top=0.8, right=0.8, bottom=-0.8):
|
||||||
vertex_data = array(
|
vertex_data = array(
|
||||||
right, top,
|
right, top,
|
||||||
@ -109,37 +107,8 @@ def rectangle_vertices(left=-0.8, top=0.8, right=0.8, bottom=-0.8):
|
|||||||
return vertex_data, texture_coords
|
return vertex_data, texture_coords
|
||||||
|
|
||||||
|
|
||||||
def rectangle(window):
|
|
||||||
program = ShaderProgram(vertex_shader, fragment)
|
|
||||||
|
|
||||||
with program:
|
|
||||||
program.set_attribute_data('vertex', rectangle_vertices()[0])
|
|
||||||
|
|
||||||
while not glfw.glfwWindowShouldClose(window):
|
|
||||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
|
|
||||||
with program:
|
|
||||||
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
|
|
||||||
|
|
||||||
glfw.glfwSwapBuffers(window)
|
|
||||||
glfw.glfwWaitEvents()
|
|
||||||
|
|
||||||
|
|
||||||
def triangle(window):
|
|
||||||
program = ShaderProgram(vertex_shader, fragment)
|
|
||||||
with program:
|
|
||||||
program.set_attribute_data('vertex', triangle_vertices())
|
|
||||||
|
|
||||||
while not glfw.glfwWindowShouldClose(window):
|
|
||||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
|
|
||||||
with program:
|
|
||||||
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 3)
|
|
||||||
|
|
||||||
glfw.glfwSwapBuffers(window)
|
|
||||||
glfw.glfwWaitEvents()
|
|
||||||
|
|
||||||
textured_shaders = (
|
textured_shaders = (
|
||||||
'''
|
'''\
|
||||||
#version 410
|
|
||||||
in vec2 vertex;
|
in vec2 vertex;
|
||||||
in vec2 texture_position;
|
in vec2 texture_position;
|
||||||
out vec2 texture_position_for_fs;
|
out vec2 texture_position_for_fs;
|
||||||
@ -150,8 +119,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
''',
|
''',
|
||||||
|
|
||||||
'''
|
'''\
|
||||||
#version 410
|
|
||||||
uniform sampler2D tex;
|
uniform sampler2D tex;
|
||||||
in vec2 texture_position_for_fs;
|
in vec2 texture_position_for_fs;
|
||||||
out vec4 final_color;
|
out vec4 final_color;
|
||||||
@ -172,23 +140,20 @@ def texture_data():
|
|||||||
return cell, w, h
|
return cell, w, h
|
||||||
|
|
||||||
|
|
||||||
def rectangle_texture(window):
|
def rectangle_texture(program=None):
|
||||||
program = ShaderProgram(*textured_shaders)
|
if program is None:
|
||||||
img_data, w, h = texture_data()
|
program = ShaderProgram(*textured_shaders)
|
||||||
with program:
|
img_data, w, h = texture_data()
|
||||||
program.set_2d_texture('tex', img_data, w, h)
|
with program:
|
||||||
rv, texc = rectangle_vertices()
|
program.set_2d_texture('tex', img_data, w, h)
|
||||||
program.set_attribute_data('vertex', rv)
|
rv, texc = rectangle_vertices()
|
||||||
program.set_attribute_data('texture_position', texc)
|
program.set_attribute_data('vertex', rv)
|
||||||
|
program.set_attribute_data('texture_position', texc)
|
||||||
while not glfw.glfwWindowShouldClose(window):
|
return program
|
||||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
|
else:
|
||||||
with program:
|
with program:
|
||||||
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
|
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
|
||||||
|
|
||||||
glfw.glfwSwapBuffers(window)
|
|
||||||
glfw.glfwWaitEvents()
|
|
||||||
|
|
||||||
|
|
||||||
def on_error(code, msg):
|
def on_error(code, msg):
|
||||||
if isinstance(msg, bytes):
|
if isinstance(msg, bytes):
|
||||||
|
|||||||
@ -13,6 +13,7 @@ from .config import load_config
|
|||||||
from .constants import appname, str_version, config_dir
|
from .constants import appname, str_version, config_dir
|
||||||
from .boss import Boss
|
from .boss import Boss
|
||||||
from .utils import fork_child, hangup
|
from .utils import fork_child, hangup
|
||||||
|
from .shaders import GL_VERSION
|
||||||
import glfw
|
import glfw
|
||||||
|
|
||||||
|
|
||||||
@ -34,8 +35,8 @@ def option_parser():
|
|||||||
|
|
||||||
|
|
||||||
def setup_opengl():
|
def setup_opengl():
|
||||||
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 3)
|
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, GL_VERSION[0])
|
||||||
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, 2)
|
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, GL_VERSION[1])
|
||||||
glfw.glfwWindowHint(glfw.GLFW_OPENGL_PROFILE, glfw.GLFW_OPENGL_CORE_PROFILE)
|
glfw.glfwWindowHint(glfw.GLFW_OPENGL_PROFILE, glfw.GLFW_OPENGL_CORE_PROFILE)
|
||||||
glfw.glfwWindowHint(glfw.GLFW_OPENGL_FORWARD_COMPAT, True)
|
glfw.glfwWindowHint(glfw.GLFW_OPENGL_FORWARD_COMPAT, True)
|
||||||
glfw.glfwWindowHint(glfw.GLFW_SAMPLES, 0)
|
glfw.glfwWindowHint(glfw.GLFW_SAMPLES, 0)
|
||||||
|
|||||||
@ -7,28 +7,28 @@ from functools import lru_cache
|
|||||||
from OpenGL.arrays import ArrayDatatype
|
from OpenGL.arrays import ArrayDatatype
|
||||||
import OpenGL.GL as gl
|
import OpenGL.GL as gl
|
||||||
|
|
||||||
|
GL_VERSION = (4, 1)
|
||||||
|
VERSION = GL_VERSION[0] * 100 + GL_VERSION[1] * 10
|
||||||
|
|
||||||
|
|
||||||
class ShaderProgram:
|
class ShaderProgram:
|
||||||
""" Helper class for using GLSL shader programs """
|
""" Helper class for using GLSL shader programs """
|
||||||
|
|
||||||
def __init__(self, vertex: str, fragment: str):
|
def __init__(self, vertex, fragment):
|
||||||
"""
|
"""
|
||||||
Create a shader program.
|
Create a shader program.
|
||||||
|
|
||||||
:param vertex: The vertex shader
|
|
||||||
:param fragment: The fragment shader
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
self.program_id = gl.glCreateProgram()
|
self.program_id = gl.glCreateProgram()
|
||||||
self.texture_id = None
|
self.texture_id = None
|
||||||
self.is_active = False
|
self.is_active = False
|
||||||
vs_id = self.add_shader(vertex, gl.GL_VERTEX_SHADER)
|
vs_id = self.add_shader(vertex, gl.GL_VERTEX_SHADER)
|
||||||
frag_id = self.add_shader(fragment, gl.GL_FRAGMENT_SHADER)
|
|
||||||
|
|
||||||
gl.glAttachShader(self.program_id, vs_id)
|
gl.glAttachShader(self.program_id, vs_id)
|
||||||
gl.glAttachShader(self.program_id, frag_id)
|
|
||||||
gl.glLinkProgram(self.program_id)
|
|
||||||
|
|
||||||
|
frag_id = self.add_shader(fragment, gl.GL_FRAGMENT_SHADER)
|
||||||
|
gl.glAttachShader(self.program_id, frag_id)
|
||||||
|
|
||||||
|
gl.glLinkProgram(self.program_id)
|
||||||
if gl.glGetProgramiv(self.program_id, gl.GL_LINK_STATUS) != gl.GL_TRUE:
|
if gl.glGetProgramiv(self.program_id, gl.GL_LINK_STATUS) != gl.GL_TRUE:
|
||||||
info = gl.glGetProgramInfoLog(self.program_id)
|
info = gl.glGetProgramInfoLog(self.program_id)
|
||||||
gl.glDeleteProgram(self.program_id)
|
gl.glDeleteProgram(self.program_id)
|
||||||
@ -52,6 +52,7 @@ class ShaderProgram:
|
|||||||
def add_shader(self, source: str, shader_type: int) -> int:
|
def add_shader(self, source: str, shader_type: int) -> int:
|
||||||
' Compile a shader and return its id, or raise an exception if compilation fails '
|
' Compile a shader and return its id, or raise an exception if compilation fails '
|
||||||
shader_id = gl.glCreateShader(shader_type)
|
shader_id = gl.glCreateShader(shader_type)
|
||||||
|
source = '#version {}\n{}'.format(VERSION, source)
|
||||||
try:
|
try:
|
||||||
gl.glShaderSource(shader_id, source)
|
gl.glShaderSource(shader_id, source)
|
||||||
gl.glCompileShader(shader_id)
|
gl.glCompileShader(shader_id)
|
||||||
@ -90,6 +91,10 @@ class ShaderProgram:
|
|||||||
def set_2d_texture(self, var_name, data, width, height, data_type='red',
|
def set_2d_texture(self, var_name, data, width, height, data_type='red',
|
||||||
min_filter=gl.GL_LINEAR, mag_filter=gl.GL_LINEAR,
|
min_filter=gl.GL_LINEAR, mag_filter=gl.GL_LINEAR,
|
||||||
swrap=gl.GL_CLAMP_TO_EDGE, twrap=gl.GL_CLAMP_TO_EDGE):
|
swrap=gl.GL_CLAMP_TO_EDGE, twrap=gl.GL_CLAMP_TO_EDGE):
|
||||||
|
if not self.is_active:
|
||||||
|
raise RuntimeError('The program must be active before you can add buffers')
|
||||||
|
if self.texture_id is not None:
|
||||||
|
gl.glDeleteTextures([self.texture_id])
|
||||||
texture_id = self.texture_id = gl.glGenTextures(1)
|
texture_id = self.texture_id = gl.glGenTextures(1)
|
||||||
self.texture_var = self.uniform_location(var_name)
|
self.texture_var = self.uniform_location(var_name)
|
||||||
gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1 if data_type == 'red' else 4)
|
gl.glPixelStorei(gl.GL_UNPACK_ALIGNMENT, 1 if data_type == 'red' else 4)
|
||||||
@ -107,14 +112,16 @@ class ShaderProgram:
|
|||||||
0, external_format, gl.GL_UNSIGNED_BYTE, data)
|
0, external_format, gl.GL_UNSIGNED_BYTE, data)
|
||||||
return texture_id
|
return texture_id
|
||||||
|
|
||||||
def set_attribute_data(self, attribute_name, data, items_per_attribute_value=2, volatile=False, normalize=False):
|
def set_attribute_data(self, attribute_name, data, items_per_attribute_value=2, normalize=False):
|
||||||
if not self.is_active:
|
if not self.is_active:
|
||||||
raise RuntimeError('The program must be active before you can add buffers')
|
raise RuntimeError('The program must be active before you can add buffers')
|
||||||
if len(data) % items_per_attribute_value != 0:
|
if len(data) % items_per_attribute_value != 0:
|
||||||
raise ValueError('The length of the data buffer is not a multiple of the items_per_attribute_value')
|
raise ValueError('The length of the data buffer is not a multiple of the items_per_attribute_value')
|
||||||
buf_id = self.attribute_buffers[attribute_name] = gl.glGenBuffers(1)
|
buf_id = self.attribute_buffers.get(attribute_name) # glBufferData auto-deletes previous data
|
||||||
|
if buf_id is None:
|
||||||
|
buf_id = self.attribute_buffers[attribute_name] = gl.glGenBuffers(1)
|
||||||
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buf_id)
|
gl.glBindBuffer(gl.GL_ARRAY_BUFFER, buf_id)
|
||||||
gl.glBufferData(gl.GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(data), data, gl.GL_STREAM_DRAW if volatile else gl.GL_STATIC_DRAW)
|
gl.glBufferData(gl.GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(data), data, gl.GL_STATIC_DRAW)
|
||||||
loc = self.attribute_location(attribute_name)
|
loc = self.attribute_location(attribute_name)
|
||||||
gl.glEnableVertexAttribArray(loc)
|
gl.glEnableVertexAttribArray(loc)
|
||||||
typ = {
|
typ = {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user