mirror of
https://github.com/love2d/love.git
synced 2026-08-16 16:20:42 +02:00
Merge remote-tracking branch 'origin/12.0-development' into vulkan
This commit is contained in:
@@ -89,55 +89,35 @@ static const char render_uniforms[] = R"(
|
||||
// According to the GLSL ES 1.0 spec, uniform precision must match between stages,
|
||||
// but we can't guarantee that highp is always supported in fragment shaders...
|
||||
// We *really* don't want to use mediump for these in vertex shaders though.
|
||||
#ifdef LOVE_SPLIT_UNIFORMS_PER_DRAW
|
||||
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[12];
|
||||
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw2[1];
|
||||
#else
|
||||
uniform LOVE_HIGHP_OR_MEDIUMP vec4 love_UniformsPerDraw[13];
|
||||
#endif
|
||||
|
||||
// These are initialized in love_initializeBuiltinUniforms below. GLSL ES can't
|
||||
// do it as an initializer.
|
||||
LOVE_HIGHP_OR_MEDIUMP mat4 TransformMatrix;
|
||||
LOVE_HIGHP_OR_MEDIUMP mat4 ProjectionMatrix;
|
||||
LOVE_HIGHP_OR_MEDIUMP mat3 NormalMatrix;
|
||||
|
||||
LOVE_HIGHP_OR_MEDIUMP vec4 love_ScreenSize;
|
||||
LOVE_HIGHP_OR_MEDIUMP vec4 ConstantColor;
|
||||
|
||||
LOVE_HIGHP_OR_MEDIUMP float CurrentDPIScale;
|
||||
|
||||
LOVE_HIGHP_OR_MEDIUMP float ConstantPointSize;
|
||||
|
||||
// Older GLSL doesn't support preprocessor line continuations...
|
||||
#define TransformMatrix mat4(love_UniformsPerDraw[0], love_UniformsPerDraw[1], love_UniformsPerDraw[2], love_UniformsPerDraw[3])
|
||||
#define ProjectionMatrix mat4(love_UniformsPerDraw[4], love_UniformsPerDraw[5], love_UniformsPerDraw[6], love_UniformsPerDraw[7])
|
||||
#define TransformProjectionMatrix (ProjectionMatrix * TransformMatrix)
|
||||
|
||||
#define NormalMatrix mat3(love_UniformsPerDraw[8].xyz, love_UniformsPerDraw[9].xyz, love_UniformsPerDraw[10].xyz)
|
||||
|
||||
#define CurrentDPIScale (love_UniformsPerDraw[8].w)
|
||||
#define ConstantPointSize (love_UniformsPerDraw[9].w)
|
||||
#define ConstantColor (love_UniformsPerDraw[11])
|
||||
|
||||
#ifdef LOVE_SPLIT_UNIFORMS_PER_DRAW
|
||||
#define love_ScreenSize (love_UniformsPerDraw2[0])
|
||||
#else
|
||||
#define love_ScreenSize (love_UniformsPerDraw[12])
|
||||
#endif
|
||||
|
||||
// Alternate names
|
||||
#define ViewSpaceFromLocal TransformMatrix
|
||||
#define ClipSpaceFromView ProjectionMatrix
|
||||
#define ClipSpaceFromLocal TransformProjectionMatrix
|
||||
#define ViewNormalFromLocal NormalMatrix
|
||||
|
||||
void love_initializeBuiltinUniforms() {
|
||||
TransformMatrix = mat4(
|
||||
love_UniformsPerDraw[0],
|
||||
love_UniformsPerDraw[1],
|
||||
love_UniformsPerDraw[2],
|
||||
love_UniformsPerDraw[3]
|
||||
);
|
||||
|
||||
ProjectionMatrix = mat4(
|
||||
love_UniformsPerDraw[4],
|
||||
love_UniformsPerDraw[5],
|
||||
love_UniformsPerDraw[6],
|
||||
love_UniformsPerDraw[7]
|
||||
);
|
||||
|
||||
NormalMatrix = mat3(
|
||||
love_UniformsPerDraw[8].xyz,
|
||||
love_UniformsPerDraw[9].xyz,
|
||||
love_UniformsPerDraw[10].xyz
|
||||
);
|
||||
|
||||
CurrentDPIScale = love_UniformsPerDraw[8].w;
|
||||
ConstantPointSize = love_UniformsPerDraw[9].w;
|
||||
love_ScreenSize = love_UniformsPerDraw[11];
|
||||
ConstantColor = love_UniformsPerDraw[12];
|
||||
}
|
||||
)";
|
||||
|
||||
static const char global_functions[] = R"(
|
||||
@@ -274,7 +254,6 @@ LOVE_IO_LOCATION(1) varying vec4 VaryingColor;
|
||||
vec4 position(mat4 clipSpaceFromLocal, vec4 localPosition);
|
||||
|
||||
void main() {
|
||||
love_initializeBuiltinUniforms();
|
||||
VaryingTexCoord = VertexTexCoord;
|
||||
VaryingColor = gammaCorrectColor(VertexColor) * ConstantColor;
|
||||
love_Position = position(ClipSpaceFromLocal, VertexPosition);
|
||||
@@ -285,7 +264,6 @@ static const char vertex_main_raw[] = R"(
|
||||
void vertexmain();
|
||||
|
||||
void main() {
|
||||
love_initializeBuiltinUniforms();
|
||||
vertexmain();
|
||||
}
|
||||
)";
|
||||
@@ -344,7 +322,6 @@ LOVE_IO_LOCATION(1) varying mediump vec4 VaryingColor;
|
||||
vec4 effect(vec4 vcolor, Image tex, vec2 texcoord, vec2 pixcoord);
|
||||
|
||||
void main() {
|
||||
love_initializeBuiltinUniforms();
|
||||
love_PixelColor = effect(VaryingColor, MainTex, VaryingTexCoord.st, love_PixelCoord);
|
||||
}
|
||||
)";
|
||||
@@ -380,7 +357,6 @@ LOVE_IO_LOCATION(1) varying mediump vec4 VaryingColor;
|
||||
void effect();
|
||||
|
||||
void main() {
|
||||
love_initializeBuiltinUniforms();
|
||||
effect();
|
||||
}
|
||||
)";
|
||||
@@ -389,7 +365,6 @@ static const char pixel_main_raw[] = R"(
|
||||
void pixelmain();
|
||||
|
||||
void main() {
|
||||
love_initializeBuiltinUniforms();
|
||||
pixelmain();
|
||||
}
|
||||
)";
|
||||
@@ -404,7 +379,6 @@ static const char compute_header[] = R"(
|
||||
)";
|
||||
|
||||
static const char compute_uniforms[] = R"(
|
||||
void love_initializeBuiltinUniforms() {}
|
||||
)";
|
||||
|
||||
static const char compute_functions[] = R"()";
|
||||
@@ -413,7 +387,6 @@ static const char compute_main[] = R"(
|
||||
void computemain();
|
||||
|
||||
void main() {
|
||||
love_initializeBuiltinUniforms();
|
||||
computemain();
|
||||
}
|
||||
)";
|
||||
@@ -575,7 +548,12 @@ std::string Shader::createShaderStageCode(Graphics *gfx, ShaderStageType stage,
|
||||
if (info.usesMRT)
|
||||
ss << "#define LOVE_MULTI_RENDER_TARGETS 1\n";
|
||||
|
||||
for (const auto& def : options.defines)
|
||||
// Note: backends are expected to handle this situation if highp is ever
|
||||
// conditional in that backend.
|
||||
if (!gfx->getCapabilities().features[Graphics::FEATURE_PIXEL_SHADER_HIGHP])
|
||||
ss << "#define LOVE_SPLIT_UNIFORMS_PER_DRAW 1";
|
||||
|
||||
for (const auto &def : options.defines)
|
||||
ss << "#define " + def.first + " " + def.second + "\n";
|
||||
|
||||
ss << "#define " << stageinfo.name << " " << stageinfo.name << "\n";
|
||||
@@ -1204,11 +1182,12 @@ static StringMap<Shader::Language, Shader::LANGUAGE_MAX_ENUM> languages(language
|
||||
|
||||
static StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM>::Entry builtinNameEntries[] =
|
||||
{
|
||||
{ "MainTex", Shader::BUILTIN_TEXTURE_MAIN },
|
||||
{ "love_VideoYChannel", Shader::BUILTIN_TEXTURE_VIDEO_Y },
|
||||
{ "love_VideoCbChannel", Shader::BUILTIN_TEXTURE_VIDEO_CB },
|
||||
{ "love_VideoCrChannel", Shader::BUILTIN_TEXTURE_VIDEO_CR },
|
||||
{ "love_UniformsPerDraw", Shader::BUILTIN_UNIFORMS_PER_DRAW },
|
||||
{ "MainTex", Shader::BUILTIN_TEXTURE_MAIN },
|
||||
{ "love_VideoYChannel", Shader::BUILTIN_TEXTURE_VIDEO_Y },
|
||||
{ "love_VideoCbChannel", Shader::BUILTIN_TEXTURE_VIDEO_CB },
|
||||
{ "love_VideoCrChannel", Shader::BUILTIN_TEXTURE_VIDEO_CR },
|
||||
{ "love_UniformsPerDraw", Shader::BUILTIN_UNIFORMS_PER_DRAW },
|
||||
{ "love_UniformsPerDraw2", Shader::BUILTIN_UNIFORMS_PER_DRAW_2 },
|
||||
};
|
||||
|
||||
static StringMap<Shader::BuiltinUniform, Shader::BUILTIN_MAX_ENUM> builtinNames(builtinNameEntries, sizeof(builtinNameEntries));
|
||||
|
||||
@@ -64,6 +64,7 @@ public:
|
||||
BUILTIN_TEXTURE_VIDEO_CB,
|
||||
BUILTIN_TEXTURE_VIDEO_CR,
|
||||
BUILTIN_UNIFORMS_PER_DRAW,
|
||||
BUILTIN_UNIFORMS_PER_DRAW_2,
|
||||
BUILTIN_MAX_ENUM
|
||||
};
|
||||
|
||||
@@ -176,8 +177,10 @@ public:
|
||||
Matrix4 transformMatrix;
|
||||
Matrix4 projectionMatrix;
|
||||
Vector4 normalMatrix[3]; // 3x3 matrix padded to an array of 3 vector4s.
|
||||
Vector4 screenSizeParams;
|
||||
Colorf constantColor;
|
||||
|
||||
// Pixel shader-centric variables past this point.
|
||||
Vector4 screenSizeParams;
|
||||
};
|
||||
|
||||
// Pointer to currently active Shader.
|
||||
|
||||
@@ -46,6 +46,7 @@ static bool isBuffer(Shader::UniformType utype)
|
||||
Shader::Shader(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM])
|
||||
: love::graphics::Shader(stages)
|
||||
, program(0)
|
||||
, splitUniformsPerDraw(false)
|
||||
, builtinUniforms()
|
||||
, builtinUniformInfo()
|
||||
{
|
||||
@@ -486,6 +487,11 @@ bool Shader::loadVolatile()
|
||||
{
|
||||
OpenGL::TempDebugGroup debuggroup("Shader load");
|
||||
|
||||
// love::graphics::Shader sets up the shader code-side of this.
|
||||
auto gfx = Module::getInstance<love::graphics::Graphics>(Module::M_GRAPHICS);
|
||||
if (gfx != nullptr)
|
||||
splitUniformsPerDraw = gfx->getCapabilities().features[Graphics::FEATURE_PIXEL_SHADER_HIGHP];
|
||||
|
||||
// zero out active texture list
|
||||
textureUnits.clear();
|
||||
textureUnits.push_back(TextureUnit());
|
||||
@@ -1014,9 +1020,27 @@ void Shader::updateBuiltinUniforms(love::graphics::Graphics *gfx, int viewportW,
|
||||
data.constantColor = gfx->getColor();
|
||||
gammaCorrectColor(data.constantColor);
|
||||
|
||||
GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
|
||||
if (location >= 0)
|
||||
glUniform4fv(location, 13, (const GLfloat *) &data);
|
||||
// This branch is to avoid always declaring the whole array as highp in the
|
||||
// vertex shader and mediump in the pixel shader for love's default shaders,
|
||||
// on systems that don't support highp in pixel shaders. The default shaders
|
||||
// use the transform matrices in vertex shaders and screen size params in
|
||||
// pixel shaders. If there's a single array containing both and each shader
|
||||
// stage declares a different precision, that's a compile error.
|
||||
if (splitUniformsPerDraw)
|
||||
{
|
||||
GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
|
||||
if (location >= 0)
|
||||
glUniform4fv(location, 12, (const GLfloat *) &data);
|
||||
GLint location2 = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW_2];
|
||||
if (location2 >= 0)
|
||||
glUniform4fv(location2, 1, (const GLfloat *) &data.screenSizeParams);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLint location = builtinUniforms[BUILTIN_UNIFORMS_PER_DRAW];
|
||||
if (location >= 0)
|
||||
glUniform4fv(location, 13, (const GLfloat *) &data);
|
||||
}
|
||||
}
|
||||
|
||||
int Shader::getUniformTypeComponents(GLenum type) const
|
||||
|
||||
@@ -112,6 +112,8 @@ private:
|
||||
// volatile
|
||||
GLuint program;
|
||||
|
||||
bool splitUniformsPerDraw;
|
||||
|
||||
// Location values for any built-in uniform variables.
|
||||
GLint builtinUniforms[BUILTIN_MAX_ENUM];
|
||||
UniformInfo *builtinUniformInfo[BUILTIN_MAX_ENUM];
|
||||
|
||||
@@ -58,16 +58,20 @@ STRINGMAP_CLASS_END(Joystick, Joystick::Hat, Joystick::HAT_MAX_ENUM, hat)
|
||||
|
||||
STRINGMAP_CLASS_BEGIN(Joystick, Joystick::GamepadType, Joystick::GAMEPAD_TYPE_MAX_ENUM, gamepadType)
|
||||
{
|
||||
{ "unknown", Joystick::GAMEPAD_TYPE_UNKNOWN },
|
||||
{ "xbox360", Joystick::GAMEPAD_TYPE_XBOX360 },
|
||||
{ "xboxone", Joystick::GAMEPAD_TYPE_XBOXONE },
|
||||
{ "ps3", Joystick::GAMEPAD_TYPE_PS3 },
|
||||
{ "ps4", Joystick::GAMEPAD_TYPE_PS4 },
|
||||
{ "ps5", Joystick::GAMEPAD_TYPE_PS5 },
|
||||
{ "switchpro", Joystick::GAMEPAD_TYPE_NINTENDO_SWITCH_PRO },
|
||||
{ "amazonluna", Joystick::GAMEPAD_TYPE_AMAZON_LUNA },
|
||||
{ "stadia", Joystick::GAMEPAD_TYPE_STADIA },
|
||||
{ "virtual", Joystick::GAMEPAD_TYPE_VIRTUAL },
|
||||
{ "unknown", Joystick::GAMEPAD_TYPE_UNKNOWN },
|
||||
{ "xbox360", Joystick::GAMEPAD_TYPE_XBOX360 },
|
||||
{ "xboxone", Joystick::GAMEPAD_TYPE_XBOXONE },
|
||||
{ "ps3", Joystick::GAMEPAD_TYPE_PS3 },
|
||||
{ "ps4", Joystick::GAMEPAD_TYPE_PS4 },
|
||||
{ "ps5", Joystick::GAMEPAD_TYPE_PS5 },
|
||||
{ "switchpro", Joystick::GAMEPAD_TYPE_NINTENDO_SWITCH_PRO },
|
||||
{ "amazonluna", Joystick::GAMEPAD_TYPE_AMAZON_LUNA },
|
||||
{ "stadia", Joystick::GAMEPAD_TYPE_STADIA },
|
||||
{ "virtual", Joystick::GAMEPAD_TYPE_VIRTUAL },
|
||||
{ "shield", Joystick::GAMEPAD_TYPE_NVIDIA_SHIELD },
|
||||
{ "joyconleft", Joystick::GAMEPAD_TYPE_JOYCON_LEFT },
|
||||
{ "joyconright", Joystick::GAMEPAD_TYPE_JOYCON_RIGHT },
|
||||
{ "joyconpair", Joystick::GAMEPAD_TYPE_JOYCON_PAIR },
|
||||
}
|
||||
STRINGMAP_CLASS_END(Joystick, Joystick::GamepadType, Joystick::GAMEPAD_TYPE_MAX_ENUM, gamepadType)
|
||||
|
||||
|
||||
@@ -68,6 +68,10 @@ public:
|
||||
GAMEPAD_TYPE_AMAZON_LUNA,
|
||||
GAMEPAD_TYPE_STADIA,
|
||||
GAMEPAD_TYPE_VIRTUAL,
|
||||
GAMEPAD_TYPE_NVIDIA_SHIELD,
|
||||
GAMEPAD_TYPE_JOYCON_LEFT,
|
||||
GAMEPAD_TYPE_JOYCON_RIGHT,
|
||||
GAMEPAD_TYPE_JOYCON_PAIR,
|
||||
GAMEPAD_TYPE_MAX_ENUM
|
||||
};
|
||||
|
||||
|
||||
@@ -260,6 +260,12 @@ Joystick::GamepadType Joystick::getGamepadType() const
|
||||
#if SDL_VERSION_ATLEAST(2, 0, 16)
|
||||
case SDL_CONTROLLER_TYPE_AMAZON_LUNA: return GAMEPAD_TYPE_AMAZON_LUNA;
|
||||
case SDL_CONTROLLER_TYPE_GOOGLE_STADIA: return GAMEPAD_TYPE_STADIA;
|
||||
#endif
|
||||
#if SDL_VERSION_ATLEAST(2, 24, 0)
|
||||
case SDL_CONTROLLER_TYPE_NVIDIA_SHIELD: return GAMEPAD_TYPE_NVIDIA_SHIELD;
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_LEFT: return GAMEPAD_TYPE_JOYCON_LEFT;
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_RIGHT: return GAMEPAD_TYPE_JOYCON_RIGHT;
|
||||
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_JOYCON_PAIR: return GAMEPAD_TYPE_JOYCON_PAIR;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
@@ -509,7 +515,7 @@ bool Joystick::setVibration(float left, float right, float duration)
|
||||
Uint32 length = SDL_HAPTIC_INFINITY;
|
||||
if (duration >= 0.0f)
|
||||
{
|
||||
float maxduration = std::numeric_limits<Uint32>::max() / 1000.0f;
|
||||
float maxduration = (float) (std::numeric_limits<Uint32>::max() / 1000.0);
|
||||
length = Uint32(std::min(duration, maxduration) * 1000);
|
||||
}
|
||||
|
||||
|
||||
@@ -171,6 +171,28 @@ bool World::QueryCallback::ReportFixture(b2Fixture *fixture)
|
||||
return true;
|
||||
}
|
||||
|
||||
World::CollectCallback::CollectCallback(World *world, lua_State *L)
|
||||
: world(world)
|
||||
, L(L)
|
||||
{
|
||||
lua_newtable(L);
|
||||
}
|
||||
|
||||
World::CollectCallback::~CollectCallback()
|
||||
{
|
||||
}
|
||||
|
||||
bool World::CollectCallback::ReportFixture(b2Fixture *f)
|
||||
{
|
||||
Fixture *fixture = (Fixture *)world->findObject(f);
|
||||
if (!fixture)
|
||||
throw love::Exception("A fixture has escaped Memoizer!");
|
||||
luax_pushtype(L, fixture);
|
||||
lua_rawseti(L, -2, i);
|
||||
i++;
|
||||
return true;
|
||||
}
|
||||
|
||||
World::RayCastCallback::RayCastCallback(World *world, lua_State *L, int idx)
|
||||
: world(world)
|
||||
, L(L)
|
||||
@@ -556,6 +578,20 @@ int World::queryBoundingBox(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int World::getFixturesInArea(lua_State *L)
|
||||
{
|
||||
float lx = (float)luaL_checknumber(L, 1);
|
||||
float ly = (float)luaL_checknumber(L, 2);
|
||||
float ux = (float)luaL_checknumber(L, 3);
|
||||
float uy = (float)luaL_checknumber(L, 4);
|
||||
b2AABB box;
|
||||
box.lowerBound = Physics::scaleDown(b2Vec2(lx, ly));
|
||||
box.upperBound = Physics::scaleDown(b2Vec2(ux, uy));
|
||||
CollectCallback query(this, L);
|
||||
world->QueryAABB(&query, box);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int World::rayCast(lua_State *L)
|
||||
{
|
||||
float x1 = (float)luaL_checknumber(L, 1);
|
||||
|
||||
@@ -102,6 +102,18 @@ public:
|
||||
int funcidx;
|
||||
};
|
||||
|
||||
class CollectCallback : public b2QueryCallback
|
||||
{
|
||||
public:
|
||||
CollectCallback(World *world, lua_State *L);
|
||||
~CollectCallback();
|
||||
virtual bool ReportFixture(b2Fixture *fixture);
|
||||
private:
|
||||
World *world;
|
||||
lua_State *L;
|
||||
int i = 1;
|
||||
};
|
||||
|
||||
class RayCastCallback : public b2RayCastCallback
|
||||
{
|
||||
public:
|
||||
@@ -270,10 +282,15 @@ public:
|
||||
b2Body *getGroundBody() const;
|
||||
|
||||
/**
|
||||
* Gets all fixtures that overlap a given bounding box.
|
||||
* Calls a callback on all fixtures that overlap a given bounding box.
|
||||
**/
|
||||
int queryBoundingBox(lua_State *L);
|
||||
|
||||
/**
|
||||
* Gets all fixtures that overlap a given bounding box.
|
||||
**/
|
||||
int getFixturesInArea(lua_State *L);
|
||||
|
||||
/**
|
||||
* Raycasts the World for all Fixtures in the path of the ray.
|
||||
**/
|
||||
|
||||
@@ -185,6 +185,15 @@ int w_World_queryBoundingBox(lua_State *L)
|
||||
return t->queryBoundingBox(L);
|
||||
}
|
||||
|
||||
int w_World_getFixturesInArea(lua_State *L)
|
||||
{
|
||||
World *t = luax_checkworld(L, 1);
|
||||
lua_remove(L, 1);
|
||||
int ret = 0;
|
||||
luax_catchexcept(L, [&](){ ret = t->getFixturesInArea(L); });
|
||||
return ret;
|
||||
}
|
||||
|
||||
int w_World_rayCast(lua_State *L)
|
||||
{
|
||||
World *t = luax_checkworld(L, 1);
|
||||
@@ -228,6 +237,7 @@ static const luaL_Reg w_World_functions[] =
|
||||
{ "getJoints", w_World_getJoints },
|
||||
{ "getContacts", w_World_getContacts },
|
||||
{ "queryBoundingBox", w_World_queryBoundingBox },
|
||||
{ "getFixturesInArea", w_World_getFixturesInArea },
|
||||
{ "rayCast", w_World_rayCast },
|
||||
{ "destroy", w_World_destroy },
|
||||
{ "isDestroyed", w_World_isDestroyed },
|
||||
|
||||
@@ -39,7 +39,14 @@ Decoder::Decoder(Stream *stream, int bufferSize)
|
||||
if (!stream->isReadable() || !stream->isSeekable())
|
||||
throw love::Exception("Decoder input stream must be readable and seekable.");
|
||||
|
||||
buffer = new char[bufferSize];
|
||||
try
|
||||
{
|
||||
buffer = new char[bufferSize];
|
||||
}
|
||||
catch (std::exception &)
|
||||
{
|
||||
throw love::Exception("Out of memory.");
|
||||
}
|
||||
}
|
||||
|
||||
Decoder::~Decoder()
|
||||
|
||||
Reference in New Issue
Block a user