Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 410f936b7b | |||
| 79bda8a568 | |||
| 1fefbeba52 | |||
| 1336b5cfb8 | |||
| 935a25490a | |||
| 5f73d6f1b2 | |||
| 595e4d45bd | |||
| c42667b197 | |||
| 00750cb5d5 | |||
| 5f42c6bff9 | |||
| e6e11dab9f | |||
| 6351d60213 | |||
| 2928e5495c | |||
| ffd5eddaf9 | |||
| 27b4c46013 | |||
| c8da44781d | |||
| a40d302500 | |||
| 8ad44080ae | |||
| c41b740ae6 | |||
| 67e508c979 | |||
| a7e9d39c1d | |||
| 921ddb07f7 | |||
| b2b222f23e | |||
| af202584db | |||
| d38dbc79b2 | |||
| 15c6fdf8c1 | |||
| 5e02e88ec0 | |||
| 3337049968 | |||
| 2565157a5a |
@@ -116,7 +116,7 @@ init python in project:
|
||||
|
||||
try:
|
||||
with open(os.path.join(self.path, "project.json"), "w") as f:
|
||||
json.dump(self.data, f)
|
||||
json.dump(self.data, f, indent=2)
|
||||
except Exception:
|
||||
self.load_data()
|
||||
|
||||
|
||||
@@ -25,11 +25,6 @@ renpy.display.accelerator gen/renpy.display.accelerator.c
|
||||
renpy.display.quaternion gen/renpy.display.quaternion.c
|
||||
renpy.uguu.gl gen/renpy.uguu.gl.c
|
||||
renpy.uguu.uguu gen/renpy.uguu.uguu.c
|
||||
renpy.gl.gldraw gen/renpy.gl.gldraw.c
|
||||
renpy.gl.gltexture gen/renpy.gl.gltexture.c
|
||||
renpy.gl.glenviron_shader gen/renpy.gl.glenviron_shader.c
|
||||
renpy.gl.glrtt_copy gen/renpy.gl.glrtt_copy.c
|
||||
renpy.gl.glrtt_fbo gen/renpy.gl.glrtt_fbo.c
|
||||
renpy.gl2.gl2mesh gen/renpy.gl2.gl2mesh.c
|
||||
renpy.gl2.gl2mesh2 gen/renpy.gl2.gl2mesh2.c
|
||||
renpy.gl2.gl2mesh3 gen/renpy.gl2.gl2mesh3.c
|
||||
|
||||
@@ -174,12 +174,6 @@ cython("renpy.display.quaternion", libs=[ 'm' ])
|
||||
cython("renpy.uguu.gl", libs=sdl)
|
||||
cython("renpy.uguu.uguu", libs=sdl)
|
||||
|
||||
cython("renpy.gl.gldraw", libs=sdl)
|
||||
cython("renpy.gl.gltexture", libs=sdl)
|
||||
cython("renpy.gl.glenviron_shader", libs=sdl)
|
||||
cython("renpy.gl.glrtt_copy", libs=sdl)
|
||||
cython("renpy.gl.glrtt_fbo", libs=sdl)
|
||||
|
||||
cython("renpy.gl2.gl2mesh")
|
||||
cython("renpy.gl2.gl2mesh2")
|
||||
cython("renpy.gl2.gl2mesh3")
|
||||
|
||||
@@ -223,7 +223,6 @@ backup_blacklist = {
|
||||
"renpy.test.testmouse",
|
||||
"renpy.test.testparser",
|
||||
"renpy.gl2",
|
||||
"renpy.gl",
|
||||
"renpycoverage",
|
||||
}
|
||||
|
||||
@@ -479,7 +478,6 @@ def import_all():
|
||||
|
||||
sys.modules[pystr('renpy.display.text')] = renpy.text.text
|
||||
|
||||
import renpy.gl
|
||||
import renpy.gl2
|
||||
|
||||
import renpy.display.layout
|
||||
|
||||
@@ -217,7 +217,6 @@ init -1100 python:
|
||||
|
||||
if version <= (7, 4, 4):
|
||||
config.pause_after_rollback = True
|
||||
config.gl2 = False
|
||||
config.gl_lod_bias = -1.0
|
||||
config.who_what_sub_compat = 1
|
||||
|
||||
|
||||
@@ -27,8 +27,7 @@ init -1500:
|
||||
python:
|
||||
class _SetRenderer(Action):
|
||||
"""
|
||||
Sets the preferred renderer to one of "auto", "angle", "gl", or
|
||||
"sw".
|
||||
Sets the preferred renderer.
|
||||
"""
|
||||
|
||||
def __init__(self, renderer):
|
||||
@@ -95,24 +94,6 @@ init -1500:
|
||||
action _SetRenderer("auto")
|
||||
style_suffix "radio_button"
|
||||
|
||||
if not config.gl2:
|
||||
|
||||
if gl:
|
||||
textbutton _("Force GL Renderer"):
|
||||
action _SetRenderer("gl")
|
||||
style_suffix "radio_button"
|
||||
|
||||
if angle:
|
||||
textbutton _("Force ANGLE Renderer"):
|
||||
action _SetRenderer("angle")
|
||||
style_suffix "radio_button"
|
||||
|
||||
if gles:
|
||||
textbutton _("Force GLES Renderer"):
|
||||
action _SetRenderer("gles")
|
||||
style_suffix "radio_button"
|
||||
|
||||
|
||||
if gl:
|
||||
textbutton _("Force GL2 Renderer"):
|
||||
action _SetRenderer("gl2")
|
||||
@@ -349,16 +330,11 @@ init -1500 python:
|
||||
|
||||
renderer_info = renpy.get_renderer_info()
|
||||
|
||||
# Software renderer check.
|
||||
# Software renderer check.
|
||||
if config.renderer != "sw" and renderer_info["renderer"] == "sw":
|
||||
problem = "sw"
|
||||
allow_continue = False
|
||||
|
||||
# Game require gl2 that wasn't initialized.
|
||||
elif config.gl2 and not renderer_info.get("models", False):
|
||||
problem = "gl2"
|
||||
allow_continue = False
|
||||
|
||||
if problem is None:
|
||||
return
|
||||
|
||||
|
||||
+4
-18
@@ -1201,24 +1201,15 @@ class Interface(object):
|
||||
renpy.config.renderer = renderer
|
||||
|
||||
if renpy.android or renpy.ios or renpy.emscripten:
|
||||
renderers = [ "gles" ]
|
||||
renderers = [ "gles2" ]
|
||||
elif renpy.windows:
|
||||
renderers = [ "gl", "angle", "gles" ]
|
||||
renderers = [ "gl2", "angle2", "gles2" ]
|
||||
else:
|
||||
renderers = [ "gl", "gles" ]
|
||||
|
||||
gl2_renderers = [ ]
|
||||
|
||||
for i in [ "gl", "angle", "gles" ]:
|
||||
|
||||
if i in renderers:
|
||||
gl2_renderers.append(i + "2")
|
||||
|
||||
renderers = gl2_renderers + renderers
|
||||
renderers = [ "gl2", "gles2" ]
|
||||
|
||||
# Prevent a performance warning if the renderer
|
||||
# is taken from old persistent data.
|
||||
if renderer not in gl2_renderers and (renpy.macintosh or renpy.android or renpy.config.gl2):
|
||||
if renderer not in renderers:
|
||||
renderer = "auto"
|
||||
|
||||
# Software renderer is the last hope for PC .
|
||||
@@ -1254,10 +1245,6 @@ class Interface(object):
|
||||
|
||||
return False
|
||||
|
||||
make_draw("gl", "renpy.gl.gldraw", "GLDraw", "gl")
|
||||
make_draw("angle", "renpy.gl.gldraw", "GLDraw", "angle")
|
||||
make_draw("gles", "renpy.gl.gldraw", "GLDraw", "gles")
|
||||
|
||||
make_draw("gl2", "renpy.gl2.gl2draw", "GL2Draw", "gl2")
|
||||
make_draw("angle2", "renpy.gl2.gl2draw", "GL2Draw", "angle2")
|
||||
make_draw("gles2", "renpy.gl2.gl2draw", "GL2Draw", "gles2")
|
||||
@@ -1364,7 +1351,6 @@ class Interface(object):
|
||||
raise Exception("Could not set video mode.")
|
||||
|
||||
renpy.session["renderer"] = draw.info["renderer"]
|
||||
renpy.game.persistent._gl2 = renpy.config.gl2
|
||||
|
||||
if renpy.android:
|
||||
android.init()
|
||||
|
||||
@@ -60,8 +60,6 @@ def init_display():
|
||||
The minimum amount of code required to init the display.
|
||||
"""
|
||||
|
||||
renpy.config.gl2 = getattr(renpy.game.persistent, "_gl2", True)
|
||||
|
||||
# Ensure we have correctly-typed preferences.
|
||||
renpy.game.preferences.check()
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
from __future__ import division, absolute_import, with_statement, print_function, unicode_literals
|
||||
from renpy.compat import PY2, basestring, bchr, bord, chr, open, pystr, range, round, str, tobytes, unicode # *
|
||||
|
||||
|
||||
|
||||
import renpy
|
||||
renpy.update_path()
|
||||
|
||||
|
||||
# Generated by scripts/relative_imports.py, do not edit below this line.
|
||||
if 1 == 0:
|
||||
from . import gldraw
|
||||
from . import glenviron_shader
|
||||
from . import glfunctions
|
||||
from . import glrtt_copy
|
||||
from . import glrtt_fbo
|
||||
from . import gltexture
|
||||
@@ -1,96 +0,0 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from renpy.display.matrix cimport Matrix, Matrix2D
|
||||
cimport renpy.display.render as render
|
||||
|
||||
cdef class Environ
|
||||
|
||||
cdef class GLDraw:
|
||||
|
||||
cdef bint gles
|
||||
cdef bint angle
|
||||
cdef bint did_init
|
||||
cdef bint did_texture_test
|
||||
cdef Environ environ
|
||||
cdef public object rtt
|
||||
cdef object window
|
||||
cdef tuple virtual_size
|
||||
cdef public tuple physical_size
|
||||
cdef public tuple drawable_size
|
||||
cdef public tuple virtual_box
|
||||
cdef public tuple physical_box
|
||||
cdef object texture_cache
|
||||
cdef double last_redraw_time
|
||||
cdef double redraw_period
|
||||
cdef public dict info
|
||||
cdef object old_fullscreen
|
||||
cdef public object fullscreen_surface
|
||||
cdef object display_info
|
||||
cdef tuple clip_cache
|
||||
cdef bint fast_dissolve
|
||||
cdef tuple default_clip
|
||||
cdef bint did_render_to_texture
|
||||
cdef float dpi_scale
|
||||
cdef object ready_texture_queue
|
||||
|
||||
cdef public tuple clip_rtt_box
|
||||
|
||||
# The number of drawable pixels per virtual pixel.
|
||||
cdef public object draw_per_virt
|
||||
|
||||
# Matrices that transform drawable to virtual, and vice versa.
|
||||
cdef public Matrix virt_to_draw
|
||||
cdef public Matrix draw_to_virt
|
||||
|
||||
cdef public int fast_redraw_frames
|
||||
|
||||
cpdef set_clip(GLDraw self, tuple clip)
|
||||
|
||||
cpdef int draw_render_textures(
|
||||
GLDraw self,
|
||||
object what,
|
||||
bint non_aligned) except 1
|
||||
|
||||
cpdef int draw_transformed(
|
||||
GLDraw self,
|
||||
object what,
|
||||
tuple clip,
|
||||
double xo,
|
||||
double yo,
|
||||
double alpha,
|
||||
double over,
|
||||
Matrix reverse,
|
||||
bint nearest,
|
||||
bint subpixel) except 1
|
||||
|
||||
cdef class Environ:
|
||||
cdef void blit(self)
|
||||
cdef void blend(self, double fraction)
|
||||
cdef void imageblend(self, double fraction, int ramp)
|
||||
cdef void set_vertex(self, float *vertices)
|
||||
cdef void set_texture(self, int unit, float *coords)
|
||||
cdef void set_color(self, float r, float g, float b, float a)
|
||||
cdef void set_clip(self, tuple clip_box, GLDraw draw)
|
||||
cdef void unset_clip(self, GLDraw draw)
|
||||
cdef void ortho(self, double left, double right, double bottom, double top, double near, double far)
|
||||
cdef void viewport(self, int x, int y, int width, int height)
|
||||
|
||||
-1417
File diff suppressed because it is too large
Load Diff
@@ -1,671 +0,0 @@
|
||||
#cython: profile=False
|
||||
# Copyright 2004-2024 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from renpy.uguu.gl cimport *
|
||||
from renpy.gl.gldraw cimport *
|
||||
|
||||
cdef int round(double d):
|
||||
return <int> (d + .5)
|
||||
|
||||
|
||||
GLES_PORTABILITY = """\
|
||||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
# else
|
||||
precision mediump float;
|
||||
# endif
|
||||
#endif
|
||||
"""
|
||||
|
||||
VERTEX_SHADER1 = GLES_PORTABILITY + """\
|
||||
uniform mat4 Projection;
|
||||
|
||||
attribute vec4 Vertex;
|
||||
attribute vec2 VertexTexCoord0;
|
||||
|
||||
varying vec2 TexCoord0;
|
||||
|
||||
varying vec2 pos;
|
||||
|
||||
void main() {
|
||||
TexCoord0 = VertexTexCoord0;
|
||||
|
||||
pos = Vertex.xy;
|
||||
gl_Position = Projection * Vertex;
|
||||
}
|
||||
"""
|
||||
|
||||
VERTEX_SHADER2 = GLES_PORTABILITY + """\
|
||||
uniform mat4 Projection;
|
||||
|
||||
attribute vec4 Vertex;
|
||||
attribute vec2 VertexTexCoord0;
|
||||
attribute vec2 VertexTexCoord1;
|
||||
|
||||
varying vec2 TexCoord0;
|
||||
varying vec2 TexCoord1;
|
||||
|
||||
varying vec2 pos;
|
||||
|
||||
void main() {
|
||||
TexCoord0 = VertexTexCoord0;
|
||||
TexCoord1 = VertexTexCoord1;
|
||||
|
||||
pos = Vertex.xy;
|
||||
gl_Position = Projection * Vertex;
|
||||
}
|
||||
"""
|
||||
|
||||
VERTEX_SHADER3 = GLES_PORTABILITY + """\
|
||||
uniform mat4 Projection;
|
||||
|
||||
attribute vec4 Vertex;
|
||||
attribute vec2 VertexTexCoord0;
|
||||
attribute vec2 VertexTexCoord1;
|
||||
attribute vec2 VertexTexCoord2;
|
||||
|
||||
varying vec2 TexCoord0;
|
||||
varying vec2 TexCoord1;
|
||||
varying vec2 TexCoord2;
|
||||
|
||||
varying vec2 pos;
|
||||
|
||||
void main() {
|
||||
TexCoord0 = VertexTexCoord0;
|
||||
TexCoord1 = VertexTexCoord1;
|
||||
TexCoord2 = VertexTexCoord2;
|
||||
|
||||
pos = Vertex.xy;
|
||||
gl_Position = Projection * Vertex;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
BLIT_SHADER = GLES_PORTABILITY + """\
|
||||
uniform vec4 Color;
|
||||
uniform sampler2D tex0;
|
||||
|
||||
varying vec2 TexCoord0;
|
||||
|
||||
varying vec2 pos;
|
||||
uniform vec2 clip0;
|
||||
uniform vec2 clip1;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color0 = texture2D(tex0, TexCoord0.st);
|
||||
gl_FragColor = color0 * Color;
|
||||
}
|
||||
"""
|
||||
|
||||
BLIT_CLIP_SHADER = GLES_PORTABILITY + """\
|
||||
uniform vec4 Color;
|
||||
uniform sampler2D tex0;
|
||||
|
||||
varying vec2 TexCoord0;
|
||||
|
||||
varying vec2 pos;
|
||||
uniform vec2 clip0;
|
||||
uniform vec2 clip1;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (pos.x < clip0.x || pos.y < clip0.y || pos.x >= clip1.x || pos.y >= clip1.y) {
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 color0 = texture2D(tex0, TexCoord0.st);
|
||||
gl_FragColor = color0 * Color;
|
||||
}
|
||||
"""
|
||||
|
||||
BLEND_SHADER = GLES_PORTABILITY + """\
|
||||
uniform vec4 Color;
|
||||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
uniform float done;
|
||||
|
||||
varying vec2 TexCoord0;
|
||||
varying vec2 TexCoord1;
|
||||
|
||||
varying vec2 pos;
|
||||
uniform vec2 clip0;
|
||||
uniform vec2 clip1;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color0 = texture2D(tex0, TexCoord0.st);
|
||||
vec4 color1 = texture2D(tex1, TexCoord1.st);
|
||||
|
||||
gl_FragColor = mix(color0, color1, done) * Color;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
BLEND_CLIP_SHADER = GLES_PORTABILITY + """\
|
||||
uniform vec4 Color;
|
||||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
uniform float done;
|
||||
|
||||
varying vec2 TexCoord0;
|
||||
varying vec2 TexCoord1;
|
||||
|
||||
varying vec2 pos;
|
||||
uniform vec2 clip0;
|
||||
uniform vec2 clip1;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (pos.x < clip0.x || pos.y < clip0.y || pos.x >= clip1.x || pos.y >= clip1.y) {
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 color0 = texture2D(tex0, TexCoord0.st);
|
||||
vec4 color1 = texture2D(tex1, TexCoord1.st);
|
||||
|
||||
gl_FragColor = mix(color0, color1, done) * Color;
|
||||
}
|
||||
"""
|
||||
|
||||
IMAGEBLEND_SHADER = GLES_PORTABILITY + """\
|
||||
uniform vec4 Color;
|
||||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
uniform float offset;
|
||||
uniform float multiplier;
|
||||
|
||||
varying vec2 TexCoord0;
|
||||
varying vec2 TexCoord1;
|
||||
varying vec2 TexCoord2;
|
||||
|
||||
varying vec2 pos;
|
||||
uniform vec2 clip0;
|
||||
uniform vec2 clip1;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color0 = texture2D(tex0, TexCoord0.st);
|
||||
vec4 color1 = texture2D(tex1, TexCoord1.st);
|
||||
vec4 color2 = texture2D(tex2, TexCoord2.st);
|
||||
|
||||
float a = clamp((color0.a + offset) * multiplier, 0.0, 1.0);
|
||||
|
||||
gl_FragColor = mix(color1, color2, a) * Color;
|
||||
}
|
||||
"""
|
||||
|
||||
IMAGEBLEND_CLIP_SHADER = GLES_PORTABILITY + """\
|
||||
uniform vec4 Color;
|
||||
uniform sampler2D tex0;
|
||||
uniform sampler2D tex1;
|
||||
uniform sampler2D tex2;
|
||||
uniform float offset;
|
||||
uniform float multiplier;
|
||||
|
||||
varying vec2 TexCoord0;
|
||||
varying vec2 TexCoord1;
|
||||
varying vec2 TexCoord2;
|
||||
|
||||
varying vec2 pos;
|
||||
uniform vec2 clip0;
|
||||
uniform vec2 clip1;
|
||||
|
||||
void main()
|
||||
{
|
||||
if (pos.x < clip0.x || pos.y < clip0.y || pos.x >= clip1.x || pos.y >= clip1.y) {
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 color0 = texture2D(tex0, TexCoord0.st);
|
||||
vec4 color1 = texture2D(tex1, TexCoord1.st);
|
||||
vec4 color2 = texture2D(tex2, TexCoord2.st);
|
||||
|
||||
float a = clamp((color0.a + offset) * multiplier, 0.0, 1.0);
|
||||
|
||||
gl_FragColor = mix(color1, color2, a) * Color;
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
def check_status(shader, handle, type):
|
||||
"""
|
||||
Checks the status of a shader or program. If it fails, then an
|
||||
exception is raised.
|
||||
"""
|
||||
|
||||
cdef GLint status = 0
|
||||
cdef GLint log_length = 0
|
||||
|
||||
if shader:
|
||||
glGetShaderiv(handle, type, &status)
|
||||
else:
|
||||
glGetProgramiv(handle, type, &status)
|
||||
|
||||
if status == 1: # 0 for problems.
|
||||
return
|
||||
|
||||
if shader:
|
||||
glGetShaderiv(handle, GL_INFO_LOG_LENGTH, &log_length)
|
||||
else:
|
||||
glGetProgramiv(handle, GL_INFO_LOG_LENGTH, &log_length)
|
||||
|
||||
log = ' ' * log_length
|
||||
|
||||
if shader:
|
||||
glGetShaderInfoLog(handle, log_length, &log_length, <char *> log)
|
||||
else:
|
||||
glGetProgramInfoLog(handle, log_length, &log_length, <char *> log)
|
||||
|
||||
raise Exception("Shader error: %s" % log)
|
||||
|
||||
|
||||
def compile_shader(kind, source):
|
||||
"""
|
||||
Allocates and compiles a shader.
|
||||
"""
|
||||
|
||||
source = source.encode("utf-8")
|
||||
|
||||
cdef char *sourceptr = <char *> source
|
||||
cdef int lensource = len(source)
|
||||
|
||||
handle = glCreateShader(kind)
|
||||
glShaderSource(handle, 1, <const GLchar * const *> &sourceptr, &lensource)
|
||||
glCompileShader(handle)
|
||||
|
||||
check_status(True, handle, GL_COMPILE_STATUS)
|
||||
|
||||
return handle
|
||||
|
||||
|
||||
def compile_program(vertex, fragment):
|
||||
"""
|
||||
Compiles a pair of shaders into a program.
|
||||
"""
|
||||
|
||||
vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex)
|
||||
fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment)
|
||||
|
||||
program = glCreateProgram()
|
||||
|
||||
glAttachShader(program, vertex_shader)
|
||||
glAttachShader(program, fragment_shader)
|
||||
|
||||
glLinkProgram(program)
|
||||
|
||||
check_status(False, program, GL_LINK_STATUS)
|
||||
|
||||
glUseProgram(program)
|
||||
|
||||
glDeleteShader(vertex_shader)
|
||||
glDeleteShader(fragment_shader)
|
||||
|
||||
return program
|
||||
|
||||
cdef class Program(object):
|
||||
"""
|
||||
Encapsulates a program.
|
||||
"""
|
||||
|
||||
cdef GLuint program
|
||||
|
||||
# Attributes.
|
||||
cdef GLint Vertex
|
||||
cdef GLint VertexTexCoord0
|
||||
cdef GLint VertexTexCoord1
|
||||
cdef GLint VertexTexCoord2
|
||||
|
||||
# Uniforms.
|
||||
cdef GLint Projection
|
||||
cdef GLint Color
|
||||
|
||||
cdef GLint tex0
|
||||
cdef GLint tex1
|
||||
cdef GLint tex2
|
||||
|
||||
cdef GLint clip0
|
||||
cdef GLint clip1
|
||||
|
||||
cdef GLint offset
|
||||
cdef GLint multiplier
|
||||
cdef GLint done
|
||||
|
||||
def __init__(self, vertex, fragment):
|
||||
self.program = compile_program(vertex, fragment)
|
||||
|
||||
self.Vertex = glGetAttribLocation(self.program, "Vertex")
|
||||
self.VertexTexCoord0 = glGetAttribLocation(self.program, "VertexTexCoord0")
|
||||
self.VertexTexCoord1 = glGetAttribLocation(self.program, "VertexTexCoord1")
|
||||
self.VertexTexCoord2 = glGetAttribLocation(self.program, "VertexTexCoord2")
|
||||
|
||||
self.Projection = glGetUniformLocation(self.program, "Projection")
|
||||
self.tex0 = glGetUniformLocation(self.program, "tex0")
|
||||
self.tex1 = glGetUniformLocation(self.program, "tex1")
|
||||
self.tex2 = glGetUniformLocation(self.program, "tex2")
|
||||
self.offset = glGetUniformLocation(self.program, "offset")
|
||||
self.multiplier = glGetUniformLocation(self.program, "multiplier")
|
||||
self.done = glGetUniformLocation(self.program, "done")
|
||||
self.Color = glGetUniformLocation(self.program, "Color")
|
||||
self.clip0 = glGetUniformLocation(self.program, "clip0")
|
||||
self.clip1 = glGetUniformLocation(self.program, "clip1")
|
||||
|
||||
def disable_attribs(self):
|
||||
# Disable the vertex attributes used by this program.
|
||||
|
||||
if self.Vertex != -1:
|
||||
glDisableVertexAttribArray(self.Vertex)
|
||||
|
||||
if self.VertexTexCoord0 != -1:
|
||||
glDisableVertexAttribArray(self.VertexTexCoord0)
|
||||
|
||||
if self.VertexTexCoord1 != -1:
|
||||
glDisableVertexAttribArray(self.VertexTexCoord1)
|
||||
|
||||
if self.VertexTexCoord2 != -1:
|
||||
glDisableVertexAttribArray(self.VertexTexCoord2)
|
||||
|
||||
def delete(self):
|
||||
glDeleteProgram(self.program)
|
||||
|
||||
|
||||
cdef class ShaderEnviron(Environ):
|
||||
"""
|
||||
This is an environment that uses shaders.
|
||||
"""
|
||||
|
||||
cdef Program program
|
||||
cdef float projection[16]
|
||||
|
||||
cdef Program blit_program
|
||||
cdef Program blend_program
|
||||
cdef Program imageblend_program
|
||||
|
||||
cdef Program blit_clip_program
|
||||
cdef Program blend_clip_program
|
||||
cdef Program imageblend_clip_program
|
||||
|
||||
cdef bint clipping
|
||||
cdef double clip_x0
|
||||
cdef double clip_y0
|
||||
cdef double clip_x1
|
||||
cdef double clip_y1
|
||||
|
||||
cdef int viewport_x
|
||||
cdef int viewport_y
|
||||
cdef int viewport_w
|
||||
cdef int viewport_h
|
||||
|
||||
|
||||
def init(self):
|
||||
|
||||
self.blit_program = Program(VERTEX_SHADER1, BLIT_SHADER)
|
||||
self.blit_clip_program = Program(VERTEX_SHADER1, BLIT_CLIP_SHADER)
|
||||
|
||||
self.blend_program = Program(VERTEX_SHADER2, BLEND_SHADER)
|
||||
self.blend_clip_program = Program(VERTEX_SHADER2, BLEND_CLIP_SHADER)
|
||||
|
||||
self.imageblend_program = Program(VERTEX_SHADER3, IMAGEBLEND_SHADER)
|
||||
self.imageblend_clip_program = Program(VERTEX_SHADER3, IMAGEBLEND_CLIP_SHADER)
|
||||
|
||||
# The current program.
|
||||
self.program = None
|
||||
|
||||
def deinit(self):
|
||||
"""
|
||||
Called before changing the GL context.
|
||||
"""
|
||||
|
||||
if self.program is not None:
|
||||
self.program.disable_attribs()
|
||||
self.program = None
|
||||
|
||||
self.blit_program.delete()
|
||||
self.blend_program.delete()
|
||||
self.imageblend_program.delete()
|
||||
|
||||
def activate(self, Program program):
|
||||
|
||||
if self.program is not None:
|
||||
self.program.disable_attribs()
|
||||
|
||||
self.program = program
|
||||
|
||||
glUseProgram(program.program)
|
||||
glUniformMatrix4fv(program.Projection, 1, GL_FALSE, self.projection)
|
||||
|
||||
if self.clipping:
|
||||
glUniform2f(program.clip0, self.clip_x0 - .01, self.clip_y0 - .01)
|
||||
glUniform2f(program.clip1, self.clip_x1 + .01, self.clip_y1 + .01)
|
||||
|
||||
cdef void blit(self):
|
||||
|
||||
if self.clipping:
|
||||
program = self.blit_clip_program
|
||||
else:
|
||||
program = self.blit_program
|
||||
|
||||
if self.program is not program:
|
||||
self.activate(program)
|
||||
glUniform1i(program.tex0, 0)
|
||||
|
||||
cdef void blend(self, double fraction):
|
||||
if self.clipping:
|
||||
program = self.blend_clip_program
|
||||
else:
|
||||
program = self.blend_program
|
||||
|
||||
if self.program is not program:
|
||||
self.activate(program)
|
||||
glUniform1i(program.tex0, 0)
|
||||
glUniform1i(program.tex1, 1)
|
||||
|
||||
glUniform1f(program.done, fraction)
|
||||
|
||||
cdef void imageblend(self, double fraction, int ramp):
|
||||
|
||||
if self.clipping:
|
||||
program = self.imageblend_clip_program
|
||||
else:
|
||||
program = self.imageblend_program
|
||||
|
||||
if self.program is not program:
|
||||
self.activate(program)
|
||||
glUniform1i(program.tex0, 0)
|
||||
glUniform1i(program.tex1, 1)
|
||||
glUniform1i(program.tex2, 2)
|
||||
|
||||
# Prevent a DBZ if the user gives us a 0 ramp.
|
||||
if ramp < 1:
|
||||
ramp = 1
|
||||
|
||||
# Compute the offset to apply to the alpha.
|
||||
start = -1.0
|
||||
end = ramp / 256.0
|
||||
offset = start + ( end - start) * fraction
|
||||
|
||||
# Setup the multiplier and the offset.
|
||||
glUniform1f(program.multiplier, 256.0 / ramp)
|
||||
glUniform1f(program.offset, offset)
|
||||
|
||||
cdef void set_vertex(self, float *vertices):
|
||||
glEnableVertexAttribArray(self.program.Vertex)
|
||||
glVertexAttribPointer(self.program.Vertex, 2, GL_FLOAT, GL_FALSE, 0, <GLubyte *> vertices)
|
||||
|
||||
cdef void set_texture(self, int unit, float *coords):
|
||||
cdef tex
|
||||
|
||||
if unit == 0:
|
||||
tex = self.program.VertexTexCoord0
|
||||
elif unit == 1:
|
||||
tex = self.program.VertexTexCoord1
|
||||
elif unit == 2:
|
||||
tex = self.program.VertexTexCoord2
|
||||
else:
|
||||
return
|
||||
|
||||
if tex < 0:
|
||||
return
|
||||
|
||||
if coords != NULL:
|
||||
glVertexAttribPointer(tex, 2, GL_FLOAT, GL_FALSE, 0, <GLubyte *> coords)
|
||||
glEnableVertexAttribArray(tex)
|
||||
else:
|
||||
glDisableVertexAttribArray(tex)
|
||||
|
||||
cdef void set_color(self, float r, float g, float b, float a):
|
||||
glUniform4f(self.program.Color, r, g, b, a)
|
||||
|
||||
cdef void ortho(self, double left, double right, double bottom, double top, double near, double far):
|
||||
|
||||
self.projection[ 0] = 2 / (right - left)
|
||||
self.projection[ 4] = 0
|
||||
self.projection[ 8] = 0
|
||||
self.projection[12] = -(right + left) / (right - left)
|
||||
|
||||
self.projection[ 1] = 0
|
||||
self.projection[ 5] = 2 / (top - bottom)
|
||||
self.projection[ 9] = 0
|
||||
self.projection[13] = -(top + bottom) / (top - bottom)
|
||||
|
||||
self.projection[ 2] = 0
|
||||
self.projection[ 6] = 0
|
||||
self.projection[10] = -2 / (far - near)
|
||||
self.projection[14] = -(far + near) / (far - near)
|
||||
|
||||
self.projection[ 3] = 0
|
||||
self.projection[ 7] = 0
|
||||
self.projection[11] = 0
|
||||
self.projection[15] = 1
|
||||
|
||||
if self.program is not None:
|
||||
self.program.disable_attribs()
|
||||
|
||||
self.program = None
|
||||
|
||||
cdef void project(self, x, y, z, double *rv_x, double *rv_y, double *rv_z):
|
||||
"""
|
||||
Given a point, projects it using the projection.
|
||||
"""
|
||||
|
||||
rv_x[0] = x * self.projection[0] + y * self.projection[4] + z * self.projection[8] + self.projection[12]
|
||||
rv_y[0] = x * self.projection[1] + y * self.projection[5] + z * self.projection[9] + self.projection[13]
|
||||
rv_z[0] = x * self.projection[2] + y * self.projection[6] + z * self.projection[10] + self.projection[14]
|
||||
|
||||
cdef void set_clip(self, tuple clip_box, GLDraw draw):
|
||||
|
||||
cdef double minx, miny, maxx, maxy, z
|
||||
cdef double vwidth, vheight
|
||||
cdef double px, py, pw, ph
|
||||
cdef int cx, cy, cw, ch
|
||||
cdef int psw, psh
|
||||
|
||||
if clip_box == draw.default_clip:
|
||||
self.unset_clip(draw)
|
||||
return
|
||||
|
||||
minx, miny, maxx, maxy = clip_box
|
||||
psw, psh = draw.physical_size
|
||||
|
||||
# The clipping box.
|
||||
self.clipping = True
|
||||
self.clip_x0 = minx
|
||||
self.clip_y0 = miny
|
||||
self.clip_x1 = maxx
|
||||
self.clip_y1 = maxy
|
||||
|
||||
# Set the scissor rectangle to be slightly larger than the
|
||||
# clipping box. This ensures everything that needs to be drawn
|
||||
# is drawn, and we don't spend a lot of time shading clipped
|
||||
# fragments.
|
||||
|
||||
if draw.clip_rtt_box is None:
|
||||
|
||||
z = 0
|
||||
|
||||
# Project to normalized coordinates.
|
||||
self.project(minx, miny, z, &minx, &miny, &z)
|
||||
self.project(maxx, maxy, z, &maxx, &maxy, &z)
|
||||
|
||||
# Convert to window coordinates.
|
||||
minx = (minx + 1) * self.viewport_w / 2 + self.viewport_x
|
||||
maxx = (maxx + 1) * self.viewport_w / 2 + self.viewport_x
|
||||
miny = (miny + 1) * self.viewport_h / 2 + self.viewport_y
|
||||
maxy = (maxy + 1) * self.viewport_h / 2 + self.viewport_y
|
||||
|
||||
# Increase the bounding box, to ensure every relevant pixel is
|
||||
# in it. The shader will take care of enforcing the actual box.
|
||||
minx -= 1
|
||||
maxx += 1
|
||||
miny += 1
|
||||
maxy -= 1
|
||||
|
||||
if minx < 0:
|
||||
minx = 0
|
||||
if miny < 0:
|
||||
miny = 0
|
||||
|
||||
glEnable(GL_SCISSOR_TEST)
|
||||
glScissor(<GLint> round(minx), <GLint> round(maxy), <GLint> round(maxx - minx), <GLsizei> round(miny - maxy))
|
||||
|
||||
else:
|
||||
|
||||
cx, cy, cw, ch = draw.clip_rtt_box
|
||||
|
||||
glEnable(GL_SCISSOR_TEST)
|
||||
glScissor(<GLint> round(minx - cx), <GLint> round(miny - cy), <GLint> round(maxx - minx), <GLint> round(maxy - miny))
|
||||
|
||||
if self.program is not None:
|
||||
self.program.disable_attribs()
|
||||
|
||||
self.program = None
|
||||
|
||||
cdef void unset_clip(self, GLDraw draw):
|
||||
|
||||
glDisable(GL_SCISSOR_TEST)
|
||||
|
||||
self.clipping = False
|
||||
self.clip_x0 = 0
|
||||
self.clip_y0 = 0
|
||||
self.clip_x1 = 65535
|
||||
self.clip_y1 = 65535
|
||||
|
||||
if self.program is not None:
|
||||
self.program.disable_attribs()
|
||||
|
||||
self.program = None
|
||||
|
||||
cdef void viewport(self, int x, int y, int width, int height):
|
||||
glViewport(x, y, width, height)
|
||||
self.viewport_x = x
|
||||
self.viewport_y = y
|
||||
self.viewport_w = width
|
||||
self.viewport_h = height
|
||||
@@ -1,59 +0,0 @@
|
||||
# This file has been automatically generated by module/uguu/generate_required_functions.py,
|
||||
# please do not edit it by hand.
|
||||
|
||||
from __future__ import division, absolute_import, with_statement, print_function, unicode_literals
|
||||
from renpy.compat import PY2, basestring, bchr, bord, chr, open, pystr, range, round, str, tobytes, unicode # *
|
||||
|
||||
|
||||
|
||||
required_functions = [
|
||||
"glActiveTexture",
|
||||
"glAttachShader",
|
||||
"glBindFramebuffer",
|
||||
"glBindTexture",
|
||||
"glBlendFunc",
|
||||
"glClear",
|
||||
"glClearColor",
|
||||
"glCompileShader",
|
||||
"glCopyTexImage2D",
|
||||
"glCopyTexSubImage2D",
|
||||
"glCreateProgram",
|
||||
"glCreateShader",
|
||||
"glDeleteFramebuffers",
|
||||
"glDeleteProgram",
|
||||
"glDeleteShader",
|
||||
"glDeleteTextures",
|
||||
"glDisable",
|
||||
"glDisableVertexAttribArray",
|
||||
"glDrawArrays",
|
||||
"glEnable",
|
||||
"glEnableVertexAttribArray",
|
||||
"glFinish",
|
||||
"glFramebufferTexture2D",
|
||||
"glGenFramebuffers",
|
||||
"glGenTextures",
|
||||
"glGetAttribLocation",
|
||||
"glGetError",
|
||||
"glGetIntegerv",
|
||||
"glGetProgramInfoLog",
|
||||
"glGetProgramiv",
|
||||
"glGetShaderInfoLog",
|
||||
"glGetShaderiv",
|
||||
"glGetString",
|
||||
"glGetUniformLocation",
|
||||
"glLinkProgram",
|
||||
"glReadPixels",
|
||||
"glScissor",
|
||||
"glShaderSource",
|
||||
"glTexImage2D",
|
||||
"glTexParameteri",
|
||||
"glTexSubImage2D",
|
||||
"glUniform1f",
|
||||
"glUniform1i",
|
||||
"glUniform2f",
|
||||
"glUniform4f",
|
||||
"glUniformMatrix4fv",
|
||||
"glUseProgram",
|
||||
"glVertexAttribPointer",
|
||||
"glViewport",
|
||||
]
|
||||
@@ -1,72 +0,0 @@
|
||||
#@PydevCodeAnalysisIgnore
|
||||
#cython: profile=False
|
||||
# Copyright 2004-2024 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from renpy.uguu.gl cimport *
|
||||
from renpy.gl.gldraw cimport *
|
||||
from renpy.gl.gldraw import Rtt
|
||||
|
||||
class CopyRtt(Rtt):
|
||||
"""
|
||||
This class uses texture copying to implement Render-to-texture.
|
||||
"""
|
||||
|
||||
def init(self):
|
||||
return
|
||||
|
||||
def deinit(self):
|
||||
return
|
||||
|
||||
def render(self, Environ environ, texture, x, y, w, h, draw_func):
|
||||
"""
|
||||
This function is called to trigger a rendering to a texture.
|
||||
`x`, `y`, `w`, and `h` specify the location and dimensions of
|
||||
the sub-image to render to the texture. `draw_func` is called
|
||||
to render the texture.
|
||||
"""
|
||||
|
||||
environ.viewport(0, 0, w, h)
|
||||
environ.ortho(x, x + w, y, y + h, -1, 1)
|
||||
|
||||
draw_func(x, y, w, h)
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture)
|
||||
|
||||
glCopyTexSubImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
w,
|
||||
h)
|
||||
|
||||
def end(self):
|
||||
"""
|
||||
This is called when a Render-to-texture session ends.
|
||||
"""
|
||||
|
||||
def get_size_limit(self, dimension):
|
||||
return dimension
|
||||
@@ -1,115 +0,0 @@
|
||||
#@PydevCodeAnalysisIgnore
|
||||
#cython: profile=False
|
||||
# Copyright 2004-2024 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
from renpy.uguu.gl cimport *
|
||||
from renpy.gl.gldraw cimport *
|
||||
from renpy.gl.gldraw import Rtt
|
||||
|
||||
import renpy
|
||||
|
||||
# The framebuffer object we use.
|
||||
cdef GLuint fbo
|
||||
|
||||
# The root framebuffer.
|
||||
cdef GLint root_fbo
|
||||
|
||||
# The renderbuffer object we use.
|
||||
cdef GLuint texture
|
||||
|
||||
class FboRtt(Rtt):
|
||||
"""
|
||||
This class uses texture copying to implement Render-to-texture.
|
||||
"""
|
||||
|
||||
def init(self):
|
||||
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &root_fbo);
|
||||
renpy.display.log.write("Root FBO is: %d", root_fbo)
|
||||
|
||||
glGenFramebuffers(1, &fbo)
|
||||
glGenTextures(1, &texture)
|
||||
|
||||
cdef int i
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &i)
|
||||
self.size_limit = min(i, 2048)
|
||||
renpy.display.log.write("FBO Maximum Texture Size: %d", self.size_limit)
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, self.size_limit, self.size_limit, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo)
|
||||
glFramebufferTexture2D(
|
||||
GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
GL_TEXTURE_2D,
|
||||
texture,
|
||||
0)
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, root_fbo)
|
||||
|
||||
|
||||
def deinit(self):
|
||||
"""
|
||||
Called before changing the GL context.
|
||||
"""
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, root_fbo)
|
||||
glDeleteFramebuffers(1, &fbo)
|
||||
glDeleteTextures(1, &texture)
|
||||
|
||||
def begin(self):
|
||||
"""
|
||||
This function should be called when a Render-to-texture
|
||||
session begins. It's responsible for setting the GPU to
|
||||
RTT mode.
|
||||
"""
|
||||
|
||||
def render(self, Environ environ, texture, x, y, w, h, draw_func):
|
||||
"""
|
||||
This function is called to trigger a rendering to a texture.
|
||||
`x`, `y`, `w`, and `h` specify the location and dimensions of
|
||||
the sub-image to render to the texture. `draw_func` is called
|
||||
to render the texture.
|
||||
"""
|
||||
|
||||
try:
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo)
|
||||
|
||||
environ.viewport(0, 0, w, h)
|
||||
environ.ortho(x, x + w, y, y + h, -1, 1)
|
||||
|
||||
draw_func(x, y, w, h)
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, texture)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL)
|
||||
glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, w, h, 0)
|
||||
|
||||
finally:
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, root_fbo)
|
||||
|
||||
|
||||
def get_size_limit(self, dimension):
|
||||
return self.size_limit
|
||||
@@ -1,104 +0,0 @@
|
||||
# Copyright 2004-2014 Tom Rothamel <pytom@bishoujo.us>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person
|
||||
# obtaining a copy of this software and associated documentation files
|
||||
# (the "Software"), to deal in the Software without restriction,
|
||||
# including without limitation the rights to use, copy, modify, merge,
|
||||
# publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
# and to permit persons to whom the Software is furnished to do so,
|
||||
# subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be
|
||||
# included in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
from renpy.display.matrix cimport Matrix
|
||||
cimport renpy.display.render as render
|
||||
from renpy.gl.gldraw cimport Environ
|
||||
|
||||
cdef class TextureCore:
|
||||
cdef public int width
|
||||
cdef public int height
|
||||
cdef public int generation
|
||||
cdef public unsigned int number
|
||||
cdef unsigned int format
|
||||
cdef double xmul
|
||||
cdef double xadd
|
||||
cdef double ymul
|
||||
cdef double yadd
|
||||
cdef object premult
|
||||
cdef tuple premult_size
|
||||
cdef int premult_left
|
||||
cdef int premult_right
|
||||
cdef int premult_top
|
||||
cdef int premult_bottom
|
||||
cdef bint nearest
|
||||
cdef public list free_list
|
||||
|
||||
cdef void make_ready(TextureCore)
|
||||
cdef void make_nearest(TextureCore)
|
||||
cdef void make_linear(TextureCore)
|
||||
cpdef int allocate(TextureCore)
|
||||
|
||||
cdef public object debug
|
||||
|
||||
cdef class TextureGrid:
|
||||
|
||||
|
||||
cdef object __weakref__
|
||||
|
||||
cdef public int width
|
||||
cdef public int height
|
||||
cdef list rows
|
||||
cdef list columns
|
||||
cdef list tiles # list of lists.
|
||||
cdef public TextureGrid half_cache
|
||||
|
||||
cpdef void make_ready(self, bint nearest)
|
||||
|
||||
cdef public object debug
|
||||
cdef public bint ready
|
||||
|
||||
|
||||
cpdef blit(
|
||||
TextureGrid tg,
|
||||
double sx,
|
||||
double sy,
|
||||
Matrix transform,
|
||||
double alpha,
|
||||
double over,
|
||||
Environ environ,
|
||||
bint nearest)
|
||||
|
||||
cpdef blend(
|
||||
TextureGrid tg0,
|
||||
TextureGrid tg1,
|
||||
double sx,
|
||||
double sy,
|
||||
Matrix transform,
|
||||
double alpha,
|
||||
double over,
|
||||
double fraction,
|
||||
Environ environ,
|
||||
bint nearest)
|
||||
|
||||
cpdef imageblend(
|
||||
TextureGrid tg0,
|
||||
TextureGrid tg1,
|
||||
TextureGrid tg2,
|
||||
double sx,
|
||||
double sy,
|
||||
Matrix transform,
|
||||
double alpha,
|
||||
double over,
|
||||
double fraction,
|
||||
int ramp,
|
||||
Environ environ,
|
||||
bint nearest)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -88,9 +88,6 @@ def init():
|
||||
if live2dmodel is None:
|
||||
raise Exception("Live2D has not been built.")
|
||||
|
||||
if not renpy.config.gl2:
|
||||
raise Exception("Live2D requires that config.gl2 be True.")
|
||||
|
||||
if renpy.emscripten:
|
||||
raise Exception("Live2D is not supported the web platform.")
|
||||
|
||||
|
||||
+1
-2
@@ -2,5 +2,4 @@
|
||||
|
||||
cd $(dirname $(dirname $(readlink -f $0)))
|
||||
|
||||
nice lib/py2-linux-x86_64/python add.py --real "$@"
|
||||
nice lib/py3-linux-x86_64/python add.py --real "$@"
|
||||
lib/py3-linux-x86_64/python add.py --real "$@"
|
||||
|
||||
@@ -16,7 +16,5 @@ sleep 2
|
||||
|
||||
rpy pull
|
||||
rpy build --python 3
|
||||
rpy build --python 2
|
||||
|
||||
lib/py3-linux-x86_64/python distribute.py
|
||||
lib/py2-linux-x86_64/python distribute.py
|
||||
|
||||
+294
-62
@@ -1,5 +1,6 @@
|
||||
from __future__ import print_function, unicode_literals
|
||||
from __future__ import print_function, unicode_literals, annotations
|
||||
|
||||
import ast
|
||||
import inspect
|
||||
import re
|
||||
import collections
|
||||
@@ -10,11 +11,14 @@ import io
|
||||
import os
|
||||
import textwrap
|
||||
import pprint
|
||||
import types
|
||||
|
||||
from typing import Any, Iterable, Literal
|
||||
|
||||
try:
|
||||
import builtins
|
||||
except ImportError:
|
||||
import __builtin__ as builtins
|
||||
import __builtin__ as builtins # type: ignore
|
||||
|
||||
# Additional keywords in the Ren'Py script language.
|
||||
SCRIPT_KEYWORDS = """\
|
||||
@@ -203,20 +207,17 @@ def write_keywords(srcdir='source'):
|
||||
|
||||
# A map from filename to a list of lines that are supposed to go into
|
||||
# that file.
|
||||
line_buffer = collections.defaultdict(list)
|
||||
line_buffer = collections.defaultdict[str, list[str]](list)
|
||||
|
||||
# A map from id(o) to the names it's documented under.
|
||||
documented = collections.defaultdict(list)
|
||||
|
||||
# This keeps all objectsd we see alive, to prevent duplicates in documented.
|
||||
documented_list = [ ]
|
||||
documented = collections.defaultdict[int, list[str]](list)
|
||||
|
||||
def getdoc(o):
|
||||
"""
|
||||
Returns the docstring for `o`, but unlike inspect.getdoc, does not get
|
||||
values from base classes if absent (and it's faster too).
|
||||
Will still get the inherited docstring for a non-overridden method in a
|
||||
subclass (because the method object is the same as the base classe's).
|
||||
subclass (because the method object is the same as the base classes).
|
||||
"""
|
||||
|
||||
doc = getattr(o, "__doc__", None)
|
||||
@@ -229,23 +230,189 @@ def getdoc(o):
|
||||
# The docstring for object.__init__ - which we don't want to pass for one of our classes's
|
||||
objinidoc = getdoc(object.__init__)
|
||||
|
||||
_file_trees: dict[str, ast.Module] = {}
|
||||
|
||||
def scan(name, o, prefix="", inclass=False):
|
||||
def scan_pep224(prefix: str, o_name: str | None, o: type | types.ModuleType, /):
|
||||
"""
|
||||
Scan for PEP-224 docstrings for variables of `o` (either a module or class).
|
||||
For classes also scans its __init__ method.
|
||||
|
||||
Documented variables are then scanned for Sphinx docstrings and added to the
|
||||
line buffer.
|
||||
"""
|
||||
|
||||
if isinstance(o, types.ModuleType):
|
||||
# No variables in namespace packages.
|
||||
if o.__spec__.origin is None:
|
||||
return
|
||||
|
||||
module_name = o.__name__
|
||||
|
||||
elif isinstance(o, type):
|
||||
module_name = o.__module__
|
||||
|
||||
if inspect.isclass(o):
|
||||
if issubclass(o, (renpy.store.Action,
|
||||
renpy.store.BarValue,
|
||||
renpy.store.InputValue)):
|
||||
doc_type = "function"
|
||||
else:
|
||||
doc_type = "class"
|
||||
elif inclass:
|
||||
doc_type = "method"
|
||||
else:
|
||||
doc_type = "function"
|
||||
raise TypeError(f"Expected a class or module, got {o!r}")
|
||||
|
||||
# The section it's going into.
|
||||
section = None
|
||||
fn = inspect.getfile(o)
|
||||
|
||||
# Can't read Cython files.
|
||||
if fn == "built-in":
|
||||
return
|
||||
|
||||
# No source for Ren'Py store modules.
|
||||
if module_name in renpy.python.store_modules:
|
||||
return
|
||||
|
||||
if fn in _file_trees:
|
||||
tree = _file_trees[fn]
|
||||
else:
|
||||
try:
|
||||
# Maybe raise exceptions with appropriate message
|
||||
# before using cleaned doc_obj.source
|
||||
source, _ = inspect.findsource(o)
|
||||
tree = ast.parse("".join(source), fn)
|
||||
|
||||
except (OSError, TypeError, SyntaxError) as exc:
|
||||
print(f"Warning: couldn't read PEP-224 variable docstrings from {o!r}: {exc}")
|
||||
return
|
||||
|
||||
_file_trees[fn] = tree
|
||||
|
||||
def scan(tree: ast.AST, in_init_func: bool):
|
||||
from itertools import tee
|
||||
a, b = \
|
||||
tee(ast.iter_child_nodes(tree))
|
||||
|
||||
next(b, None)
|
||||
|
||||
for assign_node, str_node in zip(a, b):
|
||||
if not (isinstance(str_node, ast.Expr) and
|
||||
isinstance(str_node.value, ast.Constant) and
|
||||
isinstance(str_node.value.value, str)):
|
||||
continue
|
||||
|
||||
if isinstance(assign_node, ast.Assign) and len(assign_node.targets) == 1:
|
||||
target = assign_node.targets[0]
|
||||
|
||||
elif isinstance(assign_node, ast.AnnAssign):
|
||||
target = assign_node.target
|
||||
else:
|
||||
continue
|
||||
|
||||
if (not in_init_func) and isinstance(target, ast.Name):
|
||||
name = target.id
|
||||
elif (in_init_func and
|
||||
isinstance(target, ast.Attribute) and
|
||||
isinstance(target.value, ast.Name) and
|
||||
target.value.id == 'self'):
|
||||
name = target.attr
|
||||
else:
|
||||
continue
|
||||
|
||||
docstring = inspect.cleandoc(str_node.value.value)
|
||||
if not docstring:
|
||||
continue
|
||||
|
||||
default = None
|
||||
if assign_node.value is not None:
|
||||
try:
|
||||
default = ast.unparse(assign_node.value)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if o_name is not None:
|
||||
name = f"{o_name}{name}"
|
||||
|
||||
vars[name] = docstring, default
|
||||
|
||||
return vars
|
||||
|
||||
vars: dict[str, tuple[str, str | None]] = {}
|
||||
|
||||
if isinstance(o, types.ModuleType):
|
||||
default_doc_type = "var"
|
||||
scan(tree, False)
|
||||
|
||||
elif isinstance(o, type):
|
||||
default_doc_type = "attribute"
|
||||
|
||||
class ClassFoundException(Exception):
|
||||
def __init__(self, class_def: ast.ClassDef):
|
||||
self.class_def = class_def
|
||||
|
||||
class ClassFinder(ast.NodeVisitor):
|
||||
def __init__(self):
|
||||
self.stack = []
|
||||
|
||||
def visit_FunctionDef(self, node):
|
||||
self.stack.append(node.name)
|
||||
self.stack.append('<locals>')
|
||||
self.generic_visit(node)
|
||||
self.stack.pop()
|
||||
self.stack.pop()
|
||||
|
||||
visit_AsyncFunctionDef = visit_FunctionDef # type: ignore
|
||||
|
||||
def visit_ClassDef(self, node):
|
||||
self.stack.append(node.name)
|
||||
if o.__qualname__ == '.'.join(self.stack):
|
||||
raise ClassFoundException(node)
|
||||
self.generic_visit(node)
|
||||
self.stack.pop()
|
||||
|
||||
try:
|
||||
ClassFinder().visit(tree)
|
||||
except ClassFoundException as e:
|
||||
scan(e.class_def, False)
|
||||
|
||||
# For classes add instance variables defined in __init__
|
||||
# Get the *last* __init__ node in case it is preceded by @overloads.
|
||||
for node in reversed(e.class_def.body):
|
||||
if isinstance(node, ast.FunctionDef) and node.name == '__init__':
|
||||
scan(node, True)
|
||||
break
|
||||
else:
|
||||
print(f"Warning: couldn't find class {o.__qualname__} in {fn}")
|
||||
return
|
||||
|
||||
for name, (docstring, default) in vars.items():
|
||||
(
|
||||
lines,
|
||||
doc_type,
|
||||
section,
|
||||
name,
|
||||
explicit_default,
|
||||
) = inspect_doc(name, docstring, default)
|
||||
|
||||
if section is None:
|
||||
continue
|
||||
|
||||
if doc_type is None:
|
||||
doc_type = default_doc_type
|
||||
|
||||
if explicit_default is not None:
|
||||
default = explicit_default
|
||||
|
||||
if default is None:
|
||||
default = "..."
|
||||
|
||||
# Put it into the line buffer.
|
||||
lb = line_buffer[section]
|
||||
|
||||
lb.append(f"{prefix}.. {doc_type}:: {name} = {default}")
|
||||
|
||||
for l in lines:
|
||||
lb.append(f"{prefix} {l}")
|
||||
|
||||
lb.append(prefix)
|
||||
|
||||
|
||||
def scan(name: str, o: Any, prefix="", inclass=False):
|
||||
"""
|
||||
Given an object `o`, scans it for sphinx doc string and adds it to the
|
||||
line buffer and list of documented objects.
|
||||
"""
|
||||
|
||||
# The formatted arguments.
|
||||
args = None
|
||||
@@ -256,52 +423,56 @@ def scan(name, o, prefix="", inclass=False):
|
||||
if not doc:
|
||||
return
|
||||
|
||||
if doc[0] == ' ':
|
||||
print("Bad docstring for ", name, repr(doc))
|
||||
|
||||
# Cython-generated docstrings start with the function and arguments.
|
||||
if re.match(r'[\w\.]+\(', doc):
|
||||
orig = doc
|
||||
|
||||
sig, _, doc = doc.partition("\n\n")
|
||||
doc = textwrap.dedent(doc)
|
||||
|
||||
if "(" in sig:
|
||||
args = "(" + sig.partition("(")[2]
|
||||
|
||||
if not doc:
|
||||
return
|
||||
|
||||
# Break up the doc string, scan it for specials.
|
||||
lines = [ ]
|
||||
|
||||
for l in doc.split("\n"):
|
||||
|
||||
m = re.match(r':doc: *(\w+) *(\w+)?', l)
|
||||
if m:
|
||||
section = m.group(1)
|
||||
|
||||
if m.group(2):
|
||||
doc_type = m.group(2)
|
||||
|
||||
continue
|
||||
|
||||
m = re.match(r':args: *(.*)', l)
|
||||
if m:
|
||||
args = m.group(1)
|
||||
continue
|
||||
|
||||
m = re.match(r':name: *(\S+)', l)
|
||||
if m:
|
||||
if name != m.group(1):
|
||||
return
|
||||
continue
|
||||
|
||||
lines.append(l)
|
||||
(
|
||||
lines,
|
||||
doc_type,
|
||||
section,
|
||||
new_name,
|
||||
explicit_args,
|
||||
) = inspect_doc(name, doc, args)
|
||||
|
||||
if section is None:
|
||||
return
|
||||
|
||||
if args is None:
|
||||
# Don't add documentation via this path.
|
||||
if new_name != name:
|
||||
return
|
||||
|
||||
if inspect.isclass(o):
|
||||
if issubclass(o, (renpy.store.Action,
|
||||
renpy.store.BarValue,
|
||||
renpy.store.InputValue)):
|
||||
o_type = "function"
|
||||
else:
|
||||
o_type = "class"
|
||||
elif inclass:
|
||||
o_type = "method"
|
||||
else:
|
||||
o_type = "function"
|
||||
|
||||
if doc_type is None:
|
||||
doc_type = o_type
|
||||
|
||||
# Forbid to add functions/classes/method as variables.
|
||||
elif doc_type not in ("function", "class", "method"):
|
||||
print(f"Warning: {name} is a {o_type} but documented as {doc_type}.")
|
||||
return
|
||||
|
||||
if explicit_args is not None:
|
||||
args = explicit_args
|
||||
|
||||
if args is None:
|
||||
# Get the arguments.
|
||||
if inspect.isclass(o):
|
||||
init = getattr(o, "__init__", None)
|
||||
@@ -324,16 +495,19 @@ def scan(name, o, prefix="", inclass=False):
|
||||
args = inspect.signature(o)
|
||||
|
||||
else:
|
||||
print("Warning: %s has section but not args." % name)
|
||||
|
||||
print(f"Warning: {name} has section but not args.")
|
||||
return
|
||||
|
||||
# Format the arguments.
|
||||
if args is not None:
|
||||
if args.parameters and next(iter(args.parameters)) == "self":
|
||||
pars = iter(args.parameters.values())
|
||||
# Skip 'self' in methods.
|
||||
pars = iter(args.parameters.values())
|
||||
if "self" in args.parameters:
|
||||
next(pars)
|
||||
args = args.replace(parameters=pars)
|
||||
|
||||
# Strip annotations, at least for now.
|
||||
pars = (p.replace(annotation=p.empty) for p in pars)
|
||||
args = args.replace(parameters=list(pars))
|
||||
|
||||
args = str(args)
|
||||
else:
|
||||
@@ -342,30 +516,88 @@ def scan(name, o, prefix="", inclass=False):
|
||||
# Put it into the line buffer.
|
||||
lb = line_buffer[section]
|
||||
|
||||
lb.append(prefix + ".. %s:: %s%s" % (doc_type, name, args))
|
||||
lb.append(f"{prefix}.. {doc_type}:: {name}{args}")
|
||||
|
||||
for l in lines:
|
||||
lb.append(prefix + " " + l)
|
||||
lb.append(f"{prefix} {l}")
|
||||
|
||||
lb.append(prefix + "")
|
||||
lb.append(prefix)
|
||||
|
||||
if inspect.isclass(o):
|
||||
if (name not in [ "Matrix", "OffsetMatrix", "RotateMatrix", "ScaleMatrix" ]):
|
||||
# Scan for documented attributes in the class first.
|
||||
scan_pep224(prefix + " ", None, o)
|
||||
|
||||
# Then for other classes and methods.
|
||||
for i in dir(o):
|
||||
scan(i, getattr(o, i), prefix + " ", inclass=True)
|
||||
|
||||
if name == "identity":
|
||||
raise Exception("identity")
|
||||
|
||||
documented_list.append(o)
|
||||
documented[id(o)].append(name)
|
||||
|
||||
|
||||
def inspect_doc(name: str, doc: str, args_or_default: str | None):
|
||||
"""
|
||||
Given doc string after cleandoc, search for special lines
|
||||
:doc:, :name: and :args: or :default: in it.
|
||||
|
||||
Return a (doc lines, doc_type, section, name, args or default) tuple.
|
||||
"""
|
||||
|
||||
if doc[0] == ' ':
|
||||
print("Bad docstring for ", name, repr(doc))
|
||||
|
||||
# Break up the doc string, scan it for specials.
|
||||
lines: list[str] = [ ]
|
||||
|
||||
# The section it's going into.
|
||||
section: str | None = None
|
||||
|
||||
# The kind of doc for sphinx.
|
||||
doc_type: str | None = None
|
||||
|
||||
for l in doc.split("\n"):
|
||||
|
||||
m = re.match(r':doc: *(\w+) *(\w+)?', l)
|
||||
if m:
|
||||
section = m.group(1)
|
||||
|
||||
if m.group(2):
|
||||
doc_type = m.group(2)
|
||||
|
||||
continue
|
||||
|
||||
m = re.match(r':args: *(.*)', l)
|
||||
if m:
|
||||
args_or_default = m.group(1)
|
||||
continue
|
||||
|
||||
m = re.match(r':default: *(\S+)', l)
|
||||
if m:
|
||||
args_or_default = m.group(1)
|
||||
continue
|
||||
|
||||
m = re.match(r':name: *(\S+)', l)
|
||||
if m:
|
||||
name = m.group(1)
|
||||
continue
|
||||
|
||||
lines.append(l)
|
||||
|
||||
return lines, doc_type, section, name, args_or_default
|
||||
|
||||
|
||||
def scan_section(name, o):
|
||||
"""
|
||||
Scans object o. Assumes it has the name name.
|
||||
"""
|
||||
|
||||
# For modules also scan for documented variables.
|
||||
if isinstance(o, types.ModuleType):
|
||||
scan_pep224("", name, o)
|
||||
|
||||
for n in dir(o):
|
||||
scan(name + n, getattr(o, n))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user