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 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
|
||||
|
||||
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):
|
||||
""" Sample keyboard callback function """
|
||||
@ -45,16 +25,37 @@ def gl_get_unicode(k):
|
||||
return ans
|
||||
|
||||
|
||||
def on_resize(window, w, h):
|
||||
gl.glViewport(0, 0, w, h)
|
||||
class Renderer:
|
||||
|
||||
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():
|
||||
# These Window hints are used to specify
|
||||
# which opengl version to use and other details
|
||||
# for the opengl context that will be created
|
||||
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 4)
|
||||
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, 1)
|
||||
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, GL_VERSION[0])
|
||||
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_FORWARD_COMPAT, True)
|
||||
@ -65,7 +66,6 @@ def _main():
|
||||
raise SystemExit("glfwCreateWindow failed")
|
||||
glfw.glfwMakeContextCurrent(window)
|
||||
glfw.glfwSwapInterval(1)
|
||||
glfw.glfwSetFramebufferSizeCallback(window, on_resize)
|
||||
|
||||
# If everything went well the following calls
|
||||
# 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('Renderer: %s' % (gl_get_unicode(gl.GL_RENDERER)))
|
||||
|
||||
r = Renderer(1024, 1024)
|
||||
glfw.glfwSetFramebufferSizeCallback(window, r.on_resize)
|
||||
try:
|
||||
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:
|
||||
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):
|
||||
vertex_data = array(
|
||||
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
|
||||
|
||||
|
||||
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 = (
|
||||
'''
|
||||
#version 410
|
||||
'''\
|
||||
in vec2 vertex;
|
||||
in vec2 texture_position;
|
||||
out vec2 texture_position_for_fs;
|
||||
@ -150,8 +119,7 @@ void main() {
|
||||
}
|
||||
''',
|
||||
|
||||
'''
|
||||
#version 410
|
||||
'''\
|
||||
uniform sampler2D tex;
|
||||
in vec2 texture_position_for_fs;
|
||||
out vec4 final_color;
|
||||
@ -172,23 +140,20 @@ def texture_data():
|
||||
return cell, w, h
|
||||
|
||||
|
||||
def rectangle_texture(window):
|
||||
program = ShaderProgram(*textured_shaders)
|
||||
img_data, w, h = texture_data()
|
||||
with program:
|
||||
program.set_2d_texture('tex', img_data, w, h)
|
||||
rv, texc = rectangle_vertices()
|
||||
program.set_attribute_data('vertex', rv)
|
||||
program.set_attribute_data('texture_position', texc)
|
||||
|
||||
while not glfw.glfwWindowShouldClose(window):
|
||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
|
||||
def rectangle_texture(program=None):
|
||||
if program is None:
|
||||
program = ShaderProgram(*textured_shaders)
|
||||
img_data, w, h = texture_data()
|
||||
with program:
|
||||
program.set_2d_texture('tex', img_data, w, h)
|
||||
rv, texc = rectangle_vertices()
|
||||
program.set_attribute_data('vertex', rv)
|
||||
program.set_attribute_data('texture_position', texc)
|
||||
return program
|
||||
else:
|
||||
with program:
|
||||
gl.glDrawArrays(gl.GL_TRIANGLES, 0, 6)
|
||||
|
||||
glfw.glfwSwapBuffers(window)
|
||||
glfw.glfwWaitEvents()
|
||||
|
||||
|
||||
def on_error(code, msg):
|
||||
if isinstance(msg, bytes):
|
||||
|
||||
@ -13,6 +13,7 @@ from .config import load_config
|
||||
from .constants import appname, str_version, config_dir
|
||||
from .boss import Boss
|
||||
from .utils import fork_child, hangup
|
||||
from .shaders import GL_VERSION
|
||||
import glfw
|
||||
|
||||
|
||||
@ -34,8 +35,8 @@ def option_parser():
|
||||
|
||||
|
||||
def setup_opengl():
|
||||
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, 3)
|
||||
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MINOR, 2)
|
||||
glfw.glfwWindowHint(glfw.GLFW_CONTEXT_VERSION_MAJOR, GL_VERSION[0])
|
||||
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_FORWARD_COMPAT, True)
|
||||
glfw.glfwWindowHint(glfw.GLFW_SAMPLES, 0)
|
||||
|
||||
@ -7,28 +7,28 @@ from functools import lru_cache
|
||||
from OpenGL.arrays import ArrayDatatype
|
||||
import OpenGL.GL as gl
|
||||
|
||||
GL_VERSION = (4, 1)
|
||||
VERSION = GL_VERSION[0] * 100 + GL_VERSION[1] * 10
|
||||
|
||||
|
||||
class ShaderProgram:
|
||||
""" Helper class for using GLSL shader programs """
|
||||
|
||||
def __init__(self, vertex: str, fragment: str):
|
||||
def __init__(self, vertex, fragment):
|
||||
"""
|
||||
Create a shader program.
|
||||
|
||||
:param vertex: The vertex shader
|
||||
:param fragment: The fragment shader
|
||||
|
||||
"""
|
||||
self.program_id = gl.glCreateProgram()
|
||||
self.texture_id = None
|
||||
self.is_active = False
|
||||
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, 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:
|
||||
info = gl.glGetProgramInfoLog(self.program_id)
|
||||
gl.glDeleteProgram(self.program_id)
|
||||
@ -52,6 +52,7 @@ class ShaderProgram:
|
||||
def add_shader(self, source: str, shader_type: int) -> int:
|
||||
' Compile a shader and return its id, or raise an exception if compilation fails '
|
||||
shader_id = gl.glCreateShader(shader_type)
|
||||
source = '#version {}\n{}'.format(VERSION, source)
|
||||
try:
|
||||
gl.glShaderSource(shader_id, source)
|
||||
gl.glCompileShader(shader_id)
|
||||
@ -90,6 +91,10 @@ class ShaderProgram:
|
||||
def set_2d_texture(self, var_name, data, width, height, data_type='red',
|
||||
min_filter=gl.GL_LINEAR, mag_filter=gl.GL_LINEAR,
|
||||
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)
|
||||
self.texture_var = self.uniform_location(var_name)
|
||||
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)
|
||||
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:
|
||||
raise RuntimeError('The program must be active before you can add buffers')
|
||||
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')
|
||||
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.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)
|
||||
gl.glEnableVertexAttribArray(loc)
|
||||
typ = {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user