mirror of
https://github.com/love2d/love.git
synced 2026-08-17 11:00:31 +02:00
Merge branch '12.0-development' into filesystem
This commit is contained in:
@@ -4218,7 +4218,7 @@
|
|||||||
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
08FB7793FE84155DC02AAC07 /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastUpgradeCheck = 1000;
|
LastUpgradeCheck = 1230;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
FA0B78DC1A958B90000E1D17 = {
|
FA0B78DC1A958B90000E1D17 = {
|
||||||
CreatedOnToolsVersion = 6.1.1;
|
CreatedOnToolsVersion = 6.1.1;
|
||||||
@@ -5063,7 +5063,7 @@
|
|||||||
10D5479E63C26BB35EB5482E /* Release */ = {
|
10D5479E63C26BB35EB5482E /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
@@ -5111,10 +5111,10 @@
|
|||||||
"\"$(SRCROOT)/../../src/modules\"",
|
"\"$(SRCROOT)/../../src/modules\"",
|
||||||
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
||||||
);
|
);
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
||||||
LIBRARY_SEARCH_PATHS = "";
|
LIBRARY_SEARCH_PATHS = "";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||||
ONLY_ACTIVE_ARCH = NO;
|
ONLY_ACTIVE_ARCH = NO;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
USE_HEADERMAP = NO;
|
USE_HEADERMAP = NO;
|
||||||
@@ -5125,7 +5125,7 @@
|
|||||||
64274E785071353E1A1D0D4B /* Debug */ = {
|
64274E785071353E1A1D0D4B /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
@@ -5177,10 +5177,10 @@
|
|||||||
"\"$(SRCROOT)/../../src/modules\"",
|
"\"$(SRCROOT)/../../src/modules\"",
|
||||||
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
||||||
);
|
);
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
||||||
LIBRARY_SEARCH_PATHS = "";
|
LIBRARY_SEARCH_PATHS = "";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
USE_HEADERMAP = NO;
|
USE_HEADERMAP = NO;
|
||||||
@@ -5312,7 +5312,7 @@
|
|||||||
FA5326C4189719C700F7BBF4 /* Distribution */ = {
|
FA5326C4189719C700F7BBF4 /* Distribution */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
@@ -5360,11 +5360,11 @@
|
|||||||
"\"$(SRCROOT)/../../src/modules\"",
|
"\"$(SRCROOT)/../../src/modules\"",
|
||||||
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
||||||
);
|
);
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
||||||
LIBRARY_SEARCH_PATHS = "";
|
LIBRARY_SEARCH_PATHS = "";
|
||||||
LLVM_LTO = YES;
|
LLVM_LTO = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||||
ONLY_ACTIVE_ARCH = NO;
|
ONLY_ACTIVE_ARCH = NO;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
USE_HEADERMAP = NO;
|
USE_HEADERMAP = NO;
|
||||||
@@ -5405,6 +5405,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/ios/libraries/freetype",
|
"$(PROJECT_DIR)/ios/libraries/freetype",
|
||||||
);
|
);
|
||||||
|
MARKETING_VERSION = 11.4;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-undefined",
|
"-undefined",
|
||||||
dynamic_lookup,
|
dynamic_lookup,
|
||||||
@@ -5448,6 +5449,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/ios/libraries/freetype",
|
"$(PROJECT_DIR)/ios/libraries/freetype",
|
||||||
);
|
);
|
||||||
|
MARKETING_VERSION = 11.4;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-undefined",
|
"-undefined",
|
||||||
dynamic_lookup,
|
dynamic_lookup,
|
||||||
@@ -5492,6 +5494,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"$(PROJECT_DIR)/ios/libraries/freetype",
|
"$(PROJECT_DIR)/ios/libraries/freetype",
|
||||||
);
|
);
|
||||||
|
MARKETING_VERSION = 11.4;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-undefined",
|
"-undefined",
|
||||||
dynamic_lookup,
|
dynamic_lookup,
|
||||||
|
|||||||
@@ -503,7 +503,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
@@ -557,9 +557,9 @@
|
|||||||
"\"$(SRCROOT)/../../src/modules\"",
|
"\"$(SRCROOT)/../../src/modules\"",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = "love-Info.plist";
|
INFOPLIST_FILE = "love-Info.plist";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
"OTHER_LDFLAGS[arch=x86_64]" = (
|
"OTHER_LDFLAGS[arch=x86_64]" = (
|
||||||
@@ -582,7 +582,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
@@ -638,10 +638,10 @@
|
|||||||
"\"$(SRCROOT)/../../src/modules\"",
|
"\"$(SRCROOT)/../../src/modules\"",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = "love-Info.plist";
|
INFOPLIST_FILE = "love-Info.plist";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
||||||
LLVM_LTO = YES;
|
LLVM_LTO = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||||
ONLY_ACTIVE_ARCH = NO;
|
ONLY_ACTIVE_ARCH = NO;
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
"OTHER_LDFLAGS[arch=x86_64]" = (
|
"OTHER_LDFLAGS[arch=x86_64]" = (
|
||||||
@@ -813,7 +813,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
|
CLANG_CXX_LANGUAGE_STANDARD = "c++17";
|
||||||
CLANG_CXX_LIBRARY = "libc++";
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CLANG_ENABLE_OBJC_ARC = YES;
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
@@ -869,10 +869,10 @@
|
|||||||
"\"$(SRCROOT)/../../src/modules\"",
|
"\"$(SRCROOT)/../../src/modules\"",
|
||||||
);
|
);
|
||||||
INFOPLIST_FILE = "love-Info.plist";
|
INFOPLIST_FILE = "love-Info.plist";
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
|
||||||
LLVM_LTO = YES;
|
LLVM_LTO = YES;
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.7;
|
MACOSX_DEPLOYMENT_TARGET = 10.9;
|
||||||
ONLY_ACTIVE_ARCH = NO;
|
ONLY_ACTIVE_ARCH = NO;
|
||||||
OTHER_LDFLAGS = "";
|
OTHER_LDFLAGS = "";
|
||||||
"OTHER_LDFLAGS[arch=x86_64]" = (
|
"OTHER_LDFLAGS[arch=x86_64]" = (
|
||||||
|
|||||||
@@ -148,7 +148,14 @@ bool openURL(const std::string &url)
|
|||||||
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
|
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
|
||||||
jclass activity = env->FindClass("org/love2d/android/GameActivity");
|
jclass activity = env->FindClass("org/love2d/android/GameActivity");
|
||||||
|
|
||||||
jmethodID openURL = env->GetStaticMethodID(activity, "openURL", "(Ljava/lang/String;)Z");
|
jmethodID openURL = env->GetStaticMethodID(activity, "openURLFromLOVE", "(Ljava/lang/String;)Z");
|
||||||
|
|
||||||
|
if (openURL == nullptr)
|
||||||
|
{
|
||||||
|
env->ExceptionClear();
|
||||||
|
openURL = env->GetStaticMethodID(activity, "openURL", "(Ljava/lang/String;)Z");
|
||||||
|
}
|
||||||
|
|
||||||
jstring url_jstring = (jstring) env->NewStringUTF(url.c_str());
|
jstring url_jstring = (jstring) env->NewStringUTF(url.c_str());
|
||||||
|
|
||||||
jboolean result = env->CallStaticBooleanMethod(activity, openURL, url_jstring);
|
jboolean result = env->CallStaticBooleanMethod(activity, openURL, url_jstring);
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ Shader *Graphics::newShader(const std::vector<std::string> &stagessource)
|
|||||||
if (!validstages[i])
|
if (!validstages[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (info.isStage[i])
|
if (info.stages[i] != Shader::ENTRYPOINT_NONE)
|
||||||
{
|
{
|
||||||
isanystage = true;
|
isanystage = true;
|
||||||
stages[i].set(newShaderStage((ShaderStage::StageType) i, source, info), Acquire::NORETAIN);
|
stages[i].set(newShaderStage((ShaderStage::StageType) i, source, info), Acquire::NORETAIN);
|
||||||
@@ -347,7 +347,7 @@ bool Graphics::validateShader(bool gles, const std::vector<std::string> &stagess
|
|||||||
if (!validstages[i])
|
if (!validstages[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (info.isStage[i])
|
if (info.stages[i] != Shader::ENTRYPOINT_NONE)
|
||||||
{
|
{
|
||||||
isanystage = true;
|
isanystage = true;
|
||||||
std::string glsl = Shader::createShaderStageCode(this, stype, source, info);
|
std::string glsl = Shader::createShaderStageCode(this, stype, source, info);
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ namespace graphics
|
|||||||
|
|
||||||
namespace glsl
|
namespace glsl
|
||||||
{
|
{
|
||||||
|
|
||||||
static const char global_syntax[] = R"(
|
static const char global_syntax[] = R"(
|
||||||
#if !defined(GL_ES) && __VERSION__ < 140
|
#if !defined(GL_ES) && __VERSION__ < 140
|
||||||
#define lowp
|
#define lowp
|
||||||
@@ -60,7 +61,11 @@ static const char global_syntax[] = R"(
|
|||||||
#define DepthCubeImage samplerCubeShadow
|
#define DepthCubeImage samplerCubeShadow
|
||||||
#endif
|
#endif
|
||||||
#define extern uniform
|
#define extern uniform
|
||||||
#ifdef GL_EXT_texture_array
|
#if defined(GL_EXT_texture_array) && (!defined(GL_ES) || __VERSION__ > 100 || defined(GL_OES_gpu_shader5))
|
||||||
|
// Only used when !GLSLES1 to work around Ouya driver bug. But we still want it
|
||||||
|
// enabled for glslang validation when glsl 1-on-3 is used, so also enable it if
|
||||||
|
// OES_gpu_shader5 exists.
|
||||||
|
#define LOVE_EXT_TEXTURE_ARRAY_ENABLED
|
||||||
#extension GL_EXT_texture_array : enable
|
#extension GL_EXT_texture_array : enable
|
||||||
#endif
|
#endif
|
||||||
#ifdef GL_OES_texture_3D
|
#ifdef GL_OES_texture_3D
|
||||||
@@ -122,7 +127,7 @@ void love_initializeBuiltinUniforms() {
|
|||||||
|
|
||||||
static const char global_functions[] = R"(
|
static const char global_functions[] = R"(
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
#if __VERSION__ >= 300 || defined(GL_EXT_texture_array)
|
#if __VERSION__ >= 300 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
|
||||||
precision lowp sampler2DArray;
|
precision lowp sampler2DArray;
|
||||||
#endif
|
#endif
|
||||||
#if __VERSION__ >= 300 || defined(GL_OES_texture_3D)
|
#if __VERSION__ >= 300 || defined(GL_OES_texture_3D)
|
||||||
@@ -158,7 +163,7 @@ static const char global_functions[] = R"(
|
|||||||
#if __VERSION__ > 100 || defined(GL_OES_texture_3D)
|
#if __VERSION__ > 100 || defined(GL_OES_texture_3D)
|
||||||
vec4 Texel(sampler3D s, vec3 c) { return love_texture3D(s, c); }
|
vec4 Texel(sampler3D s, vec3 c) { return love_texture3D(s, c); }
|
||||||
#endif
|
#endif
|
||||||
#if __VERSION__ >= 130 || defined(GL_EXT_texture_array)
|
#if __VERSION__ >= 130 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
|
||||||
vec4 Texel(sampler2DArray s, vec3 c) { return love_texture2DArray(s, c); }
|
vec4 Texel(sampler2DArray s, vec3 c) { return love_texture2DArray(s, c); }
|
||||||
#endif
|
#endif
|
||||||
#ifdef PIXEL
|
#ifdef PIXEL
|
||||||
@@ -167,7 +172,7 @@ static const char global_functions[] = R"(
|
|||||||
#if __VERSION__ > 100 || defined(GL_OES_texture_3D)
|
#if __VERSION__ > 100 || defined(GL_OES_texture_3D)
|
||||||
vec4 Texel(sampler3D s, vec3 c, float b) { return love_texture3D(s, c, b); }
|
vec4 Texel(sampler3D s, vec3 c, float b) { return love_texture3D(s, c, b); }
|
||||||
#endif
|
#endif
|
||||||
#if __VERSION__ >= 130 || defined(GL_EXT_texture_array)
|
#if __VERSION__ >= 130 || defined(LOVE_EXT_TEXTURE_ARRAY_ENABLED)
|
||||||
vec4 Texel(sampler2DArray s, vec3 c, float b) { return love_texture2DArray(s, c, b); }
|
vec4 Texel(sampler2DArray s, vec3 c, float b) { return love_texture2DArray(s, c, b); }
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -271,6 +276,16 @@ void main() {
|
|||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
static const char vertex_main_raw[] = R"(
|
||||||
|
void vertexmain();
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
love_initializeBuiltinUniforms();
|
||||||
|
setPointSize();
|
||||||
|
vertexmain();
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
static const char pixel_header[] = R"(
|
static const char pixel_header[] = R"(
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision mediump float;
|
precision mediump float;
|
||||||
@@ -280,29 +295,10 @@ static const char pixel_header[] = R"(
|
|||||||
|
|
||||||
#if __VERSION__ >= 130
|
#if __VERSION__ >= 130
|
||||||
#define varying in
|
#define varying in
|
||||||
// Some drivers seem to make the pixel shader do more work when multiple
|
|
||||||
// pixel shader outputs are defined, even when only one is actually used.
|
|
||||||
// TODO: We should use reflection or something instead of this, to determine
|
|
||||||
// how many outputs are actually used in the shader code.
|
|
||||||
#ifdef LOVE_MULTI_RENDER_TARGETS
|
|
||||||
layout(location = 0) out vec4 love_RenderTargets[love_MaxRenderTargets];
|
|
||||||
#define love_PixelColor love_RenderTargets[0]
|
|
||||||
#else
|
|
||||||
layout(location = 0) out vec4 love_PixelColor;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#ifdef LOVE_MULTI_RENDER_TARGETS
|
|
||||||
#define love_RenderTargets gl_FragData
|
|
||||||
#endif
|
|
||||||
#define love_PixelColor gl_FragColor
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Legacy
|
// Legacy
|
||||||
#define love_MaxCanvases love_MaxRenderTargets
|
#define love_MaxCanvases love_MaxRenderTargets
|
||||||
#define love_Canvases love_RenderTargets
|
|
||||||
#ifdef LOVE_MULTI_RENDER_TARGETS
|
|
||||||
#define LOVE_MULTI_CANVASES 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// See Shader::updateScreenParams in Shader.cpp.
|
// See Shader::updateScreenParams in Shader.cpp.
|
||||||
#define love_PixelCoord (vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w))
|
#define love_PixelCoord (vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w))
|
||||||
@@ -331,6 +327,12 @@ vec4 VideoTexel(vec2 texcoords) {
|
|||||||
)";
|
)";
|
||||||
|
|
||||||
static const char pixel_main[] = R"(
|
static const char pixel_main[] = R"(
|
||||||
|
#if __VERSION__ >= 130
|
||||||
|
layout(location = 0) out vec4 love_PixelColor;
|
||||||
|
#else
|
||||||
|
#define love_PixelColor gl_FragColor
|
||||||
|
#endif
|
||||||
|
|
||||||
uniform sampler2D MainTex;
|
uniform sampler2D MainTex;
|
||||||
varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
|
varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
|
||||||
varying mediump vec4 VaryingColor;
|
varying mediump vec4 VaryingColor;
|
||||||
@@ -344,6 +346,30 @@ void main() {
|
|||||||
)";
|
)";
|
||||||
|
|
||||||
static const char pixel_main_custom[] = R"(
|
static const char pixel_main_custom[] = R"(
|
||||||
|
#if __VERSION__ >= 130
|
||||||
|
// Some drivers seem to make the pixel shader do more work when multiple
|
||||||
|
// pixel shader outputs are defined, even when only one is actually used.
|
||||||
|
// TODO: We should use reflection or something instead of this, to determine
|
||||||
|
// how many outputs are actually used in the shader code.
|
||||||
|
#ifdef LOVE_MULTI_RENDER_TARGETS
|
||||||
|
layout(location = 0) out vec4 love_RenderTargets[love_MaxRenderTargets];
|
||||||
|
#define love_PixelColor love_RenderTargets[0]
|
||||||
|
#else
|
||||||
|
layout(location = 0) out vec4 love_PixelColor;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifdef LOVE_MULTI_RENDER_TARGETS
|
||||||
|
#define love_RenderTargets gl_FragData
|
||||||
|
#endif
|
||||||
|
#define love_PixelColor gl_FragColor
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Legacy
|
||||||
|
#define love_Canvases love_RenderTargets
|
||||||
|
#ifdef LOVE_MULTI_RENDER_TARGETS
|
||||||
|
#define LOVE_MULTI_CANVASES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
|
varying LOVE_HIGHP_OR_MEDIUMP vec4 VaryingTexCoord;
|
||||||
varying mediump vec4 VaryingColor;
|
varying mediump vec4 VaryingColor;
|
||||||
|
|
||||||
@@ -355,6 +381,15 @@ void main() {
|
|||||||
}
|
}
|
||||||
)";
|
)";
|
||||||
|
|
||||||
|
static const char pixel_main_raw[] = R"(
|
||||||
|
void pixelmain();
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
love_initializeBuiltinUniforms();
|
||||||
|
pixelmain();
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
|
||||||
struct StageInfo
|
struct StageInfo
|
||||||
{
|
{
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -362,12 +397,13 @@ struct StageInfo
|
|||||||
const char *functions;
|
const char *functions;
|
||||||
const char *main;
|
const char *main;
|
||||||
const char *main_custom;
|
const char *main_custom;
|
||||||
|
const char *main_raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const StageInfo stageInfo[] =
|
static const StageInfo stageInfo[] =
|
||||||
{
|
{
|
||||||
{ "VERTEX", vertex_header, vertex_functions, vertex_main, vertex_main },
|
{ "VERTEX", vertex_header, vertex_functions, vertex_main, vertex_main, vertex_main_raw },
|
||||||
{ "PIXEL", pixel_header, pixel_functions, pixel_main, pixel_main_custom },
|
{ "PIXEL", pixel_header, pixel_functions, pixel_main, pixel_main_custom, pixel_main_raw },
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert((sizeof(stageInfo) / sizeof(StageInfo)) == ShaderStage::STAGE_MAX_ENUM, "Stages array size must match ShaderStage enum.");
|
static_assert((sizeof(stageInfo) / sizeof(StageInfo)) == ShaderStage::STAGE_MAX_ENUM, "Stages array size must match ShaderStage enum.");
|
||||||
@@ -396,30 +432,38 @@ static Shader::Language getTargetLanguage(const std::string &src)
|
|||||||
return lang;
|
return lang;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isVertexCode(const std::string &src)
|
static Shader::EntryPoint getVertexEntryPoint(const std::string &src)
|
||||||
{
|
{
|
||||||
std::regex r("vec4\\s+position\\s*\\(");
|
|
||||||
std::smatch m;
|
std::smatch m;
|
||||||
return std::regex_search(src, m, r);
|
|
||||||
|
if (std::regex_search(src, m, std::regex("void\\s+vertexmain\\s*\\(")))
|
||||||
|
return Shader::ENTRYPOINT_RAW;
|
||||||
|
|
||||||
|
if (std::regex_search(src, m, std::regex("vec4\\s+position\\s*\\(")))
|
||||||
|
return Shader::ENTRYPOINT_HIGHLEVEL;
|
||||||
|
|
||||||
|
return Shader::ENTRYPOINT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isPixelCode(const std::string &src, bool &custompixel, bool &mrt)
|
static Shader::EntryPoint getPixelEntryPoint(const std::string &src, bool &mrt)
|
||||||
{
|
{
|
||||||
custompixel = false;
|
|
||||||
mrt = false;
|
mrt = false;
|
||||||
std::smatch m;
|
std::smatch m;
|
||||||
|
|
||||||
|
if (std::regex_search(src, m, std::regex("void\\s+pixelmain\\s*\\(")))
|
||||||
|
return Shader::ENTRYPOINT_RAW;
|
||||||
|
|
||||||
if (std::regex_search(src, m, std::regex("vec4\\s+effect\\s*\\(")))
|
if (std::regex_search(src, m, std::regex("vec4\\s+effect\\s*\\(")))
|
||||||
return true;
|
return Shader::ENTRYPOINT_HIGHLEVEL;
|
||||||
|
|
||||||
if (std::regex_search(src, m, std::regex("void\\s+effect\\s*\\(")))
|
if (std::regex_search(src, m, std::regex("void\\s+effect\\s*\\(")))
|
||||||
{
|
{
|
||||||
custompixel = true;
|
|
||||||
if (src.find("love_RenderTargets") != std::string::npos || src.find("love_Canvases") != std::string::npos)
|
if (src.find("love_RenderTargets") != std::string::npos || src.find("love_Canvases") != std::string::npos)
|
||||||
mrt = true;
|
mrt = true;
|
||||||
return true;
|
return Shader::ENTRYPOINT_CUSTOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return Shader::ENTRYPOINT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // glsl
|
} // glsl
|
||||||
@@ -435,8 +479,8 @@ Shader::SourceInfo Shader::getSourceInfo(const std::string &src)
|
|||||||
{
|
{
|
||||||
SourceInfo info = {};
|
SourceInfo info = {};
|
||||||
info.language = glsl::getTargetLanguage(src);
|
info.language = glsl::getTargetLanguage(src);
|
||||||
info.isStage[ShaderStage::STAGE_VERTEX] = glsl::isVertexCode(src);
|
info.stages[ShaderStage::STAGE_VERTEX] = glsl::getVertexEntryPoint(src);
|
||||||
info.isStage[ShaderStage::STAGE_PIXEL] = glsl::isPixelCode(src, info.customPixelFunction, info.usesMRT);
|
info.stages[ShaderStage::STAGE_PIXEL] = glsl::getPixelEntryPoint(src, info.usesMRT);
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,6 +489,12 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStage::StageType
|
|||||||
if (info.language == Shader::LANGUAGE_MAX_ENUM)
|
if (info.language == Shader::LANGUAGE_MAX_ENUM)
|
||||||
throw love::Exception("Invalid shader language");
|
throw love::Exception("Invalid shader language");
|
||||||
|
|
||||||
|
if (info.stages[stage] == ENTRYPOINT_NONE)
|
||||||
|
throw love::Exception("Cannot find entry point for shader stage.");
|
||||||
|
|
||||||
|
if (info.stages[stage] == ENTRYPOINT_RAW && info.language == LANGUAGE_GLSL1)
|
||||||
|
throw love::Exception("Shaders using a raw entry point (vertexmain or pixelmain) must use GLSL 3 or greater.");
|
||||||
|
|
||||||
const auto &features = gfx->getCapabilities().features;
|
const auto &features = gfx->getCapabilities().features;
|
||||||
|
|
||||||
if (info.language == LANGUAGE_GLSL3 && !features[Graphics::FEATURE_GLSL3])
|
if (info.language == LANGUAGE_GLSL3 && !features[Graphics::FEATURE_GLSL3])
|
||||||
@@ -477,7 +527,15 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStage::StageType
|
|||||||
ss << glsl::global_uniforms;
|
ss << glsl::global_uniforms;
|
||||||
ss << glsl::global_functions;
|
ss << glsl::global_functions;
|
||||||
ss << stageinfo.functions;
|
ss << stageinfo.functions;
|
||||||
ss << (info.customPixelFunction ? stageinfo.main_custom : stageinfo.main);
|
|
||||||
|
if (info.stages[stage] == ENTRYPOINT_HIGHLEVEL)
|
||||||
|
ss << stageinfo.main;
|
||||||
|
else if (info.stages[stage] == ENTRYPOINT_CUSTOM)
|
||||||
|
ss << stageinfo.main_custom;
|
||||||
|
else if (info.stages[stage] == ENTRYPOINT_RAW)
|
||||||
|
ss << stageinfo.main_raw;
|
||||||
|
else
|
||||||
|
throw love::Exception("Unknown shader entry point %d", info.stages[stage]);
|
||||||
ss << ((!gles && (lang == Shader::LANGUAGE_GLSL1 || glsl1on3)) ? "#line 0\n" : "#line 1\n");
|
ss << ((!gles && (lang == Shader::LANGUAGE_GLSL1 || glsl1on3)) ? "#line 0\n" : "#line 1\n");
|
||||||
ss << code;
|
ss << code;
|
||||||
|
|
||||||
|
|||||||
@@ -90,11 +90,18 @@ public:
|
|||||||
STANDARD_MAX_ENUM
|
STANDARD_MAX_ENUM
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum EntryPoint
|
||||||
|
{
|
||||||
|
ENTRYPOINT_NONE,
|
||||||
|
ENTRYPOINT_HIGHLEVEL,
|
||||||
|
ENTRYPOINT_CUSTOM,
|
||||||
|
ENTRYPOINT_RAW,
|
||||||
|
};
|
||||||
|
|
||||||
struct SourceInfo
|
struct SourceInfo
|
||||||
{
|
{
|
||||||
Language language;
|
Language language;
|
||||||
bool isStage[ShaderStage::STAGE_MAX_ENUM];
|
EntryPoint stages[ShaderStage::STAGE_MAX_ENUM];
|
||||||
bool customPixelFunction;
|
|
||||||
bool usesMRT;
|
bool usesMRT;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -316,8 +316,8 @@ bool Graphics::setMode(int width, int height, int pixelwidth, int pixelheight, b
|
|||||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||||
|
|
||||||
// Set whether drawing converts input from linear -> sRGB colorspace.
|
// Set whether drawing converts input from linear -> sRGB colorspace.
|
||||||
if (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB || GLAD_EXT_framebuffer_sRGB
|
if (!gl.bugs.brokenSRGB && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB
|
||||||
|| GLAD_ES_VERSION_3_0)
|
|| GLAD_EXT_framebuffer_sRGB || GLAD_ES_VERSION_3_0))
|
||||||
{
|
{
|
||||||
if (GLAD_VERSION_1_0 || GLAD_EXT_sRGB_write_control)
|
if (GLAD_VERSION_1_0 || GLAD_EXT_sRGB_write_control)
|
||||||
gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, isGammaCorrect());
|
gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, isGammaCorrect());
|
||||||
|
|||||||
@@ -150,6 +150,16 @@ bool OpenGL::initContext()
|
|||||||
if (strstr(device, "HD Graphics 4000") || strstr(device, "HD Graphics 2500"))
|
if (strstr(device, "HD Graphics 4000") || strstr(device, "HD Graphics 2500"))
|
||||||
bugs.clientWaitSyncStalls = true;
|
bugs.clientWaitSyncStalls = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (getVendor() == VENDOR_INTEL)
|
||||||
|
{
|
||||||
|
const char *device = (const char *) glGetString(GL_RENDERER);
|
||||||
|
if (strstr(device, "HD Graphics 3000") || strstr(device, "HD Graphics 2000")
|
||||||
|
|| !strcmp(device, "Intel(R) HD Graphics") || !strcmp(device, "Intel(R) HD Graphics Family"))
|
||||||
|
{
|
||||||
|
bugs.brokenSRGB = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LOVE_WINDOWS
|
#ifdef LOVE_WINDOWS
|
||||||
@@ -210,8 +220,8 @@ void OpenGL::setupContext()
|
|||||||
setEnableState(ENABLE_SCISSOR_TEST, state.enableState[ENABLE_SCISSOR_TEST]);
|
setEnableState(ENABLE_SCISSOR_TEST, state.enableState[ENABLE_SCISSOR_TEST]);
|
||||||
setEnableState(ENABLE_FACE_CULL, state.enableState[ENABLE_FACE_CULL]);
|
setEnableState(ENABLE_FACE_CULL, state.enableState[ENABLE_FACE_CULL]);
|
||||||
|
|
||||||
if (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB || GLAD_EXT_framebuffer_sRGB
|
if (!bugs.brokenSRGB && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_sRGB
|
||||||
|| GLAD_EXT_sRGB_write_control)
|
|| GLAD_EXT_framebuffer_sRGB || GLAD_EXT_sRGB_write_control))
|
||||||
{
|
{
|
||||||
setEnableState(ENABLE_FRAMEBUFFER_SRGB, state.enableState[ENABLE_FRAMEBUFFER_SRGB]);
|
setEnableState(ENABLE_FRAMEBUFFER_SRGB, state.enableState[ENABLE_FRAMEBUFFER_SRGB]);
|
||||||
}
|
}
|
||||||
@@ -391,15 +401,23 @@ void OpenGL::initOpenGLFunctions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GLAD_ES_VERSION_2_0 && GLAD_OES_texture_3D && !GLAD_ES_VERSION_3_0)
|
if (GLAD_ES_VERSION_2_0 && !GLAD_ES_VERSION_3_0)
|
||||||
{
|
{
|
||||||
// Function signatures don't match, we'll have to conditionally call it
|
// The Nvidia Tegra 3 driver (used by Ouya) claims to support GL_EXT_texture_array but
|
||||||
//fp_glTexImage3D = fp_glTexImage3DOES;
|
// segfaults if you actually try to use it. OpenGL ES 2.0 devices should use OES_texture_3D.
|
||||||
fp_glTexSubImage3D = fp_glTexSubImage3DOES;
|
// GL_EXT_texture_array is for desktops.
|
||||||
fp_glCopyTexSubImage3D = fp_glCopyTexSubImage3DOES;
|
GLAD_EXT_texture_array = false;
|
||||||
fp_glCompressedTexImage3D = fp_glCompressedTexImage3DOES;
|
|
||||||
fp_glCompressedTexSubImage3D = fp_glCompressedTexSubImage3DOES;
|
if (GLAD_OES_texture_3D)
|
||||||
fp_glFramebufferTexture3D = fp_glFramebufferTexture3DOES;
|
{
|
||||||
|
// Function signatures don't match, we'll have to conditionally call it
|
||||||
|
//fp_glTexImage3D = fp_glTexImage3DOES;
|
||||||
|
fp_glTexSubImage3D = fp_glTexSubImage3DOES;
|
||||||
|
fp_glCopyTexSubImage3D = fp_glCopyTexSubImage3DOES;
|
||||||
|
fp_glCompressedTexImage3D = fp_glCompressedTexImage3DOES;
|
||||||
|
fp_glCompressedTexSubImage3D = fp_glCompressedTexSubImage3DOES;
|
||||||
|
fp_glFramebufferTexture3D = fp_glFramebufferTexture3DOES;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!GLAD_VERSION_3_2 && !GLAD_ES_VERSION_3_2 && !GLAD_ARB_draw_elements_base_vertex)
|
if (!GLAD_VERSION_3_2 && !GLAD_ES_VERSION_3_2 && !GLAD_ARB_draw_elements_base_vertex)
|
||||||
@@ -1881,6 +1899,8 @@ bool OpenGL::isPixelFormatSupported(PixelFormat pixelformat, bool rendertarget,
|
|||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
case PIXELFORMAT_sRGBA8_UNORM:
|
case PIXELFORMAT_sRGBA8_UNORM:
|
||||||
|
if (gl.bugs.brokenSRGB)
|
||||||
|
return false;
|
||||||
if (rendertarget)
|
if (rendertarget)
|
||||||
{
|
{
|
||||||
if (GLAD_VERSION_1_0)
|
if (GLAD_VERSION_1_0)
|
||||||
|
|||||||
@@ -178,6 +178,13 @@ public:
|
|||||||
**/
|
**/
|
||||||
bool brokenR8PixelFormat;
|
bool brokenR8PixelFormat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intel HD Graphics drivers on Windows prior to the HD 2500/4000 have
|
||||||
|
* completely broken sRGB support.
|
||||||
|
* https://github.com/love2d/love/issues/1592
|
||||||
|
**/
|
||||||
|
bool brokenSRGB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Other bugs which have workarounds that don't use conditional code at
|
* Other bugs which have workarounds that don't use conditional code at
|
||||||
* the moment:
|
* the moment:
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace graphics
|
|||||||
namespace opengl
|
namespace opengl
|
||||||
{
|
{
|
||||||
|
|
||||||
static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat format, GLuint texture, int layers, bool clear)
|
static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat format, GLuint texture, int mips, int layers, bool clear)
|
||||||
{
|
{
|
||||||
// get currently bound fbo to reset to it later
|
// get currently bound fbo to reset to it later
|
||||||
GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
|
GLuint current_fbo = gl.getFramebuffer(OpenGL::FRAMEBUFFER_ALL);
|
||||||
@@ -42,11 +42,6 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
|
|||||||
glGenFramebuffers(1, &framebuffer);
|
glGenFramebuffers(1, &framebuffer);
|
||||||
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, framebuffer);
|
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, framebuffer);
|
||||||
|
|
||||||
// Intel driver bug: https://github.com/love2d/love/issues/1592
|
|
||||||
bool current_srgb = gl.isStateEnabled(OpenGL::ENABLE_FRAMEBUFFER_SRGB);
|
|
||||||
if (current_srgb && isPixelFormatDepthStencil(format))
|
|
||||||
gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, false);
|
|
||||||
|
|
||||||
if (texture != 0)
|
if (texture != 0)
|
||||||
{
|
{
|
||||||
if (isPixelFormatDepthStencil(format) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
|
if (isPixelFormatDepthStencil(format) && (GLAD_ES_VERSION_3_0 || !GLAD_ES_VERSION_2_0))
|
||||||
@@ -68,37 +63,40 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
|
|||||||
// Make sure all faces and layers of the texture are initialized to
|
// Make sure all faces and layers of the texture are initialized to
|
||||||
// transparent black. This is unfortunately probably pretty slow for
|
// transparent black. This is unfortunately probably pretty slow for
|
||||||
// 2D-array and 3D textures with a lot of layers...
|
// 2D-array and 3D textures with a lot of layers...
|
||||||
for (int layer = layers - 1; layer >= 0; layer--)
|
for (int mip = mips - 1; mip >= 0; mip--)
|
||||||
{
|
{
|
||||||
for (int face = faces - 1; face >= 0; face--)
|
for (int layer = layers - 1; layer >= 0; layer--)
|
||||||
{
|
{
|
||||||
for (GLenum attachment : fmt.framebufferAttachments)
|
for (int face = faces - 1; face >= 0; face--)
|
||||||
{
|
{
|
||||||
if (attachment == GL_NONE)
|
for (GLenum attachment : fmt.framebufferAttachments)
|
||||||
continue;
|
|
||||||
|
|
||||||
gl.framebufferTexture(attachment, texType, texture, 0, layer, face);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (clear)
|
|
||||||
{
|
|
||||||
if (isPixelFormatDepthStencil(format))
|
|
||||||
{
|
{
|
||||||
bool hadDepthWrites = gl.hasDepthWrites();
|
if (attachment == GL_NONE)
|
||||||
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
continue;
|
||||||
gl.setDepthWrites(true);
|
|
||||||
|
|
||||||
gl.clearDepth(1.0);
|
gl.framebufferTexture(attachment, texType, texture, mip, layer, face);
|
||||||
glClearStencil(0);
|
|
||||||
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
|
||||||
|
|
||||||
if (!hadDepthWrites)
|
|
||||||
gl.setDepthWrites(hadDepthWrites);
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (clear)
|
||||||
{
|
{
|
||||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
if (isPixelFormatDepthStencil(format))
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
{
|
||||||
|
bool hadDepthWrites = gl.hasDepthWrites();
|
||||||
|
if (!hadDepthWrites) // glDepthMask also affects glClear.
|
||||||
|
gl.setDepthWrites(true);
|
||||||
|
|
||||||
|
gl.clearDepth(1.0);
|
||||||
|
glClearStencil(0);
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
|
||||||
|
if (!hadDepthWrites)
|
||||||
|
gl.setDepthWrites(hadDepthWrites);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,10 +107,6 @@ static GLenum createFBO(GLuint &framebuffer, TextureType texType, PixelFormat fo
|
|||||||
|
|
||||||
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, current_fbo);
|
gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, current_fbo);
|
||||||
|
|
||||||
// Restore sRGB state if we turned it off above.
|
|
||||||
if (current_srgb && isPixelFormatDepthStencil(format))
|
|
||||||
gl.setEnableState(OpenGL::ENABLE_FRAMEBUFFER_SRGB, current_srgb);
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,28 +322,43 @@ void Texture::createTexture()
|
|||||||
|
|
||||||
bool hasdata = slices.get(0, 0) != nullptr;
|
bool hasdata = slices.get(0, 0) != nullptr;
|
||||||
|
|
||||||
|
// All mipmap levels need to be initialized - for color formats we can clear
|
||||||
|
// the base mip and use glGenerateMipmap after that's done. Depth and
|
||||||
|
// stencil formats don't always support glGenerateMipmap so we need to
|
||||||
|
// individually clear each mip level in that case. We avoid doing that for
|
||||||
|
// color formats because of an Intel driver bug:
|
||||||
|
// https://github.com/love2d/love/issues/1585
|
||||||
|
int clearmips = 1;
|
||||||
|
if (isPixelFormatDepthStencil(format))
|
||||||
|
clearmips = mipmapCount;
|
||||||
|
|
||||||
// Create a local FBO used for glReadPixels as well as MSAA blitting.
|
// Create a local FBO used for glReadPixels as well as MSAA blitting.
|
||||||
if (isRenderTarget())
|
if (isRenderTarget())
|
||||||
{
|
{
|
||||||
bool clear = !hasdata;
|
bool clear = !hasdata;
|
||||||
int slices = texType == TEXTURE_VOLUME ? depth : layers;
|
int slices = texType == TEXTURE_VOLUME ? depth : layers;
|
||||||
framebufferStatus = createFBO(fbo, texType, format, texture, slices, clear);
|
framebufferStatus = createFBO(fbo, texType, format, texture, clearmips, slices, clear);
|
||||||
}
|
}
|
||||||
else if (!hasdata)
|
else if (!hasdata)
|
||||||
{
|
{
|
||||||
// Initialize all slices to transparent black.
|
// Initialize all slices to transparent black.
|
||||||
std::vector<uint8> emptydata(getPixelFormatSliceSize(format, w, h));
|
for (int mip = 0; mip < clearmips; mip++)
|
||||||
|
{
|
||||||
|
int mipw = getPixelWidth(mip);
|
||||||
|
int miph = getPixelHeight(mip);
|
||||||
|
std::vector<uint8> emptydata(getPixelFormatSliceSize(format, mipw, miph));
|
||||||
|
|
||||||
Rect r = {0, 0, w, h};
|
Rect r = {0, 0, mipw, miph};
|
||||||
int slices = texType == TEXTURE_VOLUME ? depth : layers;
|
int slices = texType == TEXTURE_VOLUME ? getDepth(mip) : layers;
|
||||||
slices = texType == TEXTURE_CUBE ? 6 : slices;
|
slices = texType == TEXTURE_CUBE ? 6 : slices;
|
||||||
for (int i = 0; i < slices; i++)
|
for (int i = 0; i < slices; i++)
|
||||||
uploadByteData(format, emptydata.data(), emptydata.size(), 0, i, r);
|
uploadByteData(format, emptydata.data(), emptydata.size(), mip, i, r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-readable textures can't have mipmaps (enforced in the base class),
|
// Non-readable textures can't have mipmaps (enforced in the base class),
|
||||||
// so generateMipmaps here is fine - when they aren't already initialized.
|
// so generateMipmaps here is fine - when they aren't already initialized.
|
||||||
if (getMipmapCount() > 1 && slices.getMipmapCount() <= 1)
|
if (clearmips < mipmapCount && slices.getMipmapCount() <= 1 && getMipmapsMode() != MIPMAPS_NONE)
|
||||||
generateMipmaps();
|
generateMipmaps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -371,6 +371,23 @@ static int w_deprecation__gc(lua_State *)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void luax_addcompatibilityalias(lua_State *L, const char *module, const char *name, const char *alias)
|
||||||
|
{
|
||||||
|
lua_getglobal(L, module);
|
||||||
|
if (lua_istable(L, -1))
|
||||||
|
{
|
||||||
|
lua_getfield(L, -1, alias);
|
||||||
|
bool hasalias = !lua_isnoneornil(L, -1);
|
||||||
|
lua_pop(L, 1);
|
||||||
|
if (!hasalias)
|
||||||
|
{
|
||||||
|
lua_getfield(L, -1, name);
|
||||||
|
lua_setfield(L, -2, alias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
int luaopen_love(lua_State *L)
|
int luaopen_love(lua_State *L)
|
||||||
{
|
{
|
||||||
love::luax_insistpinnedthread(L);
|
love::luax_insistpinnedthread(L);
|
||||||
@@ -480,6 +497,13 @@ int luaopen_love(lua_State *L)
|
|||||||
love::luax_require(L, "love.data");
|
love::luax_require(L, "love.data");
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
#if LUA_VERSION_NUM <= 501
|
||||||
|
// These are deprecated in Lua 5.1. LuaJIT 2.1 removes them, but code
|
||||||
|
// written assuming LuaJIT 2.0 or Lua 5.1 is used might still rely on them.
|
||||||
|
luax_addcompatibilityalias(L, "math", "fmod", "mod");
|
||||||
|
luax_addcompatibilityalias(L, "string", "gmatch", "gfind");
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LOVE_ENABLE_LUASOCKET
|
#ifdef LOVE_ENABLE_LUASOCKET
|
||||||
love::luasocket::__open(L);
|
love::luasocket::__open(L);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -443,15 +443,23 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
|||||||
height = mode.h;
|
height = mode.h;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On Android we always must have fullscreen type FULLSCREEN_TYPE_DESKTOP
|
// On Android, disable fullscreen first on window creation so it's
|
||||||
|
// possible to change the orientation by specifying portait width and
|
||||||
|
// height, otherwise SDL will pick the current orientation dimensions when
|
||||||
|
// fullscreen flag is set. Don't worry, we'll set it back later when user
|
||||||
|
// also requested fullscreen after the window is created.
|
||||||
|
// See https://github.com/love2d/love-android/issues/196
|
||||||
#ifdef LOVE_ANDROID
|
#ifdef LOVE_ANDROID
|
||||||
|
bool fullscreen = f.fullscreen;
|
||||||
|
|
||||||
|
f.fullscreen = false;
|
||||||
f.fstype = FULLSCREEN_DESKTOP;
|
f.fstype = FULLSCREEN_DESKTOP;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int x = f.x;
|
int x = f.x;
|
||||||
int y = f.y;
|
int y = f.y;
|
||||||
|
|
||||||
if (f.useposition && !f.fullscreen)
|
if (f.useposition)
|
||||||
{
|
{
|
||||||
// The position needs to be in the global coordinate space.
|
// The position needs to be in the global coordinate space.
|
||||||
SDL_Rect displaybounds = {};
|
SDL_Rect displaybounds = {};
|
||||||
@@ -544,7 +552,7 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
|||||||
// Enforce minimum window dimensions.
|
// Enforce minimum window dimensions.
|
||||||
SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
|
SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
|
||||||
|
|
||||||
if (this->settings.display != f.display || ((f.useposition || f.centered) && !f.fullscreen))
|
if (this->settings.display != f.display || f.useposition || f.centered)
|
||||||
SDL_SetWindowPosition(window, x, y);
|
SDL_SetWindowPosition(window, x, y);
|
||||||
|
|
||||||
SDL_RaiseWindow(window);
|
SDL_RaiseWindow(window);
|
||||||
@@ -569,8 +577,11 @@ bool Window::setWindow(int width, int height, WindowSettings *settings)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set fullscreen when user requested it before.
|
||||||
|
// See above for explanation.
|
||||||
#ifdef LOVE_ANDROID
|
#ifdef LOVE_ANDROID
|
||||||
love::android::setImmersive(f.fullscreen);
|
setFullscreen(fullscreen);
|
||||||
|
love::android::setImmersive(fullscreen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user