OpenGL ES 3.0 rendering backend (#148)

* First steps towards shader transpilation

Needs to be manually enabled via -Dshader_transpiler=true.

Requires shaderc. https://github.com/google/shaderc

Not yet functional due to missing SPIRV-Cross integration. SPIRV-Cross
currently does not have an official C API, and crossc is too minimal to
be useful. The current plan is to extend crossc and vendor it, while
also sending PRs upstream.

* Integrate crossc; shader transpilation for GLES now works

* fix leak

* gles30 backend now playable on Mesa with 3.2 context

Some rendering issues are present. Identified so far:
    - Marisa's lasers are invisible
    - Death effect looks wrong

Also, a small pixmap manipulation library has been written, and the
texture uploading API redesigned around it.

* fix marisa lasers in GLES (uniform name clashed with builtin)

* fix player death effect in GLES (another name clash)

* Dump ANGLE's translated shader code in debug log

* fix screenshots

* Drop support for triangle fans, switch to strips

Fans offer no advantage over strips, and they've been removed in D3D10+,
so ANGLE has to emulate them.

* crude workaround for an ANGLE bug

* Re-enable GL debug labels, fix an issue with them that affected ANGLE (but was always technically a bug)

* fix race condition in shaderc initialization

* New SDL_RWops interface for vertex buffers

* Optimize VBO streaming via buffering updates

Measurable performance improvement even with the main gl33 renderer,
drastic improvement with ANGLE.

* Fix the depth texture binding problem under ANGLE

Apparently it hates GL_DEPTH_COMPONENT16 for some reason. Sized internal
formats are not supported in GLES 2.0 anyway, so not using them is
probably a good idea.

* fix GLES2.0 segfault (the backend still doesn't work, though)

* dump GL extensions at info log level, not debug

* get around a Mesa bug; more correct texture format table for GLES2

* Correct GLES3 texture format table according to the spec

Not a Mesa bug after all

* require crossc>=1.5.0, fallback to subproject

* Request at least 8bit per color channel in GL backends

* Forbid lto for static windows builds with shader_transpiler=true

* fix edge case segfault

* Add basic ANGLE bundling support to the build system

Windows only, and no NSIS support yet

* Fix various windows-related build system and installer brokenness

* Disable gles backends by default

* update documentation
This commit is contained in:
Andrei Alexeyev 2018-10-02 01:36:10 +03:00 committed by GitHub
parent 10046ff9c7
commit 2414474c89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
68 changed files with 2364 additions and 1189 deletions

View file

@ -22,7 +22,9 @@ Dependencies
- libpng >= 1.5.0
- libjpeg
- freetype2
- OpenGL >= 3.3
- OpenGL >= 3.3, or OpenGL ES >= 3.0
- libshaderc (optional, for OpenGL ES backends)
- crossc >= 1.5.0 (optional, for OpenGL ES backends)
Build-only dependencies
^^^^^^^^^^^^^^^^^^^^^^^
@ -54,6 +56,22 @@ maintainers choice. Alternatively you may want to add
``install_relative`` is always set when building for Windows.
The OpenGL ES 3.0 backend is not built by default. To enable it, do:
::
meson configure -Dr_gles30=true -Dshader_transpiler=true
See `here <doc/ENVIRON.rst>`__ for information on how to activate it.
Alternatively, do this to make GLES 3.0 the default backend:
::
meson configure -Dr_default=gles30
Note that while it's also possible to enable a GLES 2.0 backend, it's currently
not functional.
Where are my replays, screenshots and settings?
-----------------------------------------------

View file

@ -116,10 +116,12 @@ Video and OpenGL
Selects the rendering backend to use. Currently available options are:
- ``gl33``: the OpenGL 3.3 Core renderer
- ``gles30``: the OpenGL ES 3.0 renderer
- ``null``: the no-op renderer (nothing is displayed)
Note that the actual subset of usable backends, as well as the default
choice, can be controlled by build options.
choice, can be controlled by build options. The ``gles30`` backend is not
built by default.
**TAISEI_LIBGL**
| Default: unset

32
doc/LICENSE.ANGLE Normal file
View file

@ -0,0 +1,32 @@
// Copyright 2018 The ANGLE Project Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following
// disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// Neither the name of TransGaming Inc., Google Inc., 3DLabs Inc.
// Ltd., nor the names of their contributors may be used to endorse
// or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

View file

@ -5,15 +5,18 @@ if get_option('docs')
'rst2html5.py',
'rst2html5-docutils',
'rst2html5-3',
'rst2html53',
'rst2html5-3.py',
'rst2html4',
'rst2html4.py',
'rst2html4-3',
'rst2html43',
'rst2html4-3.py',
'rst2html4-docutils',
'rst2html',
'rst2html.py',
'rst2html-3',
'rst2html3',
'rst2html-3.py',
'rst2html-docutils',
required : false
@ -39,7 +42,7 @@ if get_option('docs')
rst_docs = [
'ENVIRON.rst',
'GAME.rst',
'ANIMATION_FORMAT.rst'
# 'ANIMATION_FORMAT.rst'
]
txt_docs = [
@ -47,11 +50,9 @@ if get_option('docs')
'STORY.txt',
]
eol = host_machine.system() == 'windows' ? 'crlf' : 'lf'
foreach f : txt_docs
custom_target(f,
command : [eolconv, eol, '@INPUT@', '@OUTPUT@'],
command : [eolconv, host_eol_style, '@INPUT@', '@OUTPUT@'],
input : f,
output : f,
install : true,
@ -62,7 +63,7 @@ if get_option('docs')
foreach f : rst_docs
name = f.split('.')[0] + '.html'
custom_target(name,
command : [eolconv, eol, '@INPUT@', '@OUTPUT@'],
command : [eolconv, host_eol_style, '@INPUT@', '@OUTPUT@'],
input : rst_to_html.process(f),
output : name,
install : true,
@ -70,4 +71,14 @@ if get_option('docs')
depend_files : files('taisei.css')
)
endforeach
if angle_enabled and host_machine.system() == 'windows'
custom_target(f,
command : [eolconv, host_eol_style, '@INPUT@', '@OUTPUT@'],
input : 'LICENSE.ANGLE',
output : 'LICENSE.txt',
install : true,
install_dir : join_paths(bindir, 'ANGLE')
)
endif
endif

View file

@ -43,6 +43,7 @@ preprocessor = generator(preprocess_script,
)
eolconv = find_program(join_paths(scripts_dir, 'eolconv.py'))
host_eol_style = host_machine.system() == 'windows' ? 'crlf' : 'lf'
taisei_version_result = run_command(version_command, '{string}')
@ -185,7 +186,7 @@ else
endif
if config.get('TAISEI_BUILDCONF_RELATIVE_DATA_PATH')
bindir = ''
bindir = '.'
else
bindir = get_option('bindir')
endif
@ -226,6 +227,8 @@ config.set('TAISEI_BUILDCONF_LOG_ENABLE_BACKTRACE', is_debug_build and have_back
config.set('TAISEI_BUILDCONF_LOG_FATAL_MSGBOX', host_machine.system() == 'windows' or host_machine.system() == 'darwin')
config.set('TAISEI_BUILDCONF_DEBUG_OPENGL', get_option('debug_opengl'))
angle_enabled = get_option('install_angle')
if host_machine.system() == 'windows'
custom_target('COPYING.txt',
command : [eolconv, 'crlf', '@INPUT@', '@OUTPUT@'],
@ -234,8 +237,20 @@ if host_machine.system() == 'windows'
install : true,
install_dir : doc_path
)
if angle_enabled
install_data(
get_option('angle_libgles'),
get_option('angle_libegl'),
install_dir : join_paths(bindir, 'ANGLE'),
)
endif
else
install_data('COPYING', install_dir : doc_path)
if angle_enabled
error('install_angle is only available for Windows targets at the moment')
endif
endif
systype = (have_posix ? 'POSIX (@0@)' : '@0@').format(host_machine.system())

View file

@ -32,6 +32,25 @@ option(
description : 'Install freedesktop.org integration files (launchers, icons, replay file associations, etc.). Mostly relevant for Linux/BSD/etc. desktop systems'
)
option(
'install_angle',
type : 'boolean',
value : 'false',
description : 'Install pre-built ANGLE libraries. Only makes sense with a GLES backend. Currently only supported on Windows'
)
option(
'angle_libgles',
type : 'string',
description : 'Path to ANGLE\'s libGLESv2 dynamic library (see install_angle)'
)
option(
'angle_libegl',
type : 'string',
description : 'Path to ANGLE\'s libEGL dynamic library (see install_angle)'
)
option(
'win_console',
type : 'boolean',
@ -92,6 +111,13 @@ option(
description : 'Build and install documentation'
)
option(
'shader_transpiler',
type : 'boolean',
value : false,
description : 'Enable shader trans-compilation. Requires shaderc'
)
option(
'validate_glsl',
type : 'combo',
@ -116,14 +142,14 @@ option(
option(
'r_gles20',
type : 'boolean',
value : true,
description : 'Build the OpenGL ES 2.0 renderer'
value : false,
description : 'Build the OpenGL ES 2.0 renderer (incomplete)'
)
option(
'r_gles30',
type : 'boolean',
value : true,
value : false,
description : 'Build the OpenGL ES 3.0 renderer'
)

View file

@ -12,4 +12,15 @@ if macos_app_bundle
)
endif
if angle_enabled and host_machine.system() == 'windows'
angle_launcher = 'taisei-angle.bat'
custom_target(angle_launcher,
command : [eolconv, host_eol_style, '--no-bom', '@INPUT@', '@OUTPUT@'],
input : angle_launcher,
output : angle_launcher,
install : true,
install_dir : bindir,
)
endif
glslc_test_file = files('glslc-test.frag.glsl')

10
misc/taisei-angle.bat Normal file
View file

@ -0,0 +1,10 @@
@echo off
cd "%~dp0"
set ANGLE_PATH=.\ANGLE
set TAISEI_RENDERER=gles30
set SDL_OPENGL_ES_DRIVER=1
set SDL_VIDEO_GL_DRIVER=%ANGLE_PATH%\libGLESv2.dll
set SDL_VIDEO_EGL_DRIVER=%ANGLE_PATH%\libEGL.dll
start .\taisei.exe %*

View file

@ -8,13 +8,13 @@ UNIFORM(2) vec4 color1;
UNIFORM(3) float color_phase;
UNIFORM(4) float color_freq;
UNIFORM(5) float alphamod;
UNIFORM(6) float length;
UNIFORM(6) float laser_length;
void main(void) {
vec2 uv_scaled = (vec4(texCoordRaw,0.0,1.0)*r_textureMatrix).xy; // what the hell
float edgefactor = 20.0 * pow(alphamod, 2.0);
float edgemod = min(1.0, uv_scaled.x * edgefactor) * clamp((length - uv_scaled.x) * edgefactor, 0.0, 1.0);
float edgemod = min(1.0, uv_scaled.x * edgefactor) * clamp((laser_length - uv_scaled.x) * edgefactor, 0.0, 1.0);
float a = alphamod * edgemod;
vec4 color = mix(color0, color1, 0.5 + 0.5 * sin(color_phase + color_freq * uv_scaled.x));

View file

@ -9,7 +9,7 @@ UNIFORM(2) vec2 origin;
UNIFORM(3) vec2 clear_origin;
UNIFORM(4) int frames;
UNIFORM(5) float progress;
UNIFORM(6) sampler2D noise;
UNIFORM(6) sampler2D noise_tex;
bool in_circle(vec2 pos, vec2 ofs, float a, vec2 origin, float radius) {
mat2 m = mat2(cos(a), -sin(a), sin(a), cos(a));
@ -33,7 +33,7 @@ vec3 invert(vec3 v) {
}
void main(void) {
vec3 colormod = texture(noise, vec2(texCoord.x + frames/43.0 * sin(texCoord.y * 42), texCoord.y - frames/30.0)).rgb;
vec3 colormod = texture(noise_tex, vec2(texCoord.x + frames/43.0 * sin(texCoord.y * 42), texCoord.y - frames/30.0)).rgb;
vec4 pclr = texture(tex, texCoord);
vec4 nclr = pclr;
nclr.rgb = colormod * vec3(lum(invert(nclr.rgb)));

View file

@ -1,46 +0,0 @@
[Settings]
NumFields=5
[Field 1]
Type=label
Text=By default, Taisei Project does not add its directory to the system PATH.
Left=0
Right=-1
Top=0
Bottom=20
[Field 2]
Type=radiobutton
Text=Do not add Taisei to the system PATH
Left=0
Right=-1
Top=30
Bottom=40
State=1
[Field 3]
Type=radiobutton
Text=Add Taisei to the system PATH for all users
Left=0
Right=-1
Top=40
Bottom=50
State=0
[Field 4]
Type=radiobutton
Text=Add Taisei to the system PATH for current user
Left=0
Right=-1
Top=50
Bottom=60
State=0
[Field 5]
Type=CheckBox
Text=Create Taisei Desktop Icon
Left=0
Right=-1
Top=80
Bottom=90
State=1

View file

@ -3,14 +3,17 @@
import sys
if __name__ == '__main__':
try:
linemode = sys.argv[1].lower()
inpath = sys.argv[2]
outpath = sys.argv[3]
assert linemode in ('lf', 'crlf')
except (IndexError, AssertionError):
sys.stdout.write("Usage: %s [lf|crlf] infile outfile\n" % sys.argv[0])
exit(1)
args = sys.argv[1:]
linemode = args.pop(0).lower()
use_bom = linemode == 'crlf'
if args[0] == '--no-bom':
use_bom = False
args.pop(0)
inpath = args.pop(0)
outpath = args.pop(0)
assert linemode in ('lf', 'crlf')
bom = b'\xef\xbb\xbf'
@ -21,11 +24,10 @@ if __name__ == '__main__':
if linemode == 'crlf':
content = content.replace(b'\n', b'\r\n')
if not content.startswith(bom):
content = bom + content
else:
if content.startswith(bom):
content = content[len(bom):]
if use_bom and not content.startswith(bom):
content = bom + content
elif not use_bom and content.startswith(bom):
content = content[len(bom):]
with open(outpath, 'wb') as outfile:
outfile.write(content)

View file

@ -29,6 +29,12 @@ if host_machine.system() == 'windows'
nsis_defs += '-DTAISEI_64BIT=0'
endif
if angle_enabled
nsis_defs += '-DUSE_ANGLE=1'
else
nsis_defs += '-DUSE_ANGLE=0'
endif
nsis_target = run_target('nsis',
command: [
nsis_command,

View file

@ -1,15 +1,15 @@
Unicode true
;
; TODO: clean up this unholy mess
; Most stuff here have been ported from the CPack template
;
Name "Taisei Project"
!define PUBLISHER "Taisei Project"
!define APPNAME "Taisei Project"
!define PROJECT "Taisei Project"
!define PROJECT_URL "https://taisei-project.org/"
!define PUBLISHER "${PROJECT}"
!define APPNAME "${PROJECT}"
!define APPREGISTRY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}"
Name "${PROJECT}"
OutFile "@OUTPUT@"
; LZMA compression is *very* slow
SetCompressor /SOLID zlib
!define VERSION "@VERSION({string})@"
@ -20,61 +20,66 @@ SetCompressor /SOLID zlib
!if @TAISEI_64BIT@ == 1
!include x64.nsh
!define ARCH_INSTDIR "$PROGRAMFILES64\${APPNAME}"
InstallDir "${ARCH_INSTDIR}"
!else
!define ARCH_INSTDIR "$PROGRAMFILES32\${APPNAME}"
InstallDir "${ARCH_INSTDIR}"
!define MULTIUSER_USE_PROGRAMFILES64
!endif
; All vars must be global...
Var STARTMENU_FOLDER
Var MUI_TEMP
Var START_MENU
Var DO_NOT_ADD_TO_PATH
Var ADD_TO_PATH_ALL_USERS
Var ADD_TO_PATH_CURRENT_USER
Var INSTALL_DESKTOP
Var SV_ALLUSERS
Var IS_DEFAULT_INSTALLDIR
; Multi-user handling
!define MULTIUSER_EXECUTIONLEVEL Highest
!define MULTIUSER_MUI
!define MULTIUSER_INSTALLMODE_COMMANDLINE
!define MULTIUSER_INSTALLMODE_INSTDIR "${APPNAME}"
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_KEY "${APPREGISTRY}"
!define MULTIUSER_INSTALLMODE_INSTDIR_REGISTRY_VALUENAME "InstallLocation"
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_KEY "${APPREGISTRY}"
!define MULTIUSER_INSTALLMODE_DEFAULT_REGISTRY_VALUENAME "InstallMode"
!include "MultiUser.nsh"
; UI
!include "MUI2.nsh"
!include "InstallOptions.nsh"
!define MUI_HEADERIMAGE_BITMAP "@MESON_SOURCE_ROOT@/misc/icons/taisei.ico"
!define MUI_FINISHPAGE_RUN "$INSTDIR/taisei.exe"
!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_LICENSE "@MESON_BUILD_ROOT@/COPYING.txt"
Page custom InstallOptionsPage
!define MULTIUSER_INSTALLMODEPAGE_TEXT_ALLUSERS "Install globally for all users (required for replay file association)"
!insertmacro MULTIUSER_PAGE_INSTALLMODE
!insertmacro MUI_PAGE_DIRECTORY
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "SHCTX"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\${PUBLISHER}\${APPNAME}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "Start Menu Folder"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "${APPREGISTRY}"
!define MUI_STARTMENUPAGE_REGISTRY_VALUENAME "StartMenu"
!insertmacro MUI_PAGE_STARTMENU Application $STARTMENU_FOLDER
!insertmacro MUI_PAGE_INSTFILES
!define MUI_FINISHPAGE_NOAUTOCLOSE
!define MUI_FINISHPAGE_RUN_NOTCHECKED
!define MUI_FINISHPAGE_RUN "$INSTDIR/taisei.exe"
!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR/README.txt"
!define MUI_FINISHPAGE_LINK "Visit project web site"
!define MUI_FINISHPAGE_LINK_LOCATION "${PROJECT_URL}"
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_UNPAGE_CONFIRM
!insertmacro MUI_UNPAGE_INSTFILES
!insertmacro MUI_UNPAGE_FINISH
!insertmacro MUI_LANGUAGE "English"
ReserveFile "@INSTALL_OPTIONS_INI@"
ReserveFile /plugin InstallOptions.dll
# !insertmacro MUI_RESERVEFILE_INSTALLOPTIONS
; Installer sections
Function ConditionalAddToRegisty
Pop $0
Pop $1
StrCmp "$0" "" ConditionalAddToRegisty_EmptyString
WriteRegStr SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "$1" "$0"
DetailPrint "Set install registry entry: '$1' to '$0'"
ConditionalAddToRegisty_EmptyString:
Function AddToInstallerRegisty
Pop $0
Pop $1
StrCmp "$0" "" ConditionalAddToRegisty_EmptyString
WriteRegStr SHCTX "${APPREGISTRY}" "$1" "$0"
DetailPrint "Set install registry entry: '$1' to '$0'"
ConditionalAddToRegisty_EmptyString:
FunctionEnd
Section "-Core installation"
@ -83,337 +88,157 @@ Section "-Core installation"
File /r "${INST_DIR}\*.*"
; Uninstaller
WriteRegStr SHCTX "Software\${PUBLISHER}\${APPNAME}" "" $INSTDIR
WriteUninstaller "$INSTDIR\Uninstall.exe"
Push "DisplayName"
Push "${APPNAME}"
Call ConditionalAddToRegisty
Call AddToInstallerRegisty
Push "DisplayVersion"
Push "${VERSION}"
Call ConditionalAddToRegisty
Call AddToInstallerRegisty
Push "Publisher"
Push "${PUBLISHER}"
Call ConditionalAddToRegisty
Call AddToInstallerRegisty
Push "UninstallString"
Push "$INSTDIR\Uninstall.exe"
Call ConditionalAddToRegisty
Push "$\"$INSTDIR\Uninstall.exe$\""
Call AddToInstallerRegisty
Push "QuietUninstallString"
Push "$\"$INSTDIR\Uninstall.exe$\" /S"
Call AddToInstallerRegisty
Push "NoRepair"
Push "1"
Call ConditionalAddToRegisty
Call AddToInstallerRegisty
Push "NoModify"
Push "1"
Call AddToInstallerRegisty
; Registration
Push "DisplayIcon"
Push "$INSTDIR\taisei.exe"
Call ConditionalAddToRegisty
Push "HelpLink"
Push "https://taisei-project.org/"
Call ConditionalAddToRegisty
Call AddToInstallerRegisty
Push "HelpLink"
Push "${PROJECT_URL}"
Call AddToInstallerRegisty
Push "URLInfoAbout"
Push "${PROJECT_URL}"
Call AddToInstallerRegisty
Push "URLUpdateInfo"
Push "${PROJECT_URL}"
Call AddToInstallerRegisty
Push "Readme"
Push "$INSTDIR\README.txt"
Call AddToInstallerRegisty
Push "InstallLocation"
Push "$INSTDIR"
Call AddToInstallerRegisty
Push "InstallMode"
Push "$MultiUser.InstallMode"
Call AddToInstallerRegisty
Push "InstallToDesktop"
Push "$INSTALL_DESKTOP"
Call AddToInstallerRegisty
!insertmacro INSTALLOPTIONS_READ $INSTALL_DESKTOP "NSIS.InstallOptions.ini" "Field 5" "State"
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
CreateDirectory "$SMPROGRAMS\$STARTMENU_FOLDER"
CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Taisei.lnk" "$INSTDIR\taisei.exe"
!insertmacro INSTALLOPTIONS_READ $DO_NOT_ADD_TO_PATH "NSIS.InstallOptions.ini" "Field 2" "State"
!insertmacro INSTALLOPTIONS_READ $ADD_TO_PATH_ALL_USERS "NSIS.InstallOptions.ini" "Field 3" "State"
!insertmacro INSTALLOPTIONS_READ $ADD_TO_PATH_CURRENT_USER "NSIS.InstallOptions.ini" "Field 4" "State"
CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk" "$INSTDIR\Uninstall.exe"
Push "StartMenu"
Push "$STARTMENU_FOLDER"
Call ConditionalAddToRegisty
Push "DoNotAddToPath"
Push "$DO_NOT_ADD_TO_PATH"
Call ConditionalAddToRegisty
Push "AddToPathAllUsers"
Push "$ADD_TO_PATH_ALL_USERS"
Call ConditionalAddToRegisty
Push "AddToPathCurrentUser"
Push "$ADD_TO_PATH_CURRENT_USER"
Call ConditionalAddToRegisty
Push "InstallToDesktop"
Push "$INSTALL_DESKTOP"
Call ConditionalAddToRegisty
!if @USE_ANGLE@ == 1
CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Taisei (OpenGL).lnk" "$INSTDIR\taisei.exe"
CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Taisei (ANGLE).lnk" "$INSTDIR\taisei-angle.bat" "" "$INSTDIR\taisei.exe" 0 SW_SHOWMINIMIZED
!else
CreateShortcut "$SMPROGRAMS\$STARTMENU_FOLDER\Taisei.lnk" "$INSTDIR\taisei.exe"
!endif
${If} "$INSTALL_DESKTOP" == "1"
!if @USE_ANGLE@ == 1
CreateShortcut "$DESKTOP\Taisei (OpenGL).lnk" "$INSTDIR\taisei.exe"
CreateShortcut "$DESKTOP\Taisei (ANGLE).lnk" "$INSTDIR\taisei-angle.bat" "" "$INSTDIR\taisei.exe" 0 SW_SHOWMINIMIZED
!else
CreateShortcut "$DESKTOP\Taisei.lnk" "$INSTDIR\taisei.exe"
!endif
${EndIf}
!insertmacro MUI_STARTMENU_WRITE_END
DeleteRegKey HKCR ".tsr"
DeleteRegKey HKCR "TaiseiProject.tsr"
DeleteRegKey HKCR "TaiseiProject.tsr\DefaultIcon"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell\Open"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell\Open\Command"
DeleteRegKey HKCR "Applications\taisei.exe"
DeleteRegKey HKCR "Applications\taisei.exe\DefaultIcon"
DeleteRegKey HKCR "Applications\taisei.exe\Shell"
DeleteRegKey HKCR "Applications\taisei.exe\Shell\Open"
DeleteRegKey HKCR "Applications\taisei.exe\Shell\Open\Command"
${If} $MultiUser.InstallMode == "AllUsers"
DeleteRegKey HKCR ".tsr"
DeleteRegKey HKCR "TaiseiProject.tsr"
DeleteRegKey HKCR "TaiseiProject.tsr\DefaultIcon"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell\Open"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell\Open\Command"
DeleteRegKey HKCR "Applications\taisei.exe"
DeleteRegKey HKCR "Applications\taisei.exe\DefaultIcon"
DeleteRegKey HKCR "Applications\taisei.exe\Shell"
DeleteRegKey HKCR "Applications\taisei.exe\Shell\Open"
DeleteRegKey HKCR "Applications\taisei.exe\Shell\Open\Command"
WriteRegStr HKCR ".tsr" "" "TaiseiProject.tsr"
WriteRegStr HKCR ".tsr" "Content Type" "application/x-taisei-replay"
WriteRegStr HKCR "TaiseiProject.tsr" "" "Taisei Project replay"
WriteRegStr HKCR "TaiseiProject.tsr" "FriendlyTypeName" "@$INSTDIR\taisei.exe,-2"
WriteRegStr HKCR "TaiseiProject.tsr\DefaultIcon" "" "$INSTDIR\taisei.exe,1"
WriteRegStr HKCR "TaiseiProject.tsr\Shell\Open\Command" "" "$\"$INSTDIR\taisei.exe$\" --replay $\"%1$\""
WriteRegStr HKCR "Applications\taisei.exe" "" "Taisei Project"
WriteRegStr HKCR "Applications\taisei.exe" "FriendlyAppName" "@$INSTDIR\taisei.exe,-1"
WriteRegStr HKCR "Applications\taisei.exe\DefaultIcon" "" "$INSTDIR\taisei.exe,1"
WriteRegStr HKCR "Applications\taisei.exe\Shell\Open\Command" "" "$\"$INSTDIR\taisei.exe$\" --replay $\"%1$\""
WriteRegStr HKCR ".tsr" "" "TaiseiProject.tsr"
WriteRegStr HKCR ".tsr" "Content Type" "application/x-taisei-replay"
WriteRegStr HKCR "TaiseiProject.tsr" "" "Taisei Project replay"
WriteRegStr HKCR "TaiseiProject.tsr" "FriendlyTypeName" "@$INSTDIR\taisei.exe,-2"
WriteRegStr HKCR "TaiseiProject.tsr\DefaultIcon" "" "$INSTDIR\taisei.exe,1"
WriteRegStr HKCR "TaiseiProject.tsr\Shell\Open\Command" "" "$\"$INSTDIR\taisei.exe$\" --replay $\"%1$\""
WriteRegStr HKCR "Applications\taisei.exe" "" "Taisei Project"
WriteRegStr HKCR "Applications\taisei.exe" "FriendlyAppName" "@$INSTDIR\taisei.exe,-1"
WriteRegStr HKCR "Applications\taisei.exe\DefaultIcon" "" "$INSTDIR\taisei.exe,1"
WriteRegStr HKCR "Applications\taisei.exe\Shell\Open\Command" "" "$\"$INSTDIR\taisei.exe$\" --replay $\"%1$\""
${EndIf}
SectionEnd
!define NT_current_env 'HKCU "Environment"'
!define NT_all_env 'HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"'
; StrStr
; input, top of stack = string to search for
; top of stack-1 = string to search in
; output, top of stack (replaces with the portion of the string remaining)
; modifies no other variables.
;
; Usage:
; Push "this is a long ass string"
; Push "ass"
; Call StrStr
; Pop $R0
; ($R0 at this point is "ass string")
!macro StrStr un
Function ${un}StrStr
Exch $R1 ; st=haystack,old$R1, $R1=needle
Exch ; st=old$R1,haystack
Exch $R2 ; st=old$R1,old$R2, $R2=haystack
Push $R3
Push $R4
Push $R5
StrLen $R3 $R1
StrCpy $R4 0
; $R1=needle
; $R2=haystack
; $R3=len(needle)
; $R4=cnt
; $R5=tmp
loop:
StrCpy $R5 $R2 $R3 $R4
StrCmp $R5 $R1 done
StrCmp $R5 "" done
IntOp $R4 $R4 + 1
Goto loop
done:
StrCpy $R1 $R2 "" $R4
Pop $R5
Pop $R4
Pop $R3
Pop $R2
Exch $R1
FunctionEnd
!macroend
!insertmacro StrStr ""
!insertmacro StrStr "un."
Function Trim ; Added by Pelaca
Exch $R1
Push $R2
Loop:
StrCpy $R2 "$R1" 1 -1
StrCmp "$R2" " " RTrim
StrCmp "$R2" "$\n" RTrim
StrCmp "$R2" "$\r" RTrim
StrCmp "$R2" ";" RTrim
GoTo Done
RTrim:
StrCpy $R1 "$R1" -1
Goto Loop
Done:
Pop $R2
Exch $R1
FunctionEnd
Function AddToPath
Exch $0
Push $1
Push $2
Push $3
# don't add if the path doesn't exist
IfFileExists "$0\*.*" "" AddToPath_done
ReadEnvStr $1 PATH
; if the path is too long for a NSIS variable NSIS will return a 0
; length string. If we find that, then warn and skip any path
; modification as it will trash the existing path.
StrLen $2 $1
IntCmp $2 0 CheckPathLength_ShowPathWarning CheckPathLength_Done CheckPathLength_Done
CheckPathLength_ShowPathWarning:
Messagebox MB_OK|MB_ICONEXCLAMATION "Warning! PATH too long; installer unable to modify PATH!"
Goto AddToPath_done
CheckPathLength_Done:
Push "$1;"
Push "$0;"
Call StrStr
Pop $2
StrCmp $2 "" "" AddToPath_done
Push "$1;"
Push "$0\;"
Call StrStr
Pop $2
StrCmp $2 "" "" AddToPath_done
GetFullPathName /SHORT $3 $0
Push "$1;"
Push "$3;"
Call StrStr
Pop $2
StrCmp $2 "" "" AddToPath_done
Push "$1;"
Push "$3\;"
Call StrStr
Pop $2
StrCmp $2 "" "" AddToPath_done
StrCmp $ADD_TO_PATH_ALL_USERS "1" ReadAllKey
ReadRegStr $1 ${NT_current_env} "PATH"
Goto DoTrim
ReadAllKey:
ReadRegStr $1 ${NT_all_env} "PATH"
DoTrim:
StrCmp $1 "" AddToPath_NTdoIt
Push $1
Call Trim
Pop $1
StrCpy $0 "$1;$0"
AddToPath_NTdoIt:
StrCmp $ADD_TO_PATH_ALL_USERS "1" WriteAllKey
WriteRegExpandStr ${NT_current_env} "PATH" $0
Goto DoSend
WriteAllKey:
WriteRegExpandStr ${NT_all_env} "PATH" $0
DoSend:
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
AddToPath_done:
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
Section "-Add to path"
Push $INSTDIR
StrCmp "" "ON" 0 doNotAddToPath
StrCmp $DO_NOT_ADD_TO_PATH "1" doNotAddToPath 0
Call AddToPath
doNotAddToPath:
SectionEnd
Function InstallOptionsPage
!insertmacro MUI_HEADER_TEXT "Install Options" "Choose options for installing Taisei Project"
!insertmacro INSTALLOPTIONS_DISPLAY "NSIS.InstallOptions.ini"
FunctionEnd
Function un.RemoveFromPath
Exch $0
Push $1
Push $2
Push $3
Push $4
Push $5
Push $6
IntFmt $6 "%c" 26 # DOS EOF
StrCmp $ADD_TO_PATH_ALL_USERS "1" unReadAllKey
ReadRegStr $1 ${NT_current_env} "PATH"
Goto unDoTrim
unReadAllKey:
ReadRegStr $1 ${NT_all_env} "PATH"
unDoTrim:
StrCpy $5 $1 1 -1 # copy last char
StrCmp $5 ";" +2 # if last char != ;
StrCpy $1 "$1;" # append ;
Push $1
Push "$0;"
Call un.StrStr ; Find `$0;` in $1
Pop $2 ; pos of our dir
StrCmp $2 "" unRemoveFromPath_done
; else, it is in path
# $0 - path to add
# $1 - path var
StrLen $3 "$0;"
StrLen $4 $2
StrCpy $5 $1 -$4 # $5 is now the part before the path to remove
StrCpy $6 $2 "" $3 # $6 is now the part after the path to remove
StrCpy $3 $5$6
StrCpy $5 $3 1 -1 # copy last char
StrCmp $5 ";" 0 +2 # if last char == ;
StrCpy $3 $3 -1 # remove last char
StrCmp $ADD_TO_PATH_ALL_USERS "1" unWriteAllKey
WriteRegExpandStr ${NT_current_env} "PATH" $3
Goto unDoSend
unWriteAllKey:
WriteRegExpandStr ${NT_all_env} "PATH" $3
unDoSend:
SendMessage ${HWND_BROADCAST} ${WM_WININICHANGE} 0 "STR:Environment" /TIMEOUT=5000
unRemoveFromPath_done:
Pop $6
Pop $5
Pop $4
Pop $3
Pop $2
Pop $1
Pop $0
FunctionEnd
Section "Uninstall"
ReadRegStr $START_MENU SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "StartMenu"
ReadRegStr $DO_NOT_ADD_TO_PATH SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "DoNotAddToPath"
ReadRegStr $ADD_TO_PATH_ALL_USERS SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "AddToPathAllUsers"
ReadRegStr $ADD_TO_PATH_CURRENT_USER SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "AddToPathCurrentUser"
ReadRegStr $INSTALL_DESKTOP SHCTX \
"Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "InstallToDesktop"
ReadRegStr $INSTALL_DESKTOP SHCTX "${APPREGISTRY}" "InstallToDesktop"
DeleteRegKey HKCR ".tsr"
DeleteRegKey HKCR "TaiseiProject.tsr"
DeleteRegKey HKCR "TaiseiProject.tsr\DefaultIcon"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell\Open"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell\Open\Command"
DeleteRegKey HKCR "Applications\taisei.exe"
DeleteRegKey HKCR "Applications\taisei.exe\DefaultIcon"
DeleteRegKey HKCR "Applications\taisei.exe\Shell"
DeleteRegKey HKCR "Applications\taisei.exe\Shell\Open"
DeleteRegKey HKCR "Applications\taisei.exe\Shell\Open\Command"
${If} $MultiUser.InstallMode == "AllUsers"
DeleteRegKey HKCR ".tsr"
DeleteRegKey HKCR "TaiseiProject.tsr"
DeleteRegKey HKCR "TaiseiProject.tsr\DefaultIcon"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell\Open"
DeleteRegKey HKCR "TaiseiProject.tsr\Shell\Open\Command"
DeleteRegKey HKCR "Applications\taisei.exe"
DeleteRegKey HKCR "Applications\taisei.exe\DefaultIcon"
DeleteRegKey HKCR "Applications\taisei.exe\Shell"
DeleteRegKey HKCR "Applications\taisei.exe\Shell\Open"
DeleteRegKey HKCR "Applications\taisei.exe\Shell\Open\Command"
${EndIf}
@UNINSTALL_COMMANDS@
Delete "$INSTDIR\Uninstall.exe"
DeleteRegKey SHCTX "Software\Microsoft\Windows\CurrentVersion\Uninstall\%{APPNAME}"
RMDir "$INSTDIR"
DeleteRegKey SHCTX "Software\${PUBLISHER}\${APPNAME}"
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\Taisei.lnk"
!insertmacro MUI_STARTMENU_GETFOLDER Application $STARTMENU_FOLDER
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\Uninstall.lnk"
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\Taisei.lnk"
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\Taisei (OpenGL).lnk"
Delete "$SMPROGRAMS\$STARTMENU_FOLDER\Taisei (ANGLE).lnk"
RMDir "$SMPROGRAMS\$STARTMENU_FOLDER"
!insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
Delete "$SMPROGRAMS\$MUI_TEMP\Uninstall.lnk"
Delete "$SMPROGRAMS\$MUI_TEMP\Taisei.lnk"
RMDir "$SMPROGRAMS\$MUI_TEMP"
${If} "$INSTALL_DESKTOP" == "1"
Delete "$DESKTOP\Taisei.lnk"
Delete "$DESKTOP\Taisei (OpenGL).lnk"
Delete "$DESKTOP\Taisei (ANGLE).lnk"
${EndIf}
DeleteRegKey /ifempty SHCTX "Software\${PUBLISHER}\${APPNAME}"
Push $INSTDIR
StrCmp $DO_NOT_ADD_TO_PATH_ "1" doNotRemoveFromPath 0
Call un.RemoveFromPath
doNotRemoveFromPath:
DeleteRegKey SHCTX "${APPREGISTRY}"
SectionEnd
Function .onInit
!macro INIT_X64
!if @TAISEI_64BIT@ == 1
${If} ${RunningX64}
SetRegView 64
@ -422,65 +247,39 @@ Function .onInit
Abort
${EndIf}
!endif
!macroend
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APPNAME}" "UninstallString"
Function .onInit
!insertmacro INIT_X64
!insertmacro MULTIUSER_INIT
ReadRegStr $0 SHCTX "${APPREGISTRY}" "UninstallString"
StrCmp $0 "" inst
MessageBox MB_YESNOCANCEL|MB_ICONEXCLAMATION \
"${APPNAME} is already installed. $\n$\nDo you want to uninstall the old version before installing the new one?" \
/SD IDYES IDYES uninst IDNO inst
"${APPNAME} is already installed. $\n$\nDo you want to uninstall the old version before installing the new one?" \
/SD IDYES IDYES uninst IDNO inst
Abort
;Run the uninstaller
uninst:
ClearErrors
StrLen $2 "\Uninstall.exe"
StrCpy $3 $0 -$2 # remove "\Uninstall.exe" from UninstallString to get path
ExecWait '"$0" /S _?=$3' ;Do not copy the uninstaller to a temp file
ReadRegStr $1 SHCTX "${APPREGISTRY}" "QuietUninstallString"
ReadRegStr $2 SHCTX "${APPREGISTRY}" "InstallLocation"
IfErrors uninst_failed
ExecWait '$1 _?=$2' ; Do not copy the uninstaller to a temp file
IfErrors uninst_failed inst
uninst_failed:
MessageBox MB_OK|MB_ICONSTOP "Uninstall failed."
Abort
inst:
; check to see if /D has been used to change
; the install directory by comparing it to the
; install directory that is expected to be the
; default
StrCpy $IS_DEFAULT_INSTALLDIR 0
StrCmp "$INSTDIR" "${ARCH_INSTDIR}" 0 +2
StrCpy $IS_DEFAULT_INSTALLDIR 1
StrCpy $SV_ALLUSERS "JustMe"
; if default install dir then change the default
; if it is installed for JustMe"
StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2
StrCpy $INSTDIR "$DOCUMENTS\${APPNAME}"
ClearErrors
UserInfo::GetName
IfErrors noLM
Pop $0
UserInfo::GetAccountType
Pop $1
StrCmp $1 "Admin" 0 +4
SetShellVarContext all
StrCpy $SV_ALLUSERS "AllUsers"
Goto done
StrCmp $1 "Power" 0 +4
SetShellVarContext all
StrCpy $SV_ALLUSERS "AllUsers"
Goto done
noLM:
StrCpy $SV_ALLUSERS "AllUsers"
done:
StrCmp $SV_ALLUSERS "AllUsers" 0 +3
StrCmp "$IS_DEFAULT_INSTALLDIR" "1" 0 +2
StrCpy $INSTDIR "${ARCH_INSTDIR}"
!insertmacro INSTALLOPTIONS_EXTRACT_AS "@INSTALL_OPTIONS_INI@" "NSIS.InstallOptions.ini"
; TODO: Maybe make it optional again
StrCpy $INSTALL_DESKTOP "1"
FunctionEnd
Function un.onInit
!insertmacro INIT_X64
!insertmacro MULTIUSER_UNINIT
FunctionEnd

View file

@ -67,7 +67,7 @@ def main(args):
uninstall_files = ('\n'+indent).join('Delete "{}\\{}"'.format(instdir, path) for path in files)
uninstall_dirs = ('\n'+indent).join('RMDir "{}\\{}"'.format(instdir, path) for path in dirs)
uninstall_commands = ('\n\n'+indent).join((uninstall_files, uninstall_dirs))
uninstall_commands = indent + ('\n\n'+indent).join((uninstall_files, uninstall_dirs))
print(uninstall_commands)
@ -83,7 +83,7 @@ def main(args):
args=args
)
nsis_cmd = shlex.split('makensis -V4 -NOCD -INPUTCHARSET UTF8 -WX -')
nsis_cmd = shlex.split('makensis -V3 -NOCD -INPUTCHARSET UTF8 -WX -')
with subprocess.Popen(nsis_cmd, stdin=subprocess.PIPE, cwd=str(args.build_dir)) as proc:
proc.stdin.write(script.encode('utf-8'))

View file

@ -158,7 +158,7 @@ static void draw_laser_curve_specialized(Laser *l) {
r_uniform_float("width", l->width);
r_uniform_float("width_exponent", l->width_exponent);
r_uniform_int("span", instances);
r_draw(PRIM_TRIANGLE_FAN, 0, 4, NULL, instances, 0);
r_draw(PRIM_TRIANGLE_STRIP, 0, 4, NULL, instances, 0);
}
static void draw_laser_curve_generic(Laser *l) {
@ -189,8 +189,11 @@ static void draw_laser_curve_generic(Laser *l) {
aptr->delta[1] = cimag(delta);
}
r_vertex_buffer_append(lasers.vbuf, sizeof(attrs), &attrs);
r_draw(PRIM_TRIANGLE_FAN, 0, 4, NULL, instances, 0);
SDL_RWops *stream = r_vertex_buffer_get_stream(lasers.vbuf);
SDL_RWseek(stream, 0, RW_SEEK_SET);
SDL_RWwrite(stream, &attrs, sizeof(attrs), 1);
r_draw(PRIM_TRIANGLE_STRIP, 0, 4, NULL, instances, 0);
}
static void ent_draw_laser(EntityInterface *ent) {

View file

@ -20,7 +20,8 @@ if host_machine.system() == 'windows'
rcdefs += ['-DBUILDTYPE_DEFINE=#define RELEASE_BUILD']
endif
rc_target = custom_target('Windows resource file',
# https://github.com/mesonbuild/meson/issues/4301
rc_target = custom_target('windows-resource',
command : [preprocess_command, rcdefs, '@INPUT@', '@OUTPUT@'],
build_always : true,
input : 'taisei.rc.in',

View file

@ -444,7 +444,7 @@ void player_realdeath(Player *plr) {
static void player_death_effect_draw_overlay(Projectile *p, int t) {
FBPair *framebuffers = stage_get_fbpair(FBPAIR_FG);
r_framebuffer(framebuffers->front);
r_uniform_sampler("noise", "static");
r_uniform_sampler("noise_tex", "static");
r_uniform_int("frames", global.frames);
r_uniform_float("progress", t / p->timeout);
r_uniform_vec2("origin", creal(p->pos), VIEWPORT_H - cimag(p->pos));

View file

@ -200,7 +200,7 @@ static void marisa_laser_renderer_visual(Enemy *renderer, int t, bool render) {
Uniform *u_clr_phase = r_shader_uniform(shader, "color_phase");
Uniform *u_clr_freq = r_shader_uniform(shader, "color_freq");
Uniform *u_alpha = r_shader_uniform(shader, "alphamod");
Uniform *u_length = r_shader_uniform(shader, "length");
Uniform *u_length = r_shader_uniform(shader, "laser_length");
Texture *tex0 = get_tex("part/marisa_laser0");
Texture *tex1 = get_tex("part/marisa_laser1");
VertexArray *varr_saved = r_vertex_array_current();

View file

@ -421,12 +421,12 @@ void r_texture_set_wrap(Texture *tex, TextureWrapMode ws, TextureWrapMode wt) {
B.texture_set_wrap(tex, ws, wt);
}
void r_texture_fill(Texture *tex, uint mipmap, void *image_data) {
void r_texture_fill(Texture *tex, uint mipmap, const Pixmap *image_data) {
B.texture_fill(tex, mipmap, image_data);
}
void r_texture_fill_region(Texture *tex, uint mipmap, uint x, uint y, uint w, uint h, void *image_data) {
B.texture_fill_region(tex, mipmap, x, y, w, h, image_data);
void r_texture_fill_region(Texture *tex, uint mipmap, uint x, uint y, const Pixmap *image_data) {
B.texture_fill_region(tex, mipmap, x, y, image_data);
}
void r_texture_invalidate(Texture *tex) {
@ -516,33 +516,8 @@ void r_vertex_buffer_invalidate(VertexBuffer *vbuf) {
B.vertex_buffer_invalidate(vbuf);
}
void r_vertex_buffer_write(VertexBuffer *vbuf, size_t offset, size_t data_size, void *data) {
B.vertex_buffer_write(vbuf, offset, data_size, data);
}
void r_vertex_buffer_append(VertexBuffer *vbuf, size_t data_size, void *data) {
B.vertex_buffer_append(vbuf, data_size, data);
}
size_t r_vertex_buffer_get_capacity(VertexBuffer *vbuf) {
return B.vertex_buffer_get_capacity(vbuf);
}
size_t r_vertex_buffer_get_cursor(VertexBuffer *vbuf) {
return B.vertex_buffer_get_cursor(vbuf);
}
void r_vertex_buffer_seek_cursor(VertexBuffer *vbuf, ssize_t offset, int whence) {
size_t pos;
switch(whence) {
case SEEK_CUR: pos = r_vertex_buffer_get_cursor(vbuf) + offset; break;
case SEEK_END: pos = r_vertex_buffer_get_capacity(vbuf) + offset; break;
case SEEK_SET: pos = offset; break;
default: UNREACHABLE;
}
B.vertex_buffer_set_cursor(vbuf, pos);
SDL_RWops* r_vertex_buffer_get_stream(VertexBuffer *vbuf) {
return B.vertex_buffer_get_stream(vbuf);
}
VertexArray* r_vertex_array_create(void) {
@ -596,8 +571,8 @@ void r_swap(SDL_Window *window) {
B.swap(window);
}
uint8_t* r_screenshot(uint *out_width, uint *out_height) {
return B.screenshot(out_width, out_height);
bool r_screenshot(Pixmap *out) {
return B.screenshot(out);
}
// uniforms garbage; hope your compiler is smart enough to inline most of this

View file

@ -10,6 +10,7 @@
#include "taisei.h"
#include "util.h"
#include "util/pixmap.h"
#include "color.h"
#include "resource/resource.h"
#include "resource/shader_program.h"
@ -137,7 +138,6 @@ typedef enum Primitive {
PRIM_LINE_LOOP,
PRIM_LINES,
PRIM_TRIANGLE_STRIP,
PRIM_TRIANGLE_FAN,
PRIM_TRIANGLES,
} Primitive;
@ -592,8 +592,8 @@ const char* r_texture_get_debug_label(Texture *tex) attr_nonnull(1);
void r_texture_set_debug_label(Texture *tex, const char *label) attr_nonnull(1);
void r_texture_set_filter(Texture *tex, TextureFilterMode fmin, TextureFilterMode fmag) attr_nonnull(1);
void r_texture_set_wrap(Texture *tex, TextureWrapMode ws, TextureWrapMode wt) attr_nonnull(1);
void r_texture_fill(Texture *tex, uint mipmap, void *image_data) attr_nonnull(1, 3);
void r_texture_fill_region(Texture *tex, uint mipmap, uint x, uint y, uint w, uint h, void *image_data) attr_nonnull(1, 7);
void r_texture_fill(Texture *tex, uint mipmap, const Pixmap *image_data) attr_nonnull(1, 3);
void r_texture_fill_region(Texture *tex, uint mipmap, uint x, uint y, const Pixmap *image_data) attr_nonnull(1, 5);
void r_texture_invalidate(Texture *tex) attr_nonnull(1);
void r_texture_clear(Texture *tex, const Color *clr) attr_nonnull(1, 2);
void r_texture_destroy(Texture *tex) attr_nonnull(1);
@ -618,11 +618,7 @@ const char* r_vertex_buffer_get_debug_label(VertexBuffer *vbuf) attr_nonnull(1);
void r_vertex_buffer_set_debug_label(VertexBuffer *vbuf, const char* label) attr_nonnull(1);
void r_vertex_buffer_destroy(VertexBuffer *vbuf) attr_nonnull(1);
void r_vertex_buffer_invalidate(VertexBuffer *vbuf) attr_nonnull(1);
void r_vertex_buffer_write(VertexBuffer *vbuf, size_t offset, size_t data_size, void *data) attr_nonnull(1, 4);
void r_vertex_buffer_append(VertexBuffer *vbuf, size_t data_size, void *data) attr_nonnull(1, 3);
size_t r_vertex_buffer_get_capacity(VertexBuffer *vbuf) attr_nonnull(1);
size_t r_vertex_buffer_get_cursor(VertexBuffer *vbuf) attr_nonnull(1);
void r_vertex_buffer_seek_cursor(VertexBuffer *vbuf, ssize_t offset, int whence) attr_nonnull(1);
SDL_RWops* r_vertex_buffer_get_stream(VertexBuffer *vbuf) attr_nonnull(1);
VertexArray* r_vertex_array_create(void);
const char* r_vertex_array_get_debug_label(VertexArray *varr) attr_nonnull(1);
@ -640,7 +636,7 @@ VsyncMode r_vsync_current(void);
void r_swap(SDL_Window *window);
uint8_t* r_screenshot(uint *out_width, uint *out_height) attr_nodiscard attr_nonnull(1, 2);
bool r_screenshot(Pixmap *dest) attr_nodiscard attr_nonnull(1);
void r_mat_mode(MatrixMode mode);
MatrixMode r_mat_mode_current(void);

View file

@ -65,8 +65,8 @@ typedef struct RendererFuncs {
void (*texture_set_wrap)(Texture *tex, TextureWrapMode ws, TextureWrapMode wt);
void (*texture_destroy)(Texture *tex);
void (*texture_invalidate)(Texture *tex);
void (*texture_fill)(Texture *tex, uint mipmap, void *image_data);
void (*texture_fill_region)(Texture *tex, uint mipmap, uint x, uint y, uint w, uint h, void *image_data);
void (*texture_fill)(Texture *tex, uint mipmap, const Pixmap *image_data);
void (*texture_fill_region)(Texture *tex, uint mipmap, uint x, uint y, const Pixmap *image_data);
void (*texture_clear)(Texture *tex, const Color *clr);
Framebuffer* (*framebuffer_create)(void);
@ -88,11 +88,7 @@ typedef struct RendererFuncs {
void (*vertex_buffer_set_debug_label)(VertexBuffer *vbuf, const char *label);
void (*vertex_buffer_destroy)(VertexBuffer *vbuf);
void (*vertex_buffer_invalidate)(VertexBuffer *vbuf);
void (*vertex_buffer_write)(VertexBuffer *vbuf, size_t offset, size_t data_size, void *data);
void (*vertex_buffer_append)(VertexBuffer *vbuf, size_t data_size, void *data);
size_t (*vertex_buffer_get_capacity)(VertexBuffer *vbuf);
size_t (*vertex_buffer_get_cursor)(VertexBuffer *vbuf);
void (*vertex_buffer_set_cursor)(VertexBuffer *vbuf, size_t pos);
SDL_RWops* (*vertex_buffer_get_stream)(VertexBuffer *vbuf);
VertexArray* (*vertex_array_create)(void);
const char* (*vertex_array_get_debug_label)(VertexArray *varr);
@ -110,7 +106,7 @@ typedef struct RendererFuncs {
void (*swap)(SDL_Window *window);
uint8_t* (*screenshot)(uint *out_width, uint *out_height);
bool (*screenshot)(Pixmap *dst);
} RendererFuncs;
typedef struct RendererBackend {

View file

@ -26,10 +26,10 @@ void _r_models_init(void) {
}, fmt, 0);
GenericModelVertex quad[4] = {
{ { -0.5, -0.5, 0.0 }, { 0, 0, 1 }, { 0, 1 } },
{ { -0.5, 0.5, 0.0 }, { 0, 0, 1 }, { 0, 0 } },
{ { 0.5, 0.5, 0.0 }, { 0, 0, 1 }, { 1, 0 } },
{ { 0.5, -0.5, 0.0 }, { 0, 0, 1 }, { 1, 1 } },
{ { -0.5, -0.5, 0.0 }, { 0, 0, 1 }, { 0, 1 } },
{ { 0.5, 0.5, 0.0 }, { 0, 0, 1 }, { 1, 0 } },
{ { -0.5, 0.5, 0.0 }, { 0, 0, 1 }, { 0, 0 } },
};
_r_models.vbuf = r_vertex_buffer_create(8192 * sizeof(GenericModelVertex), NULL);
@ -40,7 +40,9 @@ void _r_models_init(void) {
r_vertex_array_layout(_r_models.varr, 3, fmt);
r_vertex_array_attach_buffer(_r_models.varr, _r_models.vbuf, 0);
r_vertex_buffer_append(_r_models.vbuf, sizeof(quad), quad);
SDL_RWops *stream = r_vertex_buffer_get_stream(_r_models.vbuf);
SDL_RWwrite(stream, quad, sizeof(quad), 1);
r_vertex_array(_r_models.varr);
}
@ -60,14 +62,14 @@ VertexArray* r_vertex_array_static_models(void) {
void r_draw_quad(void) {
VertexArray *varr_saved = r_vertex_array_current();
r_vertex_array(_r_models.varr);
r_draw(PRIM_TRIANGLE_FAN, 0, 4, NULL, 0, 0);
r_draw(PRIM_TRIANGLE_STRIP, 0, 4, NULL, 0, 0);
r_vertex_array(varr_saved);
}
void r_draw_quad_instanced(uint instances) {
VertexArray *varr_saved = r_vertex_array_current();
r_vertex_array(_r_models.varr);
r_draw(PRIM_TRIANGLE_FAN, 0, 4, NULL, instances, 0);
r_draw(PRIM_TRIANGLE_STRIP, 0, 4, NULL, instances, 0);
r_vertex_array(varr_saved);
}

View file

@ -9,30 +9,23 @@
#pragma once
#include "taisei.h"
typedef enum ShaderStage {
SHADER_STAGE_INVALID,
SHADER_STAGE_VERTEX,
SHADER_STAGE_FRAGMENT,
} ShaderStage;
typedef enum ShaderLanguage {
SHLANG_INVALID,
SHLANG_GLSL,
} ShaderLanguage;
typedef struct ShaderSource ShaderSource;
#include "shader_defs.h"
#include "shader_glsl.h"
#include "shader_spirv.h"
typedef struct ShaderLangInfo {
struct ShaderLangInfo {
ShaderLanguage lang;
union {
struct {
GLSLVersion version;
} glsl;
struct {
SPIRVTarget target;
} spirv;
};
}