mirror of
https://github.com/love2d/love-android.git
synced 2026-08-17 19:24:07 +02:00
updated to latest mobile-common branch of Löve
This commit is contained in:
@@ -27,9 +27,9 @@ namespace love
|
|||||||
// Version stuff.
|
// Version stuff.
|
||||||
const int VERSION_MAJOR = 0;
|
const int VERSION_MAJOR = 0;
|
||||||
const int VERSION_MINOR = 9;
|
const int VERSION_MINOR = 9;
|
||||||
const int VERSION_REV = 0;
|
const int VERSION_REV = 1;
|
||||||
const char *VERSION = "0.9.0";
|
const char *VERSION = "0.9.1";
|
||||||
const char *VERSION_COMPATIBILITY[] = { VERSION, 0 };
|
const char *VERSION_COMPATIBILITY[] = { VERSION, "0.9.0", 0 };
|
||||||
const char *VERSION_CODENAME = "Baby Inspector";
|
const char *VERSION_CODENAME = "Baby Inspector";
|
||||||
|
|
||||||
} // love
|
} // love
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public:
|
|||||||
* Play the specified Source.
|
* Play the specified Source.
|
||||||
* @param source The Source to play.
|
* @param source The Source to play.
|
||||||
**/
|
**/
|
||||||
virtual void play(Source *source) = 0;
|
virtual bool play(Source *source) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops playback on the specified source.
|
* Stops playback on the specified source.
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ public:
|
|||||||
|
|
||||||
virtual Source *clone() = 0;
|
virtual Source *clone() = 0;
|
||||||
|
|
||||||
virtual void play() = 0;
|
virtual bool play() = 0;
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
virtual void pause() = 0;
|
virtual void pause() = 0;
|
||||||
virtual void resume() = 0;
|
virtual void resume() = 0;
|
||||||
|
|||||||
@@ -61,12 +61,9 @@ int Audio::getMaxSources() const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::play(love::audio::Source *)
|
bool Audio::play(love::audio::Source *)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Audio::play()
|
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::stop(love::audio::Source *)
|
void Audio::stop(love::audio::Source *)
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ public:
|
|||||||
love::audio::Source *newSource(love::sound::SoundData *soundData);
|
love::audio::Source *newSource(love::sound::SoundData *soundData);
|
||||||
int getSourceCount() const;
|
int getSourceCount() const;
|
||||||
int getMaxSources() const;
|
int getMaxSources() const;
|
||||||
void play(love::audio::Source *source);
|
bool play(love::audio::Source *source);
|
||||||
void play();
|
|
||||||
void stop(love::audio::Source *source);
|
void stop(love::audio::Source *source);
|
||||||
void stop();
|
void stop();
|
||||||
void pause(love::audio::Source *source);
|
void pause(love::audio::Source *source);
|
||||||
|
|||||||
@@ -42,8 +42,9 @@ love::audio::Source *Source::clone()
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Source::play()
|
bool Source::play()
|
||||||
{
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Source::stop()
|
void Source::stop()
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public:
|
|||||||
virtual ~Source();
|
virtual ~Source();
|
||||||
|
|
||||||
virtual love::audio::Source *clone();
|
virtual love::audio::Source *clone();
|
||||||
virtual void play();
|
virtual bool play();
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
virtual void pause();
|
virtual void pause();
|
||||||
virtual void resume();
|
virtual void resume();
|
||||||
|
|||||||
@@ -69,22 +69,25 @@ void Audio::PoolThread::setFinish()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Audio::Audio()
|
Audio::Audio()
|
||||||
: distanceModel(DISTANCE_INVERSE_CLAMPED)
|
: device(nullptr)
|
||||||
|
, capture(nullptr)
|
||||||
|
, context(nullptr)
|
||||||
|
, pool(nullptr)
|
||||||
|
, poolThread(nullptr)
|
||||||
|
, distanceModel(DISTANCE_INVERSE_CLAMPED)
|
||||||
{
|
{
|
||||||
// Passing zero for default device.
|
// Passing null for default device.
|
||||||
device = alcOpenDevice(0);
|
device = alcOpenDevice(nullptr);
|
||||||
|
|
||||||
if (device == 0)
|
if (device == nullptr)
|
||||||
throw love::Exception("Could not open device.");
|
throw love::Exception("Could not open device.");
|
||||||
|
|
||||||
context = alcCreateContext(device, 0);
|
context = alcCreateContext(device, nullptr);
|
||||||
|
|
||||||
if (context == 0)
|
if (context == nullptr)
|
||||||
throw love::Exception("Could not create context.");
|
throw love::Exception("Could not create context.");
|
||||||
|
|
||||||
alcMakeContextCurrent(context);
|
if (!alcMakeContextCurrent(context) || alcGetError(device) != ALC_NO_ERROR)
|
||||||
|
|
||||||
if (alcGetError(device) != ALC_NO_ERROR)
|
|
||||||
throw love::Exception("Could not make context current.");
|
throw love::Exception("Could not make context current.");
|
||||||
|
|
||||||
/*std::string captureName(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
|
/*std::string captureName(alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
|
||||||
@@ -108,7 +111,18 @@ Audio::Audio()
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
// pool must be allocated after AL context.
|
// pool must be allocated after AL context.
|
||||||
pool = new Pool();
|
try
|
||||||
|
{
|
||||||
|
pool = new Pool();
|
||||||
|
}
|
||||||
|
catch (love::Exception &)
|
||||||
|
{
|
||||||
|
alcMakeContextCurrent(nullptr);
|
||||||
|
alcDestroyContext(context);
|
||||||
|
//if (capture) alcCaptureCloseDevice(capture);
|
||||||
|
alcCloseDevice(device);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
poolThread = new PoolThread(pool);
|
poolThread = new PoolThread(pool);
|
||||||
poolThread->start();
|
poolThread->start();
|
||||||
@@ -122,7 +136,7 @@ Audio::~Audio()
|
|||||||
delete poolThread;
|
delete poolThread;
|
||||||
delete pool;
|
delete pool;
|
||||||
|
|
||||||
alcMakeContextCurrent(0);
|
alcMakeContextCurrent(nullptr);
|
||||||
alcDestroyContext(context);
|
alcDestroyContext(context);
|
||||||
//if (capture) alcCaptureCloseDevice(capture);
|
//if (capture) alcCaptureCloseDevice(capture);
|
||||||
alcCloseDevice(device);
|
alcCloseDevice(device);
|
||||||
@@ -154,9 +168,9 @@ int Audio::getMaxSources() const
|
|||||||
return pool->getMaxSources();
|
return pool->getMaxSources();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::play(love::audio::Source *source)
|
bool Audio::play(love::audio::Source *source)
|
||||||
{
|
{
|
||||||
source->play();
|
return source->play();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::stop(love::audio::Source *source)
|
void Audio::stop(love::audio::Source *source)
|
||||||
@@ -281,7 +295,7 @@ bool Audio::canRecord()
|
|||||||
|
|
||||||
Audio::DistanceModel Audio::getDistanceModel() const
|
Audio::DistanceModel Audio::getDistanceModel() const
|
||||||
{
|
{
|
||||||
return this->distanceModel;
|
return distanceModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::setDistanceModel(DistanceModel distanceModel)
|
void Audio::setDistanceModel(DistanceModel distanceModel)
|
||||||
|
|||||||
@@ -67,8 +67,7 @@ public:
|
|||||||
love::audio::Source *newSource(love::sound::SoundData *soundData);
|
love::audio::Source *newSource(love::sound::SoundData *soundData);
|
||||||
int getSourceCount() const;
|
int getSourceCount() const;
|
||||||
int getMaxSources() const;
|
int getMaxSources() const;
|
||||||
void play(love::audio::Source *source);
|
bool play(love::audio::Source *source);
|
||||||
void play();
|
|
||||||
void stop(love::audio::Source *source);
|
void stop(love::audio::Source *source);
|
||||||
void stop();
|
void stop();
|
||||||
void pause(love::audio::Source *source);
|
void pause(love::audio::Source *source);
|
||||||
|
|||||||
@@ -30,23 +30,43 @@ namespace openal
|
|||||||
{
|
{
|
||||||
|
|
||||||
Pool::Pool()
|
Pool::Pool()
|
||||||
|
: sources()
|
||||||
|
, totalSources(0)
|
||||||
|
, mutex(nullptr)
|
||||||
{
|
{
|
||||||
|
// Clear errors.
|
||||||
|
alGetError();
|
||||||
|
|
||||||
// Generate sources.
|
// Generate sources.
|
||||||
alGenSources(NUM_SOURCES, sources);
|
for (int i = 0; i < MAX_SOURCES; i++)
|
||||||
|
{
|
||||||
|
alGenSources(1, &sources[i]);
|
||||||
|
|
||||||
|
// We might hit an implementation-dependent limit on the total number
|
||||||
|
// of sources before reaching MAX_SOURCES.
|
||||||
|
if (alGetError() != AL_NO_ERROR)
|
||||||
|
break;
|
||||||
|
|
||||||
|
totalSources++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalSources < 4)
|
||||||
|
throw love::Exception("Could not generate sources.");
|
||||||
|
|
||||||
// Create the mutex.
|
// Create the mutex.
|
||||||
mutex = thread::newMutex();
|
mutex = thread::newMutex();
|
||||||
|
|
||||||
if (alGetError() != AL_NO_ERROR)
|
ALboolean hasext = alIsExtensionPresent("AL_SOFT_direct_channels");
|
||||||
throw love::Exception("Could not generate sources.");
|
|
||||||
|
|
||||||
// Make all sources available initially.
|
// Make all sources available initially.
|
||||||
for (int i = 0; i < NUM_SOURCES; i++)
|
for (int i = 0; i < totalSources; i++)
|
||||||
{
|
{
|
||||||
#ifdef AL_DIRECT_CHANNELS_SOFT
|
if (hasext)
|
||||||
// Bypassing virtualization of speakers for multi-channel sources in OpenAL Soft.
|
{
|
||||||
alSourcei(sources[i], AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
|
// Bypass virtualization of speakers for multi-channel sources in OpenAL Soft.
|
||||||
#endif
|
alSourcei(sources[i], AL_DIRECT_CHANNELS_SOFT, AL_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
available.push(sources[i]);
|
available.push(sources[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,7 +78,7 @@ Pool::~Pool()
|
|||||||
delete mutex;
|
delete mutex;
|
||||||
|
|
||||||
// Free all sources.
|
// Free all sources.
|
||||||
alDeleteSources(NUM_SOURCES, sources);
|
alDeleteSources(totalSources, sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pool::isAvailable() const
|
bool Pool::isAvailable() const
|
||||||
@@ -113,7 +133,7 @@ int Pool::getSourceCount() const
|
|||||||
|
|
||||||
int Pool::getMaxSources() const
|
int Pool::getMaxSources() const
|
||||||
{
|
{
|
||||||
return NUM_SOURCES;
|
return totalSources;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Pool::play(Source *source, ALuint &out)
|
bool Pool::play(Source *source, ALuint &out)
|
||||||
@@ -141,9 +161,7 @@ bool Pool::play(Source *source, ALuint &out)
|
|||||||
|
|
||||||
source->retain();
|
source->retain();
|
||||||
|
|
||||||
source->playAtomic();
|
ok = source->playAtomic();
|
||||||
|
|
||||||
ok = true;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -36,6 +36,7 @@
|
|||||||
#ifdef LOVE_MACOSX_USE_FRAMEWORKS
|
#ifdef LOVE_MACOSX_USE_FRAMEWORKS
|
||||||
#include <OpenAL-Soft/alc.h>
|
#include <OpenAL-Soft/alc.h>
|
||||||
#include <OpenAL-Soft/al.h>
|
#include <OpenAL-Soft/al.h>
|
||||||
|
#include <OpenAL-Soft/alext.h>
|
||||||
#else
|
#else
|
||||||
#include <AL/alc.h>
|
#include <AL/alc.h>
|
||||||
#include <AL/al.h>
|
#include <AL/al.h>
|
||||||
@@ -99,11 +100,15 @@ private:
|
|||||||
|
|
||||||
bool findSource(Source *source, ALuint &out);
|
bool findSource(Source *source, ALuint &out);
|
||||||
bool removeSource(Source *source);
|
bool removeSource(Source *source);
|
||||||
// Number of OpenAL sources.
|
|
||||||
static const int NUM_SOURCES = 64;
|
// Maximum possible number of OpenAL sources the pool attempts to generate.
|
||||||
|
static const int MAX_SOURCES = 64;
|
||||||
|
|
||||||
// OpenAL sources
|
// OpenAL sources
|
||||||
ALuint sources[NUM_SOURCES];
|
ALuint sources[MAX_SOURCES];
|
||||||
|
|
||||||
|
// Total number of created sources in the pool.
|
||||||
|
int totalSources;
|
||||||
|
|
||||||
// A queue of available sources.
|
// A queue of available sources.
|
||||||
std::queue<ALuint> available;
|
std::queue<ALuint> available;
|
||||||
|
|||||||
@@ -165,15 +165,16 @@ love::audio::Source *Source::clone()
|
|||||||
return new Source(*this);
|
return new Source(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Source::play()
|
bool Source::play()
|
||||||
{
|
{
|
||||||
if (valid && paused)
|
if (valid && paused)
|
||||||
{
|
{
|
||||||
pool->resume(this);
|
pool->resume(this);
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
valid = pool->play(this, source);
|
valid = pool->play(this, source);
|
||||||
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Source::stop()
|
void Source::stop()
|
||||||
@@ -512,7 +513,7 @@ bool Source::isLooping() const
|
|||||||
return looping;
|
return looping;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Source::playAtomic()
|
bool Source::playAtomic()
|
||||||
{
|
{
|
||||||
if (type == TYPE_STATIC)
|
if (type == TYPE_STATIC)
|
||||||
{
|
{
|
||||||
@@ -539,10 +540,19 @@ void Source::playAtomic()
|
|||||||
// of the new one.
|
// of the new one.
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
|
// Clear errors.
|
||||||
|
alGetError();
|
||||||
|
|
||||||
alSourcePlay(source);
|
alSourcePlay(source);
|
||||||
|
|
||||||
|
// alSourcePlay may fail if the system has reached its limit of simultaneous
|
||||||
|
// playing sources.
|
||||||
|
bool success = alGetError() == AL_NO_ERROR;
|
||||||
|
|
||||||
valid = true; //if it fails it will be set to false again
|
valid = true; //if it fails it will be set to false again
|
||||||
//but this prevents a horrible, horrible bug
|
//but this prevents a horrible, horrible bug
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Source::stopAtomic()
|
void Source::stopAtomic()
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public:
|
|||||||
virtual ~Source();
|
virtual ~Source();
|
||||||
|
|
||||||
virtual love::audio::Source *clone();
|
virtual love::audio::Source *clone();
|
||||||
virtual void play();
|
virtual bool play();
|
||||||
virtual void stop();
|
virtual void stop();
|
||||||
virtual void pause();
|
virtual void pause();
|
||||||
virtual void resume();
|
virtual void resume();
|
||||||
@@ -118,7 +118,7 @@ public:
|
|||||||
virtual float getMaxDistance() const;
|
virtual float getMaxDistance() const;
|
||||||
virtual int getChannels() const;
|
virtual int getChannels() const;
|
||||||
|
|
||||||
void playAtomic();
|
bool playAtomic();
|
||||||
void stopAtomic();
|
void stopAtomic();
|
||||||
void pauseAtomic();
|
void pauseAtomic();
|
||||||
void resumeAtomic();
|
void resumeAtomic();
|
||||||
|
|||||||
@@ -75,8 +75,8 @@ int w_newSource(lua_State *L)
|
|||||||
int w_play(lua_State *L)
|
int w_play(lua_State *L)
|
||||||
{
|
{
|
||||||
Source *s = luax_checksource(L, 1);
|
Source *s = luax_checksource(L, 1);
|
||||||
instance->play(s);
|
luax_pushboolean(L, instance->play(s));
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_stop(lua_State *L)
|
int w_stop(lua_State *L)
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ int w_Source_clone(lua_State *L)
|
|||||||
int w_Source_play(lua_State *L)
|
int w_Source_play(lua_State *L)
|
||||||
{
|
{
|
||||||
Source *t = luax_checksource(L, 1);
|
Source *t = luax_checksource(L, 1);
|
||||||
t->play();
|
luax_pushboolean(L, t->play());
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w_Source_stop(lua_State *L)
|
int w_Source_stop(lua_State *L)
|
||||||
|
|||||||
@@ -224,6 +224,14 @@ Message *Event::convert(const SDL_Event &e) const
|
|||||||
txt = "touchmoved";
|
txt = "touchmoved";
|
||||||
msg = new Message(txt, vargs);
|
msg = new Message(txt, vargs);
|
||||||
break;
|
break;
|
||||||
|
case SDL_MULTIGESTURE:
|
||||||
|
vargs.push_back(new Variant((double) e.mgesture.x));
|
||||||
|
vargs.push_back(new Variant((double) e.mgesture.y));
|
||||||
|
vargs.push_back(new Variant((double) e.mgesture.dTheta));
|
||||||
|
vargs.push_back(new Variant((double) e.mgesture.dDist));
|
||||||
|
vargs.push_back(new Variant((double) e.mgesture.numFingers));
|
||||||
|
msg = new Message("touchgestured", vargs);
|
||||||
|
break;
|
||||||
case SDL_JOYBUTTONDOWN:
|
case SDL_JOYBUTTONDOWN:
|
||||||
case SDL_JOYBUTTONUP:
|
case SDL_JOYBUTTONUP:
|
||||||
case SDL_JOYAXISMOTION:
|
case SDL_JOYAXISMOTION:
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public:
|
|||||||
* @param kx Shear along the x-axis.
|
* @param kx Shear along the x-axis.
|
||||||
* @param ky Shear along the y-axis.
|
* @param ky Shear along the y-axis.
|
||||||
**/
|
**/
|
||||||
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0;
|
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // graphics
|
} // graphics
|
||||||
|
|||||||
@@ -99,6 +99,16 @@ bool Graphics::getConstant(Support in, const char *&out)
|
|||||||
return support.find(in, out);
|
return support.find(in, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Graphics::getConstant(const char *in, SystemLimit &out)
|
||||||
|
{
|
||||||
|
return systemLimits.find(in, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Graphics::getConstant(SystemLimit in, const char *&out)
|
||||||
|
{
|
||||||
|
return systemLimits.find(in, out);
|
||||||
|
}
|
||||||
|
|
||||||
StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM>::Entry Graphics::drawModeEntries[] =
|
StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM>::Entry Graphics::drawModeEntries[] =
|
||||||
{
|
{
|
||||||
{ "line", Graphics::DRAW_LINE },
|
{ "line", Graphics::DRAW_LINE },
|
||||||
@@ -170,5 +180,15 @@ StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM>::Entry Graphics::suppor
|
|||||||
|
|
||||||
StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM> Graphics::support(Graphics::supportEntries, sizeof(Graphics::supportEntries));
|
StringMap<Graphics::Support, Graphics::SUPPORT_MAX_ENUM> Graphics::support(Graphics::supportEntries, sizeof(Graphics::supportEntries));
|
||||||
|
|
||||||
|
StringMap<Graphics::SystemLimit, Graphics::LIMIT_MAX_ENUM>::Entry Graphics::systemLimitEntries[] =
|
||||||
|
{
|
||||||
|
{"pointsize", Graphics::LIMIT_POINT_SIZE},
|
||||||
|
{"texturesize", Graphics::LIMIT_TEXTURE_SIZE},
|
||||||
|
{"multicanvas", Graphics::LIMIT_MULTI_CANVAS},
|
||||||
|
{"canvasfsaa", Graphics::LIMIT_CANVAS_FSAA},
|
||||||
|
};
|
||||||
|
|
||||||
|
StringMap<Graphics::SystemLimit, Graphics::LIMIT_MAX_ENUM> Graphics::systemLimits(Graphics::systemLimitEntries, sizeof(Graphics::systemLimitEntries));
|
||||||
|
|
||||||
} // graphics
|
} // graphics
|
||||||
} // love
|
} // love
|
||||||
|
|||||||
@@ -114,6 +114,15 @@ public:
|
|||||||
RENDERER_INFO_MAX_ENUM
|
RENDERER_INFO_MAX_ENUM
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SystemLimit
|
||||||
|
{
|
||||||
|
LIMIT_POINT_SIZE,
|
||||||
|
LIMIT_TEXTURE_SIZE,
|
||||||
|
LIMIT_MULTI_CANVAS,
|
||||||
|
LIMIT_CANVAS_FSAA,
|
||||||
|
LIMIT_MAX_ENUM
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~Graphics();
|
virtual ~Graphics();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,6 +164,9 @@ public:
|
|||||||
static bool getConstant(const char *in, Support &out);
|
static bool getConstant(const char *in, Support &out);
|
||||||
static bool getConstant(Support in, const char *&out);
|
static bool getConstant(Support in, const char *&out);
|
||||||
|
|
||||||
|
static bool getConstant(const char *in, SystemLimit &out);
|
||||||
|
static bool getConstant(SystemLimit in, const char *&out);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static StringMap<DrawMode, DRAW_MAX_ENUM>::Entry drawModeEntries[];
|
static StringMap<DrawMode, DRAW_MAX_ENUM>::Entry drawModeEntries[];
|
||||||
@@ -178,6 +190,9 @@ private:
|
|||||||
static StringMap<Support, SUPPORT_MAX_ENUM>::Entry supportEntries[];
|
static StringMap<Support, SUPPORT_MAX_ENUM>::Entry supportEntries[];
|
||||||
static StringMap<Support, SUPPORT_MAX_ENUM> support;
|
static StringMap<Support, SUPPORT_MAX_ENUM> support;
|
||||||
|
|
||||||
|
static StringMap<SystemLimit, LIMIT_MAX_ENUM>::Entry systemLimitEntries[];
|
||||||
|
static StringMap<SystemLimit, LIMIT_MAX_ENUM> systemLimits;
|
||||||
|
|
||||||
}; // Graphics
|
}; // Graphics
|
||||||
|
|
||||||
} // graphics
|
} // graphics
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public:
|
|||||||
* @param kx Shear along the x-axis.
|
* @param kx Shear along the x-axis.
|
||||||
* @param ky Shear along the y-axis.
|
* @param ky Shear along the y-axis.
|
||||||
**/
|
**/
|
||||||
virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const = 0;
|
virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) = 0;
|
||||||
|
|
||||||
virtual int getWidth() const;
|
virtual int getWidth() const;
|
||||||
virtual int getHeight() const;
|
virtual int getHeight() const;
|
||||||
|
|||||||
@@ -63,12 +63,26 @@ struct FramebufferStrategy
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Create a MSAA renderbuffer and attach it to the active FBO.
|
||||||
|
/**
|
||||||
|
* @param[in] width Width of the MSAA buffer
|
||||||
|
* @param[in] height Height of the MSAA buffer
|
||||||
|
* @param[inout] samples Number of samples to use
|
||||||
|
* @param[in] internalformat The internal format to use for the buffer
|
||||||
|
* @param[out] buffer Name for the MSAA buffer
|
||||||
|
* @return Whether the MSAA buffer was successfully created and attached
|
||||||
|
**/
|
||||||
|
virtual bool createMSAABuffer(int, int, int &, GLenum, GLuint &)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// remove objects
|
/// remove objects
|
||||||
/**
|
/**
|
||||||
* @param[in] framebuffer Framebuffer name
|
* @param[in] framebuffer Framebuffer name
|
||||||
* @param[in] depth_stencil Name for packed depth and stencil buffer
|
* @param[in] depth_stencil Name for packed depth and stencil buffer
|
||||||
*/
|
*/
|
||||||
virtual void deleteFBO(GLuint, GLuint) {}
|
virtual void deleteFBO(GLuint, GLuint, GLuint) {}
|
||||||
virtual void bindFBO(GLuint) {}
|
virtual void bindFBO(GLuint) {}
|
||||||
|
|
||||||
/// attach additional canvases to the active framebuffer for rendering
|
/// attach additional canvases to the active framebuffer for rendering
|
||||||
@@ -93,8 +107,11 @@ struct FramebufferStrategyCore : public FramebufferStrategy
|
|||||||
glGenFramebuffers(1, &framebuffer);
|
glGenFramebuffers(1, &framebuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
|
||||||
|
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
if (texture != 0)
|
||||||
GL_TEXTURE_2D, texture, 0);
|
{
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
|
GL_TEXTURE_2D, texture, 0);
|
||||||
|
}
|
||||||
|
|
||||||
// check status
|
// check status
|
||||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||||
@@ -118,13 +135,44 @@ struct FramebufferStrategyCore : public FramebufferStrategy
|
|||||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
// check status
|
// check status
|
||||||
return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
glDeleteRenderbuffers(1, &stencil);
|
||||||
|
stencil = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil)
|
virtual bool createMSAABuffer(int width, int height, int &samples, GLenum internalformat, GLuint &buffer)
|
||||||
|
{
|
||||||
|
glGenRenderbuffers(1, &buffer);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, buffer);
|
||||||
|
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, internalformat,
|
||||||
|
width, height);
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
|
GL_RENDERBUFFER, buffer);
|
||||||
|
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
|
||||||
|
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
glDeleteRenderbuffers(1, &buffer);
|
||||||
|
buffer = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil, GLuint msaa_buffer)
|
||||||
{
|
{
|
||||||
if (depth_stencil != 0)
|
if (depth_stencil != 0)
|
||||||
glDeleteRenderbuffers(1, &depth_stencil);
|
glDeleteRenderbuffers(1, &depth_stencil);
|
||||||
|
if (msaa_buffer != 0)
|
||||||
|
glDeleteRenderbuffers(1, &msaa_buffer);
|
||||||
if (framebuffer != 0)
|
if (framebuffer != 0)
|
||||||
glDeleteFramebuffers(1, &framebuffer);
|
glDeleteFramebuffers(1, &framebuffer);
|
||||||
}
|
}
|
||||||
@@ -212,7 +260,7 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
|
|||||||
virtual bool createStencil(int width, int height, GLuint &stencil)
|
virtual bool createStencil(int width, int height, GLuint &stencil)
|
||||||
{
|
{
|
||||||
// create combined depth/stencil buffer
|
// create combined depth/stencil buffer
|
||||||
glDeleteRenderbuffers(1, &stencil);
|
glDeleteRenderbuffersEXT(1, &stencil);
|
||||||
glGenRenderbuffersEXT(1, &stencil);
|
glGenRenderbuffersEXT(1, &stencil);
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil);
|
||||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT,
|
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT,
|
||||||
@@ -223,13 +271,47 @@ struct FramebufferStrategyPackedEXT : public FramebufferStrategy
|
|||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||||
|
|
||||||
// check status
|
// check status
|
||||||
return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT;
|
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
glDeleteRenderbuffersEXT(1, &stencil);
|
||||||
|
stencil = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil)
|
virtual bool createMSAABuffer(int width, int height, int &samples, GLenum internalformat, GLuint &buffer)
|
||||||
|
{
|
||||||
|
if (!GLAD_EXT_framebuffer_multisample)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
glGenRenderbuffersEXT(1, &buffer);
|
||||||
|
glBindRenderbufferEXT(GL_RENDERBUFFER, buffer);
|
||||||
|
glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, samples,
|
||||||
|
internalformat, width, height);
|
||||||
|
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
|
||||||
|
GL_RENDERBUFFER, buffer);
|
||||||
|
glGetRenderbufferParameterivEXT(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
|
||||||
|
|
||||||
|
glBindRenderbufferEXT(GL_RENDERBUFFER, 0);
|
||||||
|
|
||||||
|
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
glDeleteRenderbuffersEXT(1, &buffer);
|
||||||
|
buffer = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void deleteFBO(GLuint framebuffer, GLuint depth_stencil, GLuint msaa_buffer)
|
||||||
{
|
{
|
||||||
if (depth_stencil != 0)
|
if (depth_stencil != 0)
|
||||||
glDeleteRenderbuffersEXT(1, &depth_stencil);
|
glDeleteRenderbuffersEXT(1, &depth_stencil);
|
||||||
|
if (msaa_buffer != 0)
|
||||||
|
glDeleteRenderbuffersEXT(1, &msaa_buffer);
|
||||||
if (framebuffer != 0)
|
if (framebuffer != 0)
|
||||||
glDeleteFramebuffersEXT(1, &framebuffer);
|
glDeleteFramebuffersEXT(1, &framebuffer);
|
||||||
}
|
}
|
||||||
@@ -277,7 +359,7 @@ struct FramebufferStrategyEXT : public FramebufferStrategyPackedEXT
|
|||||||
virtual bool createStencil(int width, int height, GLuint &stencil)
|
virtual bool createStencil(int width, int height, GLuint &stencil)
|
||||||
{
|
{
|
||||||
// create stencil buffer
|
// create stencil buffer
|
||||||
glDeleteRenderbuffers(1, &stencil);
|
glDeleteRenderbuffersEXT(1, &stencil);
|
||||||
glGenRenderbuffersEXT(1, &stencil);
|
glGenRenderbuffersEXT(1, &stencil);
|
||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, stencil);
|
||||||
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,
|
glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX,
|
||||||
@@ -288,14 +370,21 @@ struct FramebufferStrategyEXT : public FramebufferStrategyPackedEXT
|
|||||||
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
|
||||||
|
|
||||||
// check status
|
// check status
|
||||||
return glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT;
|
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
glDeleteRenderbuffersEXT(1, &stencil);
|
||||||
|
stencil = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isSupported()
|
bool isSupported()
|
||||||
{
|
{
|
||||||
GLuint fb = 0, stencil = 0;
|
GLuint fb = 0, stencil = 0;
|
||||||
GLenum status = createFBO(fb, 0);
|
GLenum status = createFBO(fb, 0);
|
||||||
deleteFBO(fb, stencil);
|
deleteFBO(fb, stencil, 0);
|
||||||
return status == GL_FRAMEBUFFER_COMPLETE;
|
return status == GL_FRAMEBUFFER_COMPLETE;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -335,11 +424,15 @@ static void getStrategy()
|
|||||||
static int maxFBOColorAttachments = 0;
|
static int maxFBOColorAttachments = 0;
|
||||||
static int maxDrawBuffers = 0;
|
static int maxDrawBuffers = 0;
|
||||||
|
|
||||||
Canvas::Canvas(int width, int height, TextureType texture_type)
|
Canvas::Canvas(int width, int height, TextureType texture_type, int fsaa)
|
||||||
: fbo(0)
|
: fbo(0)
|
||||||
|
, resolve_fbo(0)
|
||||||
, texture(0)
|
, texture(0)
|
||||||
|
, fsaa_buffer(0)
|
||||||
, depth_stencil(0)
|
, depth_stencil(0)
|
||||||
, texture_type(texture_type)
|
, texture_type(texture_type)
|
||||||
|
, fsaa_samples(fsaa)
|
||||||
|
, fsaa_dirty(false)
|
||||||
{
|
{
|
||||||
this->width = width;
|
this->width = width;
|
||||||
this->height = height;
|
this->height = height;
|
||||||
@@ -381,9 +474,50 @@ Canvas::~Canvas()
|
|||||||
unloadVolatile();
|
unloadVolatile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Canvas::createFSAAFBO(GLenum internalformat)
|
||||||
|
{
|
||||||
|
// Create our FBO without a texture.
|
||||||
|
status = strategy->createFBO(fbo, 0);
|
||||||
|
|
||||||
|
GLuint previous = 0;
|
||||||
|
if (current != this)
|
||||||
|
{
|
||||||
|
if (current != nullptr)
|
||||||
|
previous = current->fbo;
|
||||||
|
|
||||||
|
strategy->bindFBO(fbo);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create and attach the MSAA buffer for our FBO.
|
||||||
|
if (strategy->createMSAABuffer(width, height, fsaa_samples, internalformat, fsaa_buffer))
|
||||||
|
status = GL_FRAMEBUFFER_COMPLETE;
|
||||||
|
else
|
||||||
|
status = GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
|
||||||
|
|
||||||
|
// Create the FBO used for the MSAA resolve, and attach the texture.
|
||||||
|
if (status == GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
status = strategy->createFBO(resolve_fbo, texture);
|
||||||
|
|
||||||
|
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||||
|
{
|
||||||
|
// Clean up.
|
||||||
|
strategy->deleteFBO(fbo, 0, fsaa_buffer);
|
||||||
|
strategy->deleteFBO(resolve_fbo, 0, 0);
|
||||||
|
fbo = fsaa_buffer = resolve_fbo = 0;
|
||||||
|
fsaa_samples = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current != this)
|
||||||
|
strategy->bindFBO(previous);
|
||||||
|
|
||||||
|
return status == GL_FRAMEBUFFER_COMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
bool Canvas::loadVolatile()
|
bool Canvas::loadVolatile()
|
||||||
{
|
{
|
||||||
fbo = depth_stencil = texture = 0;
|
fbo = depth_stencil = texture = 0;
|
||||||
|
resolve_fbo = fsaa_buffer = 0;
|
||||||
|
status = GL_FRAMEBUFFER_COMPLETE;
|
||||||
|
|
||||||
// glTexImage2D is guaranteed to error in this case.
|
// glTexImage2D is guaranteed to error in this case.
|
||||||
if (width > gl.getMaxTextureSize() || height > gl.getMaxTextureSize())
|
if (width > gl.getMaxTextureSize() || height > gl.getMaxTextureSize())
|
||||||
@@ -430,7 +564,25 @@ bool Canvas::loadVolatile()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = strategy->createFBO(fbo, texture);
|
int max_samples = 0;
|
||||||
|
if (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object
|
||||||
|
|| GLAD_EXT_framebuffer_multisample)
|
||||||
|
{
|
||||||
|
glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fsaa_samples > max_samples)
|
||||||
|
fsaa_samples = max_samples;
|
||||||
|
|
||||||
|
// Try to create a FSAA FBO if requested.
|
||||||
|
bool fsaasuccess = false;
|
||||||
|
if (fsaa_samples > 1)
|
||||||
|
fsaasuccess = createFSAAFBO(internalformat);
|
||||||
|
|
||||||
|
// On failure (or no requested FSAA), fall back to a regular FBO.
|
||||||
|
if (!fsaasuccess)
|
||||||
|
status = strategy->createFBO(fbo, texture);
|
||||||
|
|
||||||
if (status != GL_FRAMEBUFFER_COMPLETE)
|
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -440,11 +592,13 @@ bool Canvas::loadVolatile()
|
|||||||
|
|
||||||
void Canvas::unloadVolatile()
|
void Canvas::unloadVolatile()
|
||||||
{
|
{
|
||||||
strategy->deleteFBO(fbo, depth_stencil);
|
strategy->deleteFBO(fbo, depth_stencil, fsaa_buffer);
|
||||||
|
strategy->deleteFBO(resolve_fbo, 0, 0);
|
||||||
|
|
||||||
gl.deleteTexture(texture);
|
gl.deleteTexture(texture);
|
||||||
|
|
||||||
fbo = depth_stencil = texture = 0;
|
fbo = depth_stencil = texture = 0;
|
||||||
|
resolve_fbo = fsaa_buffer = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < attachedCanvases.size(); i++)
|
for (size_t i = 0; i < attachedCanvases.size(); i++)
|
||||||
attachedCanvases[i]->release();
|
attachedCanvases[i]->release();
|
||||||
@@ -452,7 +606,7 @@ void Canvas::unloadVolatile()
|
|||||||
attachedCanvases.clear();
|
attachedCanvases.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::drawv(const Matrix &t, const Vertex *v) const
|
void Canvas::drawv(const Matrix &t, const Vertex *v)
|
||||||
{
|
{
|
||||||
gl.matrices.transform.push(gl.matrices.transform.top());
|
gl.matrices.transform.push(gl.matrices.transform.top());
|
||||||
gl.matrices.transform.top() *= t;
|
gl.matrices.transform.top() *= t;
|
||||||
@@ -475,10 +629,9 @@ void Canvas::drawv(const Matrix &t, const Vertex *v) const
|
|||||||
postdraw();
|
postdraw();
|
||||||
|
|
||||||
gl.matrices.transform.pop();
|
gl.matrices.transform.pop();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
|
void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||||
{
|
{
|
||||||
static Matrix t;
|
static Matrix t;
|
||||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||||
@@ -486,7 +639,7 @@ void Canvas::draw(float x, float y, float angle, float sx, float sy, float ox, f
|
|||||||
drawv(t, vertices);
|
drawv(t, vertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
|
void Canvas::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||||
{
|
{
|
||||||
static Matrix t;
|
static Matrix t;
|
||||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||||
@@ -514,8 +667,12 @@ GLuint Canvas::getGLTexture() const
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::predraw() const
|
void Canvas::predraw()
|
||||||
{
|
{
|
||||||
|
// We need to make sure the texture is up-to-date by resolving the MSAA
|
||||||
|
// buffer (which we render to when the canvas is active) to it.
|
||||||
|
resolveMSAA();
|
||||||
|
|
||||||
gl.bindTexture(texture);
|
gl.bindTexture(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -539,6 +696,9 @@ void Canvas::setupGrab()
|
|||||||
|
|
||||||
// indicate we are using this fbo
|
// indicate we are using this fbo
|
||||||
current = this;
|
current = this;
|
||||||
|
|
||||||
|
if (fsaa_buffer != 0)
|
||||||
|
fsaa_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::startGrab(const std::vector<Canvas *> &canvases)
|
void Canvas::startGrab(const std::vector<Canvas *> &canvases)
|
||||||
@@ -554,6 +714,9 @@ void Canvas::startGrab(const std::vector<Canvas *> &canvases)
|
|||||||
|
|
||||||
if (canvases.size()+1 > size_t(maxDrawBuffers) || canvases.size()+1 > size_t(maxFBOColorAttachments))
|
if (canvases.size()+1 > size_t(maxDrawBuffers) || canvases.size()+1 > size_t(maxFBOColorAttachments))
|
||||||
throw love::Exception("This system can't simultaniously render to %d canvases.", canvases.size()+1);
|
throw love::Exception("This system can't simultaniously render to %d canvases.", canvases.size()+1);
|
||||||
|
|
||||||
|
if (fsaa_samples != 0)
|
||||||
|
throw love::Exception("Multi-canvas rendering is not supported with FSAA.");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < canvases.size(); i++)
|
for (size_t i = 0; i < canvases.size(); i++)
|
||||||
@@ -564,6 +727,9 @@ void Canvas::startGrab(const std::vector<Canvas *> &canvases)
|
|||||||
if (canvases[i]->getTextureType() != texture_type)
|
if (canvases[i]->getTextureType() != texture_type)
|
||||||
throw love::Exception("All canvas arguments must have the same texture type.");
|
throw love::Exception("All canvas arguments must have the same texture type.");
|
||||||
|
|
||||||
|
if (canvases[i]->getFSAA() != 0)
|
||||||
|
throw love::Exception("Multi-canvas rendering is not supported with FSAA.");
|
||||||
|
|
||||||
if (!canvaseschanged && canvases[i] != attachedCanvases[i])
|
if (!canvaseschanged && canvases[i] != attachedCanvases[i])
|
||||||
canvaseschanged = true;
|
canvaseschanged = true;
|
||||||
}
|
}
|
||||||
@@ -698,12 +864,22 @@ bool Canvas::checkCreateStencil()
|
|||||||
|
|
||||||
love::image::ImageData *Canvas::getImageData(love::image::Image *image)
|
love::image::ImageData *Canvas::getImageData(love::image::Image *image)
|
||||||
{
|
{
|
||||||
|
resolveMSAA();
|
||||||
|
|
||||||
int row = 4 * width;
|
int row = 4 * width;
|
||||||
int size = row * height;
|
int size = row * height;
|
||||||
GLubyte *pixels = new GLubyte[size];
|
GLubyte *pixels = new GLubyte[size];
|
||||||
|
|
||||||
strategy->bindFBO(fbo);
|
// Our texture is attached to 'resolve_fbo' when we use MSAA.
|
||||||
|
if (fsaa_samples > 1 && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object))
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo);
|
||||||
|
else if (fsaa_samples > 1 && GLAD_EXT_framebuffer_multisample)
|
||||||
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER, resolve_fbo);
|
||||||
|
else
|
||||||
|
strategy->bindFBO(fbo);
|
||||||
|
|
||||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
if (current)
|
if (current)
|
||||||
strategy->bindFBO(current->fbo);
|
strategy->bindFBO(current->fbo);
|
||||||
else
|
else
|
||||||
@@ -716,10 +892,17 @@ love::image::ImageData *Canvas::getImageData(love::image::Image *image)
|
|||||||
|
|
||||||
void Canvas::getPixel(unsigned char* pixel_rgba, int x, int y)
|
void Canvas::getPixel(unsigned char* pixel_rgba, int x, int y)
|
||||||
{
|
{
|
||||||
if (current != this)
|
resolveMSAA();
|
||||||
|
|
||||||
|
// Our texture is attached to 'resolve_fbo' when we use MSAA.
|
||||||
|
if (fsaa_samples > 1 && (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object))
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, resolve_fbo);
|
||||||
|
else if (fsaa_samples > 1 && GLAD_EXT_framebuffer_multisample)
|
||||||
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER, resolve_fbo);
|
||||||
|
else if (current != this)
|
||||||
strategy->bindFBO(fbo);
|
strategy->bindFBO(fbo);
|
||||||
|
|
||||||
glReadPixels(x, height - y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_rgba);
|
glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_rgba);
|
||||||
|
|
||||||
if (current && current != this)
|
if (current && current != this)
|
||||||
strategy->bindFBO(current->fbo);
|
strategy->bindFBO(current->fbo);
|
||||||
@@ -727,6 +910,44 @@ void Canvas::getPixel(unsigned char* pixel_rgba, int x, int y)
|
|||||||
strategy->bindFBO(gl.getDefaultFBO());
|
strategy->bindFBO(gl.getDefaultFBO());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Canvas::resolveMSAA()
|
||||||
|
{
|
||||||
|
if (resolve_fbo == 0 || fsaa_buffer == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!fsaa_dirty)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
GLuint previous = 0;
|
||||||
|
if (current != nullptr)
|
||||||
|
previous = current->fbo;
|
||||||
|
|
||||||
|
// Do the MSAA resolve by blitting the MSAA renderbuffer to the texture.
|
||||||
|
if (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object)
|
||||||
|
{
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, resolve_fbo);
|
||||||
|
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
}
|
||||||
|
else if (GLAD_EXT_framebuffer_multisample && GLAD_EXT_framebuffer_blit)
|
||||||
|
{
|
||||||
|
glBindFramebufferEXT(GL_READ_FRAMEBUFFER, fbo);
|
||||||
|
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER, resolve_fbo);
|
||||||
|
glBlitFramebufferEXT(0, 0, width, height, 0, 0, width, height,
|
||||||
|
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
|
strategy->bindFBO(previous);
|
||||||
|
|
||||||
|
if (current != this)
|
||||||
|
fsaa_dirty = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool Canvas::isSupported()
|
bool Canvas::isSupported()
|
||||||
{
|
{
|
||||||
getStrategy();
|
getStrategy();
|
||||||
@@ -740,17 +961,8 @@ bool Canvas::isHDRSupported()
|
|||||||
|
|
||||||
bool Canvas::isMultiCanvasSupported()
|
bool Canvas::isMultiCanvasSupported()
|
||||||
{
|
{
|
||||||
if (!(isSupported() && (GLAD_VERSION_2_0 || GLAD_ARB_draw_buffers)))
|
// system must support at least 4 simultanious active canvases.
|
||||||
return false;
|
return gl.getMaxRenderTargets() >= 4;
|
||||||
|
|
||||||
if (maxFBOColorAttachments == 0 || maxDrawBuffers == 0)
|
|
||||||
{
|
|
||||||
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxFBOColorAttachments);
|
|
||||||
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
|
|
||||||
}
|
|
||||||
|
|
||||||
// system must support at least 4 simultanious active canvases
|
|
||||||
return maxFBOColorAttachments >= 4 && maxDrawBuffers >= 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::bindDefaultCanvas()
|
void Canvas::bindDefaultCanvas()
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public:
|
|||||||
TYPE_MAX_ENUM
|
TYPE_MAX_ENUM
|
||||||
};
|
};
|
||||||
|
|
||||||
Canvas(int width, int height, TextureType texture_type = TYPE_NORMAL);
|
Canvas(int width, int height, TextureType texture_type = TYPE_NORMAL, int fsaa = 0);
|
||||||
virtual ~Canvas();
|
virtual ~Canvas();
|
||||||
|
|
||||||
// Implements Volatile.
|
// Implements Volatile.
|
||||||
@@ -54,14 +54,14 @@ public:
|
|||||||
virtual void unloadVolatile();
|
virtual void unloadVolatile();
|
||||||
|
|
||||||
// Implements Drawable.
|
// Implements Drawable.
|
||||||
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
|
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
||||||
|
|
||||||
// Implements Texture.
|
// Implements Texture.
|
||||||
virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
|
virtual void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
||||||
virtual void setFilter(const Texture::Filter &f);
|
virtual void setFilter(const Texture::Filter &f);
|
||||||
virtual void setWrap(const Texture::Wrap &w);
|
virtual void setWrap(const Texture::Wrap &w);
|
||||||
virtual GLuint getGLTexture() const;
|
virtual GLuint getGLTexture() const;
|
||||||
virtual void predraw() const;
|
virtual void predraw();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param canvases A list of other canvases to temporarily attach to this one,
|
* @param canvases A list of other canvases to temporarily attach to this one,
|
||||||
@@ -97,6 +97,13 @@ public:
|
|||||||
return texture_type;
|
return texture_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline int getFSAA() const
|
||||||
|
{
|
||||||
|
return fsaa_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resolveMSAA();
|
||||||
|
|
||||||
static bool isSupported();
|
static bool isSupported();
|
||||||
static bool isHDRSupported();
|
static bool isHDRSupported();
|
||||||
static bool isMultiCanvasSupported();
|
static bool isMultiCanvasSupported();
|
||||||
@@ -112,8 +119,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
bool createFSAAFBO(GLenum internalformat);
|
||||||
|
|
||||||
GLuint fbo;
|
GLuint fbo;
|
||||||
|
GLuint resolve_fbo;
|
||||||
|
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
|
GLuint fsaa_buffer;
|
||||||
GLuint depth_stencil;
|
GLuint depth_stencil;
|
||||||
|
|
||||||
TextureType texture_type;
|
TextureType texture_type;
|
||||||
@@ -122,8 +134,11 @@ private:
|
|||||||
|
|
||||||
std::vector<Canvas *> attachedCanvases;
|
std::vector<Canvas *> attachedCanvases;
|
||||||
|
|
||||||
|
int fsaa_samples;
|
||||||
|
bool fsaa_dirty;
|
||||||
|
|
||||||
void setupGrab();
|
void setupGrab();
|
||||||
void drawv(const Matrix &t, const Vertex *v) const;
|
void drawv(const Matrix &t, const Vertex *v);
|
||||||
|
|
||||||
static StringMap<TextureType, TYPE_MAX_ENUM>::Entry textureTypeEntries[];
|
static StringMap<TextureType, TYPE_MAX_ENUM>::Entry textureTypeEntries[];
|
||||||
static StringMap<TextureType, TYPE_MAX_ENUM> textureTypes;
|
static StringMap<TextureType, TYPE_MAX_ENUM> textureTypes;
|
||||||
|
|||||||
@@ -228,6 +228,18 @@ bool Graphics::setMode(int width, int height)
|
|||||||
Shader::defaultShader->attach();
|
Shader::defaultShader->attach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool enabledebug = false;
|
||||||
|
|
||||||
|
if (GLAD_VERSION_3_0)
|
||||||
|
{
|
||||||
|
// Enable OpenGL's debug output if a debug context has been created.
|
||||||
|
GLint flags = 0;
|
||||||
|
glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
|
||||||
|
enabledebug = (flags & GL_CONTEXT_FLAG_DEBUG_BIT) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
setDebug(enabledebug);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,6 +258,63 @@ void Graphics::unSetMode()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void APIENTRY debugCB(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei /*len*/, const GLchar *msg, const GLvoid* /*usr*/)
|
||||||
|
{
|
||||||
|
// Human-readable strings for the debug info.
|
||||||
|
const char *sourceStr = OpenGL::debugSourceString(source);
|
||||||
|
const char *typeStr = OpenGL::debugTypeString(type);
|
||||||
|
const char *severityStr = OpenGL::debugSeverityString(severity);
|
||||||
|
|
||||||
|
const char *fmt = "OpenGL: %s [source=%s, type=%s, severity=%s, id=%d]\n";
|
||||||
|
printf(fmt, msg, sourceStr, typeStr, severityStr, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Graphics::setDebug(bool enable)
|
||||||
|
{
|
||||||
|
// Make sure debug output is supported. The AMD ext. is a bit different
|
||||||
|
// so we don't make use of it, since AMD drivers now support KHR_debug.
|
||||||
|
if (!(GLAD_VERSION_4_3 || GLAD_KHR_debug || GLAD_ARB_debug_output))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ugly hack to reduce code duplication.
|
||||||
|
if (GLAD_ARB_debug_output && !(GLAD_VERSION_4_3 || GLAD_KHR_debug))
|
||||||
|
{
|
||||||
|
fp_glDebugMessageCallback = (pfn_glDebugMessageCallback) fp_glDebugMessageCallbackARB;
|
||||||
|
fp_glDebugMessageControl = (pfn_glDebugMessageControl) fp_glDebugMessageControlARB;
|
||||||
|
}
|
||||||
|
else if (GLAD_ES_VERSION_2_0 && GLAD_KHR_debug)
|
||||||
|
{
|
||||||
|
fp_glDebugMessageCallback = (pfn_glDebugMessageCallback) fp_glDebugMessageCallbackKHR;
|
||||||
|
fp_glDebugMessageControl = (pfn_glDebugMessageControl) fp_glDebugMessageControlKHR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!enable)
|
||||||
|
{
|
||||||
|
// Disable the debug callback function.
|
||||||
|
glDebugMessageCallback(nullptr, nullptr);
|
||||||
|
|
||||||
|
// We can disable debug output entirely with KHR_debug.
|
||||||
|
if (GLAD_VERSION_4_3 || GLAD_KHR_debug)
|
||||||
|
glDisable(GL_DEBUG_OUTPUT);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We don't want asynchronous debug output.
|
||||||
|
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||||
|
|
||||||
|
glDebugMessageCallback(debugCB, nullptr);
|
||||||
|
|
||||||
|
// Initially, enable everything.
|
||||||
|
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, 0, GL_TRUE);
|
||||||
|
|
||||||
|
// Disable messages about deprecated OpenGL functionality.
|
||||||
|
glDebugMessageControl(GL_DEBUG_SOURCE_API, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, GL_DONT_CARE, 0, 0, GL_FALSE);
|
||||||
|
glDebugMessageControl(GL_DEBUG_SOURCE_SHADER_COMPILER, GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR, GL_DONT_CARE, 0, 0, GL_FALSE);
|
||||||
|
|
||||||
|
::printf("OpenGL debug output enabled (LOVE_GRAPHICS_DEBUG=1)\n");
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::reset()
|
void Graphics::reset()
|
||||||
{
|
{
|
||||||
DisplayState s;
|
DisplayState s;
|
||||||
@@ -361,11 +430,6 @@ void Graphics::discardStencil()
|
|||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Graphics::getMaxTextureSize() const
|
|
||||||
{
|
|
||||||
return gl.getMaxTextureSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
Image *Graphics::newImage(love::image::ImageData *data)
|
Image *Graphics::newImage(love::image::ImageData *data)
|
||||||
{
|
{
|
||||||
// Create the image.
|
// Create the image.
|
||||||
@@ -440,7 +504,7 @@ ParticleSystem *Graphics::newParticleSystem(Texture *texture, int size)
|
|||||||
return new ParticleSystem(texture, size);
|
return new ParticleSystem(texture, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Canvas *Graphics::newCanvas(int width, int height, Canvas::TextureType texture_type)
|
Canvas *Graphics::newCanvas(int width, int height, Canvas::TextureType texture_type, int fsaa)
|
||||||
{
|
{
|
||||||
if (texture_type == Canvas::TYPE_HDR && !Canvas::isHDRSupported())
|
if (texture_type == Canvas::TYPE_HDR && !Canvas::isHDRSupported())
|
||||||
throw Exception("HDR Canvases are not supported by your OpenGL implementation");
|
throw Exception("HDR Canvases are not supported by your OpenGL implementation");
|
||||||
@@ -453,7 +517,7 @@ Canvas *Graphics::newCanvas(int width, int height, Canvas::TextureType texture_t
|
|||||||
while (GL_NO_ERROR != glGetError())
|
while (GL_NO_ERROR != glGetError())
|
||||||
/* clear opengl error flag */;
|
/* clear opengl error flag */;
|
||||||
|
|
||||||
Canvas *canvas = new Canvas(width, height, texture_type);
|
Canvas *canvas = new Canvas(width, height, texture_type, fsaa);
|
||||||
GLenum err = canvas->getStatus();
|
GLenum err = canvas->getStatus();
|
||||||
|
|
||||||
// everything ok, return canvas (early out)
|
// everything ok, return canvas (early out)
|
||||||
@@ -771,13 +835,6 @@ Graphics::PointStyle Graphics::getPointStyle() const
|
|||||||
return POINT_ROUGH;
|
return POINT_ROUGH;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Graphics::getMaxPointSize() const
|
|
||||||
{
|
|
||||||
GLint max;
|
|
||||||
glGetIntegerv(GL_POINT_SIZE_MAX, &max);
|
|
||||||
return (int)max;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Graphics::print(const std::string &str, float x, float y , float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
void Graphics::print(const std::string &str, float x, float y , float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||||
{
|
{
|
||||||
if (currentFont != nullptr)
|
if (currentFont != nullptr)
|
||||||
@@ -1103,6 +1160,41 @@ std::string Graphics::getRendererInfo(Graphics::RendererInfo infotype) const
|
|||||||
return std::string(infostr);
|
return std::string(infostr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double Graphics::getSystemLimit(SystemLimit limittype) const
|
||||||
|
{
|
||||||
|
double limit = 0.0;
|
||||||
|
|
||||||
|
switch (limittype)
|
||||||
|
{
|
||||||
|
case Graphics::LIMIT_POINT_SIZE:
|
||||||
|
{
|
||||||
|
GLfloat limits[2];
|
||||||
|
glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, limits);
|
||||||
|
limit = limits[1];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Graphics::LIMIT_TEXTURE_SIZE:
|
||||||
|
limit = (double) gl.getMaxTextureSize();
|
||||||
|
break;
|
||||||
|
case Graphics::LIMIT_MULTI_CANVAS:
|
||||||
|
limit = (double) gl.getMaxRenderTargets();
|
||||||
|
break;
|
||||||
|
case Graphics::LIMIT_CANVAS_FSAA:
|
||||||
|
if (GLAD_VERSION_3_0 || GLAD_ARB_framebuffer_object
|
||||||
|
|| GLAD_EXT_framebuffer_multisample)
|
||||||
|
{
|
||||||
|
GLint intlimit = 0;
|
||||||
|
glGetIntegerv(GL_MAX_SAMPLES, &intlimit);
|
||||||
|
limit = (double) intlimit;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
void Graphics::push()
|
void Graphics::push()
|
||||||
{
|
{
|
||||||
if (gl.matrices.transform.size() == matrixLimit)
|
if (gl.matrices.transform.size() == matrixLimit)
|
||||||
|
|||||||
@@ -115,6 +115,8 @@ public:
|
|||||||
virtual bool setMode(int width, int height);
|
virtual bool setMode(int width, int height);
|
||||||
virtual void unSetMode();
|
virtual void unSetMode();
|
||||||
|
|
||||||
|
void setDebug(bool enable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the current color, background color,
|
* Resets the current color, background color,
|
||||||
* line style, and so forth. (This will be called
|
* line style, and so forth. (This will be called
|
||||||
@@ -186,11 +188,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void discardStencil();
|
void discardStencil();
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the maximum supported width or height of Textures on this system.
|
|
||||||
**/
|
|
||||||
int getMaxTextureSize() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an Image object with padding and/or optimization.
|
* Creates an Image object with padding and/or optimization.
|
||||||
**/
|
**/
|
||||||
@@ -208,7 +205,7 @@ public:
|
|||||||
|
|
||||||
ParticleSystem *newParticleSystem(Texture *texture, int size);
|
ParticleSystem *newParticleSystem(Texture *texture, int size);
|
||||||
|
|
||||||
Canvas *newCanvas(int width, int height, Canvas::TextureType texture_type = Canvas::TYPE_NORMAL);
|
Canvas *newCanvas(int width, int height, Canvas::TextureType texture_type = Canvas::TYPE_NORMAL, int fsaa = 0);
|
||||||
|
|
||||||
Shader *newShader(const Shader::ShaderSources &sources);
|
Shader *newShader(const Shader::ShaderSources &sources);
|
||||||
|
|
||||||
@@ -337,12 +334,6 @@ public:
|
|||||||
**/
|
**/
|
||||||
PointStyle getPointStyle() const;
|
PointStyle getPointStyle() const;
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the maximum point size supported.
|
|
||||||
* This may vary from computer to computer.
|
|
||||||
**/
|
|
||||||
int getMaxPointSize() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws text at the specified coordinates, with rotation and
|
* Draws text at the specified coordinates, with rotation and
|
||||||
* scaling along both axes.
|
* scaling along both axes.
|
||||||
@@ -444,6 +435,11 @@ public:
|
|||||||
**/
|
**/
|
||||||
std::string getRendererInfo(Graphics::RendererInfo infotype) const;
|
std::string getRendererInfo(Graphics::RendererInfo infotype) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the system-dependent numeric limit for the specified parameter.
|
||||||
|
**/
|
||||||
|
double getSystemLimit(SystemLimit limittype) const;
|
||||||
|
|
||||||
void push();
|
void push();
|
||||||
void pop();
|
void pop();
|
||||||
void rotate(float r);
|
void rotate(float r);
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ love::image::CompressedData *Image::getCompressedData() const
|
|||||||
return cdata;
|
return cdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
|
void Image::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||||
{
|
{
|
||||||
Matrix t;
|
Matrix t;
|
||||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||||
@@ -99,7 +99,7 @@ void Image::draw(float x, float y, float angle, float sx, float sy, float ox, fl
|
|||||||
drawv(t, vertices);
|
drawv(t, vertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
|
void Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||||
{
|
{
|
||||||
Matrix t;
|
Matrix t;
|
||||||
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
t.setTransformation(x, y, angle, sx, sy, ox, oy, kx, ky);
|
||||||
@@ -107,7 +107,7 @@ void Image::drawq(Quad *quad, float x, float y, float angle, float sx, float sy,
|
|||||||
drawv(t, quad->getVertices());
|
drawv(t, quad->getVertices());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::predraw() const
|
void Image::predraw()
|
||||||
{
|
{
|
||||||
bind();
|
bind();
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ void Image::predraw() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::postdraw() const
|
void Image::postdraw()
|
||||||
{
|
{
|
||||||
if (width != paddedWidth || height != paddedHeight)
|
if (width != paddedWidth || height != paddedHeight)
|
||||||
{
|
{
|
||||||
@@ -511,7 +511,7 @@ void Image::uploadDefaultTexture()
|
|||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, px);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, px);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Image::drawv(const Matrix &t, const Vertex *v) const
|
void Image::drawv(const Matrix &t, const Vertex *v)
|
||||||
{
|
{
|
||||||
predraw();
|
predraw();
|
||||||
|
|
||||||
|
|||||||
@@ -76,20 +76,20 @@ public:
|
|||||||
/**
|
/**
|
||||||
* @copydoc Drawable::draw()
|
* @copydoc Drawable::draw()
|
||||||
**/
|
**/
|
||||||
void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
|
void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @copydoc Texture::drawq()
|
* @copydoc Texture::drawq()
|
||||||
**/
|
**/
|
||||||
void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
|
void drawq(Quad *quad, float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Call before using this Image's texture to draw. Binds the texture,
|
* Call before using this Image's texture to draw. Binds the texture,
|
||||||
* globally scales texture coordinates if the Image has NPOT dimensions and
|
* globally scales texture coordinates if the Image has NPOT dimensions and
|
||||||
* NPOT isn't supported, etc.
|
* NPOT isn't supported, etc.
|
||||||
**/
|
**/
|
||||||
virtual void predraw() const;
|
virtual void predraw();
|
||||||
virtual void postdraw() const;
|
virtual void postdraw();
|
||||||
|
|
||||||
virtual GLuint getGLTexture() const;
|
virtual GLuint getGLTexture() const;
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ private:
|
|||||||
|
|
||||||
void uploadDefaultTexture();
|
void uploadDefaultTexture();
|
||||||
|
|
||||||
void drawv(const Matrix &t, const Vertex *v) const;
|
void drawv(const Matrix &t, const Vertex *v);
|
||||||
|
|
||||||
// The ImageData from which the texture is created. May be null if
|
// The ImageData from which the texture is created. May be null if
|
||||||
// Compressed image data was used to create the texture.
|
// Compressed image data was used to create the texture.
|
||||||
|
|||||||
@@ -288,7 +288,7 @@ bool Mesh::isWireframe() const
|
|||||||
return wireframe;
|
return wireframe;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
|
void Mesh::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||||
{
|
{
|
||||||
const size_t pos_offset = offsetof(Vertex, x);
|
const size_t pos_offset = offsetof(Vertex, x);
|
||||||
const size_t tex_offset = offsetof(Vertex, s);
|
const size_t tex_offset = offsetof(Vertex, s);
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ public:
|
|||||||
bool isWireframe() const;
|
bool isWireframe() const;
|
||||||
|
|
||||||
// Implements Drawable.
|
// Implements Drawable.
|
||||||
void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
|
void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
||||||
|
|
||||||
static bool getConstant(const char *in, DrawMode &out);
|
static bool getConstant(const char *in, DrawMode &out);
|
||||||
static bool getConstant(DrawMode in, const char *&out);
|
static bool getConstant(DrawMode in, const char *&out);
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ OpenGL::OpenGL()
|
|||||||
: contextInitialized(false)
|
: contextInitialized(false)
|
||||||
, maxAnisotropy(1.0f)
|
, maxAnisotropy(1.0f)
|
||||||
, maxTextureSize(0)
|
, maxTextureSize(0)
|
||||||
|
, maxRenderTargets(0)
|
||||||
, vendor(VENDOR_UNKNOWN)
|
, vendor(VENDOR_UNKNOWN)
|
||||||
, state()
|
, state()
|
||||||
{
|
{
|
||||||
@@ -202,6 +203,19 @@ void OpenGL::initMaxValues()
|
|||||||
maxAnisotropy = 1.0f;
|
maxAnisotropy = 1.0f;
|
||||||
|
|
||||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
|
||||||
|
|
||||||
|
if (Canvas::isSupported() && (GLAD_VERSION_2_0 || GLAD_ARB_draw_buffers))
|
||||||
|
{
|
||||||
|
int maxattachments = 0;
|
||||||
|
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxattachments);
|
||||||
|
|
||||||
|
int maxdrawbuffers = 0;
|
||||||
|
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxdrawbuffers);
|
||||||
|
|
||||||
|
maxRenderTargets = std::min(maxattachments, maxdrawbuffers);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
maxRenderTargets = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGL::initMatrices()
|
void OpenGL::initMatrices()
|
||||||
@@ -260,6 +274,18 @@ void OpenGL::prepareDraw()
|
|||||||
glVertexAttrib1f((GLuint) ATTRIB_PSEUDO_INSTANCE_ID, 0.0f);
|
glVertexAttrib1f((GLuint) ATTRIB_PSEUDO_INSTANCE_ID, 0.0f);
|
||||||
state.lastPseudoInstanceID = 0;
|
state.lastPseudoInstanceID = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to make sure antialiased Canvases are properly resolved
|
||||||
|
// before sampling from their textures in a shader.
|
||||||
|
// This is kind of a big hack. :(
|
||||||
|
const std::map<std::string, Object *> &r = shader->getBoundRetainables();
|
||||||
|
for (auto it = r.begin(); it != r.end(); ++it)
|
||||||
|
{
|
||||||
|
// Even bigger hack! D:
|
||||||
|
Canvas *canvas = dynamic_cast<Canvas *>(it->second);
|
||||||
|
if (canvas != nullptr)
|
||||||
|
canvas->resolveMSAA();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GLAD_ES_VERSION_2_0 && shader)
|
if (GLAD_ES_VERSION_2_0 && shader)
|
||||||
@@ -716,11 +742,77 @@ int OpenGL::getMaxTextureSize() const
|
|||||||
return maxTextureSize;
|
return maxTextureSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int OpenGL::getMaxRenderTargets() const
|
||||||
|
{
|
||||||
|
return maxRenderTargets;
|
||||||
|
}
|
||||||
|
|
||||||
OpenGL::Vendor OpenGL::getVendor() const
|
OpenGL::Vendor OpenGL::getVendor() const
|
||||||
{
|
{
|
||||||
return vendor;
|
return vendor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *OpenGL::debugSeverityString(GLenum severity)
|
||||||
|
{
|
||||||
|
switch (severity)
|
||||||
|
{
|
||||||
|
case GL_DEBUG_SEVERITY_HIGH:
|
||||||
|
return "high";
|
||||||
|
case GL_DEBUG_SEVERITY_MEDIUM:
|
||||||
|
return "medium";
|
||||||
|
case GL_DEBUG_SEVERITY_LOW:
|
||||||
|
return "low";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *OpenGL::debugSourceString(GLenum source)
|
||||||
|
{
|
||||||
|
switch (source)
|
||||||
|
{
|
||||||
|
case GL_DEBUG_SOURCE_API:
|
||||||
|
return "API";
|
||||||
|
case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
|
||||||
|
return "window";
|
||||||
|
case GL_DEBUG_SOURCE_SHADER_COMPILER:
|
||||||
|
return "shader";
|
||||||
|
case GL_DEBUG_SOURCE_THIRD_PARTY:
|
||||||
|
return "external";
|
||||||
|
case GL_DEBUG_SOURCE_APPLICATION:
|
||||||
|
return "LOVE";
|
||||||
|
case GL_DEBUG_SOURCE_OTHER:
|
||||||
|
return "other";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *OpenGL::debugTypeString(GLenum type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case GL_DEBUG_TYPE_ERROR:
|
||||||
|
return "error";
|
||||||
|
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
|
||||||
|
return "deprecated behavior";
|
||||||
|
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
|
||||||
|
return "undefined behavior";
|
||||||
|
case GL_DEBUG_TYPE_PERFORMANCE:
|
||||||
|
return "performance";
|
||||||
|
case GL_DEBUG_TYPE_PORTABILITY:
|
||||||
|
return "portability";
|
||||||
|
case GL_DEBUG_TYPE_OTHER:
|
||||||
|
return "other";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// OpenGL class instance singleton.
|
// OpenGL class instance singleton.
|
||||||
OpenGL gl;
|
OpenGL gl;
|
||||||
|
|
||||||
|
|||||||
@@ -96,6 +96,11 @@ public:
|
|||||||
Viewport(int _x, int _y, int _w, int _h)
|
Viewport(int _x, int _y, int _w, int _h)
|
||||||
: x(_x), y(_y), w(_w), h(_h)
|
: x(_x), y(_y), w(_w), h(_h)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
bool operator == (const Viewport &rhs) const
|
||||||
|
{
|
||||||
|
return x == rhs.x && y == rhs.y && w == rhs.w && h == rhs.h;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Transformation matrix stacks.
|
// Transformation matrix stacks.
|
||||||
@@ -271,11 +276,21 @@ public:
|
|||||||
**/
|
**/
|
||||||
int getMaxTextureSize() const;
|
int getMaxTextureSize() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum supported number of simultaneous render targets.
|
||||||
|
**/
|
||||||
|
int getMaxRenderTargets() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the GPU vendor of this OpenGL context.
|
* Get the GPU vendor of this OpenGL context.
|
||||||
**/
|
**/
|
||||||
Vendor getVendor() const;
|
Vendor getVendor() const;
|
||||||
|
|
||||||
|
// Get human-readable strings for debug info.
|
||||||
|
static const char *debugSeverityString(GLenum severity);
|
||||||
|
static const char *debugSourceString(GLenum source);
|
||||||
|
static const char *debugTypeString(GLenum type);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void initVendor();
|
void initVendor();
|
||||||
@@ -290,6 +305,7 @@ private:
|
|||||||
|
|
||||||
float maxAnisotropy;
|
float maxAnisotropy;
|
||||||
int maxTextureSize;
|
int maxTextureSize;
|
||||||
|
int maxRenderTargets;
|
||||||
|
|
||||||
Vendor vendor;
|
Vendor vendor;
|
||||||
|
|
||||||
|
|||||||
@@ -442,14 +442,14 @@ ParticleSystem::InsertMode ParticleSystem::getInsertMode() const
|
|||||||
return insertMode;
|
return insertMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleSystem::setEmissionRate(int rate)
|
void ParticleSystem::setEmissionRate(float rate)
|
||||||
{
|
{
|
||||||
if (rate < 0)
|
if (rate < 0.0f)
|
||||||
throw love::Exception("Invalid emission rate");
|
throw love::Exception("Invalid emission rate");
|
||||||
emissionRate = rate;
|
emissionRate = rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ParticleSystem::getEmissionRate() const
|
float ParticleSystem::getEmissionRate() const
|
||||||
{
|
{
|
||||||
return emissionRate;
|
return emissionRate;
|
||||||
}
|
}
|
||||||
@@ -484,6 +484,7 @@ void ParticleSystem::getParticleLifetime(float *min, float *max) const
|
|||||||
void ParticleSystem::setPosition(float x, float y)
|
void ParticleSystem::setPosition(float x, float y)
|
||||||
{
|
{
|
||||||
position = love::Vector(x, y);
|
position = love::Vector(x, y);
|
||||||
|
prevPosition = position;
|
||||||
}
|
}
|
||||||
|
|
||||||
const love::Vector &ParticleSystem::getPosition() const
|
const love::Vector &ParticleSystem::getPosition() const
|
||||||
@@ -491,6 +492,11 @@ const love::Vector &ParticleSystem::getPosition() const
|
|||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ParticleSystem::moveTo(float x, float y)
|
||||||
|
{
|
||||||
|
position = love::Vector(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
void ParticleSystem::setAreaSpread(AreaSpreadDistribution distribution, float x, float y)
|
void ParticleSystem::setAreaSpread(AreaSpreadDistribution distribution, float x, float y)
|
||||||
{
|
{
|
||||||
areaSpread = love::Vector(x, y);
|
areaSpread = love::Vector(x, y);
|
||||||
@@ -790,7 +796,7 @@ bool ParticleSystem::isFull() const
|
|||||||
return activeParticles == maxParticles;
|
return activeParticles == maxParticles;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
|
void ParticleSystem::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||||
{
|
{
|
||||||
uint32 pCount = getCount();
|
uint32 pCount = getCount();
|
||||||
if (pCount == 0 || texture == nullptr || pMem == nullptr || particleVerts == nullptr)
|
if (pCount == 0 || texture == nullptr || pMem == nullptr || particleVerts == nullptr)
|
||||||
|
|||||||
@@ -132,12 +132,12 @@ public:
|
|||||||
* Sets the emission rate.
|
* Sets the emission rate.
|
||||||
* @param rate The amount of particles per second.
|
* @param rate The amount of particles per second.
|
||||||
**/
|
**/
|
||||||
void setEmissionRate(int rate);
|
void setEmissionRate(float rate);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of particles created per second.
|
* Returns the number of particles created per second.
|
||||||
**/
|
**/
|
||||||
int getEmissionRate() const;
|
float getEmissionRate() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the lifetime of the particle emitter (-1 means eternal)
|
* Sets the lifetime of the particle emitter (-1 means eternal)
|
||||||
@@ -177,6 +177,15 @@ public:
|
|||||||
**/
|
**/
|
||||||
const love::Vector &getPosition() const;
|
const love::Vector &getPosition() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the position of the center of the emitter.
|
||||||
|
* When update is called, newly spawned particles will appear in a line
|
||||||
|
* between the old emitter position and where the emitter was moved to,
|
||||||
|
* resulting in a smoother-feeling particle system if moveTo is called
|
||||||
|
* repeatedly.
|
||||||
|
**/
|
||||||
|
void moveTo(float x, float y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the emission area spread parameters and distribution type. The interpretation of
|
* Sets the emission area spread parameters and distribution type. The interpretation of
|
||||||
* the parameters depends on the distribution type:
|
* the parameters depends on the distribution type:
|
||||||
@@ -471,7 +480,7 @@ public:
|
|||||||
* @param x The x-coordinate.
|
* @param x The x-coordinate.
|
||||||
* @param y The y-coordinate.
|
* @param y The y-coordinate.
|
||||||
**/
|
**/
|
||||||
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
|
virtual void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the particle system.
|
* Updates the particle system.
|
||||||
@@ -551,7 +560,7 @@ protected:
|
|||||||
uint32 activeParticles;
|
uint32 activeParticles;
|
||||||
|
|
||||||
// The emission rate (particles/sec).
|
// The emission rate (particles/sec).
|
||||||
int emissionRate;
|
float emissionRate;
|
||||||
|
|
||||||
// Used to determine when a particle should be emitted.
|
// Used to determine when a particle should be emitted.
|
||||||
float emitCounter;
|
float emitCounter;
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ Shader::Shader(const ShaderSources &sources)
|
|||||||
, builtinUniforms()
|
, builtinUniforms()
|
||||||
, vertexAttributes()
|
, vertexAttributes()
|
||||||
, lastCanvas((Canvas *) -1)
|
, lastCanvas((Canvas *) -1)
|
||||||
|
, lastViewport()
|
||||||
{
|
{
|
||||||
if (shaderSources.empty())
|
if (shaderSources.empty())
|
||||||
throw love::Exception("Cannot create shader: no source code!");
|
throw love::Exception("Cannot create shader: no source code!");
|
||||||
@@ -753,30 +754,42 @@ bool Shader::sendBuiltinMatrix(BuiltinExtern builtin, int size, const GLfloat *m
|
|||||||
|
|
||||||
void Shader::checkSetScreenParams()
|
void Shader::checkSetScreenParams()
|
||||||
{
|
{
|
||||||
if (lastCanvas == Canvas::current)
|
OpenGL::Viewport view = gl.getViewport();
|
||||||
|
|
||||||
|
if (view == lastViewport && lastCanvas == Canvas::current)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// In the shader, we do pixcoord.y = gl_FragCoord.y * params[0] + params[1].
|
// In the shader, we do pixcoord.y = gl_FragCoord.y * params.z + params.w.
|
||||||
// This lets us flip pixcoord.y when needed, to be consistent (Canvases
|
// This lets us flip pixcoord.y when needed, to be consistent (Canvases
|
||||||
// have flipped y-values for pixel coordinates.)
|
// have flipped y-values for pixel coordinates.)
|
||||||
GLfloat params[] = {0.0f, 0.0f};
|
GLfloat params[] = {
|
||||||
|
(GLfloat) view.w, (GLfloat) view.h,
|
||||||
|
0.0f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
if (Canvas::current != nullptr)
|
if (Canvas::current != nullptr)
|
||||||
{
|
{
|
||||||
// gl_FragCoord.y is flipped in Canvases, so we un-flip:
|
// gl_FragCoord.y is flipped in Canvases, so we un-flip:
|
||||||
// pixcoord.y = gl_FragCoord.y * -1.0 + height.
|
// pixcoord.y = gl_FragCoord.y * -1.0 + height.
|
||||||
params[0] = -1.0f;
|
params[2] = -1.0f;
|
||||||
params[1] = (float) Canvas::current->getHeight();
|
params[3] = (GLfloat) view.h;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// No flipping: pixcoord.y = gl_FragCoord.y * 1.0 + 0.0.
|
// No flipping: pixcoord.y = gl_FragCoord.y * 1.0 + 0.0.
|
||||||
params[0] = 1.0f;
|
params[2] = 1.0f;
|
||||||
params[1] = 0.0f;
|
params[3] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
sendBuiltinFloat(BUILTIN_SCREEN_PARAMS, 2, params, 1);
|
sendBuiltinFloat(BUILTIN_SCREEN_SIZE, 4, params, 1);
|
||||||
|
|
||||||
lastCanvas = Canvas::current;
|
lastCanvas = Canvas::current;
|
||||||
|
lastViewport = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::map<std::string, Object *> &Shader::getBoundRetainables() const
|
||||||
|
{
|
||||||
|
return boundRetainables;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Shader::getGLSLVersion()
|
std::string Shader::getGLSLVersion()
|
||||||
@@ -829,7 +842,7 @@ StringMap<Shader::BuiltinExtern, Shader::BUILTIN_MAX_ENUM>::Entry Shader::builti
|
|||||||
{"ProjectionMatrix", Shader::BUILTIN_PROJECTION_MATRIX},
|
{"ProjectionMatrix", Shader::BUILTIN_PROJECTION_MATRIX},
|
||||||
{"TransformProjectionMatrix", Shader::BUILTIN_TRANSFORM_PROJECTION_MATRIX},
|
{"TransformProjectionMatrix", Shader::BUILTIN_TRANSFORM_PROJECTION_MATRIX},
|
||||||
{"love_PointSize", Shader::BUILTIN_POINT_SIZE},
|
{"love_PointSize", Shader::BUILTIN_POINT_SIZE},
|
||||||
{"love_ScreenParams", Shader::BUILTIN_SCREEN_PARAMS},
|
{"love_ScreenSize", Shader::BUILTIN_SCREEN_SIZE},
|
||||||
};
|
};
|
||||||
|
|
||||||
StringMap<Shader::BuiltinExtern, Shader::BUILTIN_MAX_ENUM> Shader::builtinNames(Shader::builtinNameEntries, sizeof(Shader::builtinNameEntries));
|
StringMap<Shader::BuiltinExtern, Shader::BUILTIN_MAX_ENUM> Shader::builtinNames(Shader::builtinNameEntries, sizeof(Shader::builtinNameEntries));
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public:
|
|||||||
BUILTIN_PROJECTION_MATRIX,
|
BUILTIN_PROJECTION_MATRIX,
|
||||||
BUILTIN_TRANSFORM_PROJECTION_MATRIX,
|
BUILTIN_TRANSFORM_PROJECTION_MATRIX,
|
||||||
BUILTIN_POINT_SIZE,
|
BUILTIN_POINT_SIZE,
|
||||||
BUILTIN_SCREEN_PARAMS,
|
BUILTIN_SCREEN_SIZE,
|
||||||
BUILTIN_MAX_ENUM
|
BUILTIN_MAX_ENUM
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -152,6 +152,8 @@ public:
|
|||||||
bool sendBuiltinFloat(BuiltinExtern builtin, int size, const GLfloat *m, int count);
|
bool sendBuiltinFloat(BuiltinExtern builtin, int size, const GLfloat *m, int count);
|
||||||
void checkSetScreenParams();
|
void checkSetScreenParams();
|
||||||
|
|
||||||
|
const std::map<std::string, Object *> &getBoundRetainables() const;
|
||||||
|
|
||||||
static std::string getGLSLVersion();
|
static std::string getGLSLVersion();
|
||||||
static bool isSupported();
|
static bool isSupported();
|
||||||
|
|
||||||
@@ -227,6 +229,7 @@ private:
|
|||||||
|
|
||||||
// Pointer to the active Canvas when the screen params were last checked.
|
// Pointer to the active Canvas when the screen params were last checked.
|
||||||
Canvas *lastCanvas;
|
Canvas *lastCanvas;
|
||||||
|
OpenGL::Viewport lastViewport;
|
||||||
|
|
||||||
// Max GPU texture units available for sent images
|
// Max GPU texture units available for sent images
|
||||||
static GLint maxTexUnits;
|
static GLint maxTexUnits;
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ int SpriteBatch::getBufferSize() const
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const
|
void SpriteBatch::draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky)
|
||||||
{
|
{
|
||||||
const size_t vertex_offset = offsetof(Vertex, x);
|
const size_t vertex_offset = offsetof(Vertex, x);
|
||||||
const size_t texel_offset = offsetof(Vertex, s);
|
const size_t texel_offset = offsetof(Vertex, s);
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public:
|
|||||||
int getBufferSize() const;
|
int getBufferSize() const;
|
||||||
|
|
||||||
// Implements Drawable.
|
// Implements Drawable.
|
||||||
void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky) const;
|
void draw(float x, float y, float angle, float sx, float sy, float ox, float oy, float kx, float ky);
|
||||||
|
|
||||||
static bool getConstant(const char *in, UsageHint &out);
|
static bool getConstant(const char *in, UsageHint &out);
|
||||||
static bool getConstant(UsageHint in, const char *&out);
|
static bool getConstant(UsageHint in, const char *&out);
|
||||||
|
|||||||
@@ -48,12 +48,12 @@ public:
|
|||||||
* Any setup the texture might need to do before drawing, e.g. binding
|
* Any setup the texture might need to do before drawing, e.g. binding
|
||||||
* the OpenGL texture for use.
|
* the OpenGL texture for use.
|
||||||
**/
|
**/
|
||||||
virtual void predraw() const {}
|
virtual void predraw() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any cleanup the texture might need to do directly after drawing.
|
* Any cleanup the texture might need to do directly after drawing.
|
||||||
**/
|
**/
|
||||||
virtual void postdraw() const {}
|
virtual void postdraw() {}
|
||||||
|
|
||||||
|
|
||||||
}; // Texture
|
}; // Texture
|
||||||
|
|||||||
@@ -120,6 +120,13 @@ int w_Canvas_getType(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int w_Canvas_getFSAA(lua_State *L)
|
||||||
|
{
|
||||||
|
Canvas *canvas = luax_checkcanvas(L, 1);
|
||||||
|
lua_pushinteger(L, canvas->getFSAA());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static const luaL_Reg functions[] =
|
static const luaL_Reg functions[] =
|
||||||
{
|
{
|
||||||
// From wrap_Texture.
|
// From wrap_Texture.
|
||||||
@@ -136,6 +143,7 @@ static const luaL_Reg functions[] =
|
|||||||
{ "getPixel", w_Canvas_getPixel },
|
{ "getPixel", w_Canvas_getPixel },
|
||||||
{ "clear", w_Canvas_clear },
|
{ "clear", w_Canvas_clear },
|
||||||
{ "getType", w_Canvas_getType },
|
{ "getType", w_Canvas_getType },
|
||||||
|
{ "getFSAA", w_Canvas_getFSAA },
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ int w_Canvas_getImageData(lua_State *L);
|
|||||||
int w_Canvas_getPixel(lua_State * L);
|
int w_Canvas_getPixel(lua_State * L);
|
||||||
int w_Canvas_clear(lua_State *L);
|
int w_Canvas_clear(lua_State *L);
|
||||||
int w_Canvas_getType(lua_State *L);
|
int w_Canvas_getType(lua_State *L);
|
||||||
|
int w_Canvas_getFSAA(lua_State *L);
|
||||||
extern "C" int luaopen_canvas(lua_State *L);
|
extern "C" int luaopen_canvas(lua_State *L);
|
||||||
|
|
||||||
} // opengl
|
} // opengl
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ int w_setInvertedStencil(lua_State *L)
|
|||||||
|
|
||||||
int w_getMaxTextureSize(lua_State *L)
|
int w_getMaxTextureSize(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_pushinteger(L, instance->getMaxTextureSize());
|
lua_pushinteger(L, instance->getSystemLimit(Graphics::LIMIT_TEXTURE_SIZE));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,15 +323,16 @@ int w_newCanvas(lua_State *L)
|
|||||||
int width = luaL_optint(L, 1, instance->getWidth());
|
int width = luaL_optint(L, 1, instance->getWidth());
|
||||||
int height = luaL_optint(L, 2, instance->getHeight());
|
int height = luaL_optint(L, 2, instance->getHeight());
|
||||||
const char *str = luaL_optstring(L, 3, "normal");
|
const char *str = luaL_optstring(L, 3, "normal");
|
||||||
|
int fsaa = luaL_optint(L, 4, 0);
|
||||||
|
|
||||||
Canvas::TextureType texture_type;
|
Canvas::TextureType texture_type;
|
||||||
if (!Canvas::getConstant(str, texture_type))
|
if (!Canvas::getConstant(str, texture_type))
|
||||||
return luaL_error(L, "Invalid canvas type: %s", str);
|
return luaL_error(L, "Invalid canvas type: %s", str);
|
||||||
|
|
||||||
Canvas *canvas = 0;
|
Canvas *canvas = nullptr;
|
||||||
EXCEPT_GUARD(canvas = instance->newCanvas(width, height, texture_type);)
|
EXCEPT_GUARD(canvas = instance->newCanvas(width, height, texture_type, fsaa);)
|
||||||
|
|
||||||
if (canvas == 0)
|
if (canvas == nullptr)
|
||||||
return luaL_error(L, "Canvas not created, but no error thrown. I don't even...");
|
return luaL_error(L, "Canvas not created, but no error thrown. I don't even...");
|
||||||
|
|
||||||
luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, canvas);
|
luax_pushtype(L, "Canvas", GRAPHICS_CANVAS_T, canvas);
|
||||||
@@ -830,7 +831,7 @@ int w_getPointStyle(lua_State *L)
|
|||||||
|
|
||||||
int w_getMaxPointSize(lua_State *L)
|
int w_getMaxPointSize(lua_State *L)
|
||||||
{
|
{
|
||||||
lua_pushnumber(L, instance->getMaxPointSize());
|
lua_pushnumber(L, instance->getSystemLimit(Graphics::LIMIT_POINT_SIZE));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1025,7 +1026,7 @@ int w_isSupported(lua_State *L)
|
|||||||
supported = false;
|
supported = false;
|
||||||
break;
|
break;
|
||||||
case Graphics::SUPPORT_INSTANCING:
|
case Graphics::SUPPORT_INSTANCING:
|
||||||
if (!GLAD_ARB_draw_instanced)
|
if (!(GLAD_ARB_draw_instanced || (GLAD_ES_VERSION_2_0 && GLAD_EXT_draw_instanced)))
|
||||||
supported = false;
|
supported = false;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1055,6 +1056,18 @@ int w_getRendererInfo(lua_State *L)
|
|||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int w_getSystemLimit(lua_State *L)
|
||||||
|
{
|
||||||
|
const char *limitstr = luaL_checkstring(L, 1);
|
||||||
|
Graphics::SystemLimit limittype;
|
||||||
|
|
||||||
|
if (!Graphics::getConstant(limitstr, limittype))
|
||||||
|
return luaL_error(L, "Invalid system limit type: %s", limitstr);
|
||||||
|
|
||||||
|
lua_pushnumber(L, instance->getSystemLimit(limittype));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int w_draw(lua_State *L)
|
int w_draw(lua_State *L)
|
||||||
{
|
{
|
||||||
Drawable *drawable = nullptr;
|
Drawable *drawable = nullptr;
|
||||||
@@ -1392,8 +1405,6 @@ static const luaL_Reg functions[] =
|
|||||||
{ "setPointStyle", w_setPointStyle },
|
{ "setPointStyle", w_setPointStyle },
|
||||||
{ "getPointSize", w_getPointSize },
|
{ "getPointSize", w_getPointSize },
|
||||||
{ "getPointStyle", w_getPointStyle },
|
{ "getPointStyle", w_getPointStyle },
|
||||||
{ "getMaxPointSize", w_getMaxPointSize },
|
|
||||||
{ "getMaxTextureSize", w_getMaxTextureSize },
|
|
||||||
{ "newScreenshot", w_newScreenshot },
|
{ "newScreenshot", w_newScreenshot },
|
||||||
{ "setCanvas", w_setCanvas },
|
{ "setCanvas", w_setCanvas },
|
||||||
{ "getCanvas", w_getCanvas },
|
{ "getCanvas", w_getCanvas },
|
||||||
@@ -1404,6 +1415,7 @@ static const luaL_Reg functions[] =
|
|||||||
|
|
||||||
{ "isSupported", w_isSupported },
|
{ "isSupported", w_isSupported },
|
||||||
{ "getRendererInfo", w_getRendererInfo },
|
{ "getRendererInfo", w_getRendererInfo },
|
||||||
|
{ "getSystemLimit", w_getSystemLimit },
|
||||||
|
|
||||||
{ "draw", w_draw },
|
{ "draw", w_draw },
|
||||||
|
|
||||||
@@ -1439,6 +1451,7 @@ static const luaL_Reg functions[] =
|
|||||||
|
|
||||||
// Deprecated since 0.9.1.
|
// Deprecated since 0.9.1.
|
||||||
{ "getMaxImageSize", w_getMaxTextureSize },
|
{ "getMaxImageSize", w_getMaxTextureSize },
|
||||||
|
{ "getMaxPointSize", w_getMaxPointSize },
|
||||||
|
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ int w_getShader(lua_State *L);
|
|||||||
int w_setDefaultShaderCode(lua_State *L);
|
int w_setDefaultShaderCode(lua_State *L);
|
||||||
int w_isSupported(lua_State *L);
|
int w_isSupported(lua_State *L);
|
||||||
int w_getRendererInfo(lua_State *L);
|
int w_getRendererInfo(lua_State *L);
|
||||||
|
int w_getSystemLimit(lua_State *L);
|
||||||
int w_draw(lua_State *L);
|
int w_draw(lua_State *L);
|
||||||
int w_print(lua_State *L);
|
int w_print(lua_State *L);
|
||||||
int w_printf(lua_State *L);
|
int w_printf(lua_State *L);
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ int w_ParticleSystem_getInsertMode(lua_State *L)
|
|||||||
int w_ParticleSystem_setEmissionRate(lua_State *L)
|
int w_ParticleSystem_setEmissionRate(lua_State *L)
|
||||||
{
|
{
|
||||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||||
int arg1 = luaL_checkint(L, 2);
|
float arg1 = (float) luaL_checknumber(L, 2);
|
||||||
EXCEPT_GUARD(t->setEmissionRate(arg1);)
|
EXCEPT_GUARD(t->setEmissionRate(arg1);)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -135,7 +135,7 @@ int w_ParticleSystem_setEmissionRate(lua_State *L)
|
|||||||
int w_ParticleSystem_getEmissionRate(lua_State *L)
|
int w_ParticleSystem_getEmissionRate(lua_State *L)
|
||||||
{
|
{
|
||||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||||
lua_pushinteger(L, t->getEmissionRate());
|
lua_pushnumber(L, t->getEmissionRate());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,6 +191,15 @@ int w_ParticleSystem_getPosition(lua_State *L)
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int w_ParticleSystem_moveTo(lua_State *L)
|
||||||
|
{
|
||||||
|
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||||
|
float arg1 = (float)luaL_checknumber(L, 2);
|
||||||
|
float arg2 = (float)luaL_checknumber(L, 3);
|
||||||
|
t->moveTo(arg1, arg2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int w_ParticleSystem_setAreaSpread(lua_State *L)
|
int w_ParticleSystem_setAreaSpread(lua_State *L)
|
||||||
{
|
{
|
||||||
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
ParticleSystem *t = luax_checkparticlesystem(L, 1);
|
||||||
@@ -649,6 +658,7 @@ static const luaL_Reg functions[] =
|
|||||||
{ "getParticleLifetime", w_ParticleSystem_getParticleLifetime },
|
{ "getParticleLifetime", w_ParticleSystem_getParticleLifetime },
|
||||||
{ "setPosition", w_ParticleSystem_setPosition },
|
{ "setPosition", w_ParticleSystem_setPosition },
|
||||||
{ "getPosition", w_ParticleSystem_getPosition },
|
{ "getPosition", w_ParticleSystem_getPosition },
|
||||||
|
{ "moveTo", w_ParticleSystem_moveTo },
|
||||||
{ "setAreaSpread", w_ParticleSystem_setAreaSpread },
|
{ "setAreaSpread", w_ParticleSystem_setAreaSpread },
|
||||||
{ "getAreaSpread", w_ParticleSystem_getAreaSpread },
|
{ "getAreaSpread", w_ParticleSystem_getAreaSpread },
|
||||||
{ "setDirection", w_ParticleSystem_setDirection },
|
{ "setDirection", w_ParticleSystem_setDirection },
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ int w_ParticleSystem_setParticleLifetime(lua_State *L);
|
|||||||
int w_ParticleSystem_getParticleLifetime(lua_State *L);
|
int w_ParticleSystem_getParticleLifetime(lua_State *L);
|
||||||
int w_ParticleSystem_setPosition(lua_State *L);
|
int w_ParticleSystem_setPosition(lua_State *L);
|
||||||
int w_ParticleSystem_getPosition(lua_State *L);
|
int w_ParticleSystem_getPosition(lua_State *L);
|
||||||
|
int w_ParticleSystem_moveTo(lua_State *L);
|
||||||
int w_ParticleSystem_setAreaSpread(lua_State *L);
|
int w_ParticleSystem_setAreaSpread(lua_State *L);
|
||||||
int w_ParticleSystem_getAreaSpread(lua_State *L);
|
int w_ParticleSystem_getAreaSpread(lua_State *L);
|
||||||
int w_ParticleSystem_setDirection(lua_State *L);
|
int w_ParticleSystem_setDirection(lua_State *L);
|
||||||
|
|||||||
@@ -182,6 +182,15 @@ const char *love_codename()
|
|||||||
return love::VERSION_CODENAME;
|
return love::VERSION_CODENAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int w_love_getVersion(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_pushinteger(L, love::VERSION_MAJOR);
|
||||||
|
lua_pushinteger(L, love::VERSION_MINOR);
|
||||||
|
lua_pushinteger(L, love::VERSION_REV);
|
||||||
|
lua_pushstring(L, love::VERSION_CODENAME);
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
int luaopen_love(lua_State * L)
|
int luaopen_love(lua_State * L)
|
||||||
{
|
{
|
||||||
love::luax_insistglobal(L, "love");
|
love::luax_insistglobal(L, "love");
|
||||||
@@ -215,6 +224,9 @@ int luaopen_love(lua_State * L)
|
|||||||
|
|
||||||
lua_setfield(L, -2, "_version_compat");
|
lua_setfield(L, -2, "_version_compat");
|
||||||
|
|
||||||
|
lua_pushcfunction(L, w_love_getVersion);
|
||||||
|
lua_setfield(L, -2, "getVersion");
|
||||||
|
|
||||||
#ifdef LOVE_WINDOWS
|
#ifdef LOVE_WINDOWS
|
||||||
lua_pushstring(L, "Windows");
|
lua_pushstring(L, "Windows");
|
||||||
#elif defined(LOVE_MACOSX)
|
#elif defined(LOVE_MACOSX)
|
||||||
|
|||||||
@@ -257,6 +257,18 @@ bool Window::setContext(int fsaa, bool vsync)
|
|||||||
context = SDL_GL_CreateContext(window);
|
context = SDL_GL_CreateContext(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!context)
|
||||||
|
{
|
||||||
|
int flags = 0;
|
||||||
|
SDL_GL_GetAttribute(SDL_GL_CONTEXT_FLAGS, &flags);
|
||||||
|
if (flags & SDL_GL_CONTEXT_DEBUG_FLAG)
|
||||||
|
{
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
|
||||||
|
context = SDL_GL_CreateContext(window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!context)
|
if (!context)
|
||||||
{
|
{
|
||||||
displayError("Could not create OpenGL context", SDL_GetError());
|
displayError("Could not create OpenGL context", SDL_GetError());
|
||||||
@@ -299,6 +311,8 @@ void Window::setWindowGLAttributes(int fsaa) const
|
|||||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0);
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0);
|
||||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
|
||||||
|
|
||||||
|
int contextprofile = 0;
|
||||||
|
|
||||||
bool tryES2 = false;
|
bool tryES2 = false;
|
||||||
|
|
||||||
const char *driver = SDL_GetCurrentVideoDriver();
|
const char *driver = SDL_GetCurrentVideoDriver();
|
||||||
@@ -314,17 +328,30 @@ void Window::setWindowGLAttributes(int fsaa) const
|
|||||||
if (tryES2)
|
if (tryES2)
|
||||||
{
|
{
|
||||||
// Use OpenGL ES 2+.
|
// Use OpenGL ES 2+.
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
contextprofile = SDL_GL_CONTEXT_PROFILE_ES;
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Use desktop OpenGL.
|
// Use desktop OpenGL.
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, 0);
|
contextprofile = 0;
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); // default
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2); // default
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Do we want a debug context?
|
||||||
|
const char *debugenv = SDL_GetHint("LOVE_GRAPHICS_DEBUG");
|
||||||
|
if (debugenv && *debugenv == '1')
|
||||||
|
{
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
|
||||||
|
if (!tryES2)
|
||||||
|
contextprofile |= SDL_GL_CONTEXT_PROFILE_COMPATIBILITY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||||
|
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, contextprofile);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::updateSettings(const WindowSettings &newsettings)
|
void Window::updateSettings(const WindowSettings &newsettings)
|
||||||
|
|||||||
@@ -179,6 +179,9 @@ function love.createhandlers()
|
|||||||
touchmoved = function (id,x,y,p)
|
touchmoved = function (id,x,y,p)
|
||||||
if love.touchmoved then return love.touchmoved(id,x,y,p) end
|
if love.touchmoved then return love.touchmoved(id,x,y,p) end
|
||||||
end,
|
end,
|
||||||
|
touchgestured = function (x,y,theta,dist,num)
|
||||||
|
if love.touchgestured then return love.touchgestured(x,y,theta,dist,num) end
|
||||||
|
end,
|
||||||
joystickpressed = function (j,b)
|
joystickpressed = function (j,b)
|
||||||
if love.joystickpressed then return love.joystickpressed(j,b) end
|
if love.joystickpressed then return love.joystickpressed(j,b) end
|
||||||
end,
|
end,
|
||||||
@@ -354,6 +357,11 @@ function love.init()
|
|||||||
c.console = true
|
c.console = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Console hack
|
||||||
|
if c.console and love._openConsole then
|
||||||
|
love._openConsole()
|
||||||
|
end
|
||||||
|
|
||||||
-- Gets desired modules.
|
-- Gets desired modules.
|
||||||
for k,v in ipairs{
|
for k,v in ipairs{
|
||||||
"android",
|
"android",
|
||||||
@@ -383,11 +391,6 @@ function love.init()
|
|||||||
love.createhandlers()
|
love.createhandlers()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Console hack
|
|
||||||
if c.console and love._openConsole then
|
|
||||||
love._openConsole()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Setup window here.
|
-- Setup window here.
|
||||||
if c.window and c.modules.window then
|
if c.window and c.modules.window then
|
||||||
assert(love.window.setMode(c.window.width, c.window.height,
|
assert(love.window.setMode(c.window.width, c.window.height,
|
||||||
@@ -488,7 +491,7 @@ function love.run()
|
|||||||
-- Process events.
|
-- Process events.
|
||||||
if love.event then
|
if love.event then
|
||||||
love.event.pump()
|
love.event.pump()
|
||||||
for n,a,b,c,d in love.event.poll() do
|
for n,a,b,c,d,e in love.event.poll() do
|
||||||
if n == "quit" then
|
if n == "quit" then
|
||||||
if not love.quit or not love.quit() then
|
if not love.quit or not love.quit() then
|
||||||
if love.audio then
|
if love.audio then
|
||||||
@@ -497,7 +500,7 @@ function love.run()
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
love.handlers[n](a,b,c,d)
|
love.handlers[n](a,b,c,d,e)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -319,6 +319,15 @@ const unsigned char boot_lua[] =
|
|||||||
0x76, 0x65, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x28, 0x69, 0x64, 0x2c, 0x78,
|
0x76, 0x65, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x28, 0x69, 0x64, 0x2c, 0x78,
|
||||||
0x2c, 0x79, 0x2c, 0x70, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
|
0x2c, 0x79, 0x2c, 0x70, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
|
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
|
||||||
|
0x09, 0x09, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x67, 0x65, 0x73, 0x74, 0x75, 0x72, 0x65, 0x64, 0x20, 0x3d, 0x20,
|
||||||
|
0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x74, 0x68, 0x65, 0x74,
|
||||||
|
0x61, 0x2c, 0x64, 0x69, 0x73, 0x74, 0x2c, 0x6e, 0x75, 0x6d, 0x29, 0x0a,
|
||||||
|
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x67, 0x65,
|
||||||
|
0x73, 0x74, 0x75, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
|
||||||
|
0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x6f, 0x75, 0x63, 0x68, 0x67, 0x65, 0x73, 0x74, 0x75, 0x72, 0x65,
|
||||||
|
0x64, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x74, 0x68, 0x65, 0x74, 0x61, 0x2c, 0x64, 0x69, 0x73, 0x74, 0x2c, 0x6e,
|
||||||
|
0x75, 0x6d, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
|
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
|
||||||
0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20,
|
0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20,
|
||||||
0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x0a,
|
0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63,
|
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63,
|
||||||
@@ -625,6 +634,13 @@ const unsigned char boot_lua[] =
|
|||||||
0x6e, 0x0a,
|
0x6e, 0x0a,
|
||||||
0x09, 0x09, 0x63, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a,
|
0x09, 0x09, 0x63, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x0a,
|
||||||
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
|
0x09, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x63, 0x6b, 0x0a,
|
||||||
|
0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20,
|
||||||
|
0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20,
|
||||||
|
0x74, 0x68, 0x65, 0x6e, 0x0a,
|
||||||
|
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c,
|
||||||
|
0x65, 0x28, 0x29, 0x0a,
|
||||||
|
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
0x09, 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x74, 0x73, 0x20, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x20, 0x6d,
|
0x09, 0x2d, 0x2d, 0x20, 0x47, 0x65, 0x74, 0x73, 0x20, 0x64, 0x65, 0x73, 0x69, 0x72, 0x65, 0x64, 0x20, 0x6d,
|
||||||
0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x0a,
|
0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x2e, 0x0a,
|
||||||
0x09, 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, 0x73,
|
0x09, 0x66, 0x6f, 0x72, 0x20, 0x6b, 0x2c, 0x76, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x70, 0x61, 0x69, 0x72, 0x73,
|
||||||
@@ -658,13 +674,6 @@ const unsigned char boot_lua[] =
|
|||||||
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x68, 0x61, 0x6e, 0x64, 0x6c,
|
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x68, 0x61, 0x6e, 0x64, 0x6c,
|
||||||
0x65, 0x72, 0x73, 0x28, 0x29, 0x0a,
|
0x65, 0x72, 0x73, 0x28, 0x29, 0x0a,
|
||||||
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
0x09, 0x2d, 0x2d, 0x20, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x68, 0x61, 0x63, 0x6b, 0x0a,
|
|
||||||
0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20, 0x61, 0x6e, 0x64, 0x20,
|
|
||||||
0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x20,
|
|
||||||
0x74, 0x68, 0x65, 0x6e, 0x0a,
|
|
||||||
0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c,
|
|
||||||
0x65, 0x28, 0x29, 0x0a,
|
|
||||||
0x09, 0x65, 0x6e, 0x64, 0x0a,
|
|
||||||
0x09, 0x2d, 0x2d, 0x20, 0x53, 0x65, 0x74, 0x75, 0x70, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x68,
|
0x09, 0x2d, 0x2d, 0x20, 0x53, 0x65, 0x74, 0x75, 0x70, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x68,
|
||||||
0x65, 0x72, 0x65, 0x2e, 0x0a,
|
0x65, 0x72, 0x65, 0x2e, 0x0a,
|
||||||
0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63,
|
0x09, 0x69, 0x66, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x63,
|
||||||
@@ -863,9 +872,9 @@ const unsigned char boot_lua[] =
|
|||||||
0x65, 0x6e, 0x0a,
|
0x65, 0x6e, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, 0x6d, 0x70,
|
0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x75, 0x6d, 0x70,
|
||||||
0x28, 0x29, 0x0a,
|
0x28, 0x29, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x2c, 0x61, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x20, 0x69,
|
0x09, 0x09, 0x09, 0x66, 0x6f, 0x72, 0x20, 0x6e, 0x2c, 0x61, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x2c, 0x65,
|
||||||
0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x6f, 0x6c, 0x6c, 0x28,
|
0x20, 0x69, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x6f, 0x6c,
|
||||||
0x29, 0x20, 0x64, 0x6f, 0x0a,
|
0x6c, 0x28, 0x29, 0x20, 0x64, 0x6f, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x71, 0x75, 0x69, 0x74, 0x22,
|
0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x20, 0x3d, 0x3d, 0x20, 0x22, 0x71, 0x75, 0x69, 0x74, 0x22,
|
||||||
0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
|
0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x71,
|
0x09, 0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x71,
|
||||||
@@ -880,7 +889,7 @@ const unsigned char boot_lua[] =
|
|||||||
0x09, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
|
0x09, 0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
|
0x09, 0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x5b,
|
0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x73, 0x5b,
|
||||||
0x6e, 0x5d, 0x28, 0x61, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x29, 0x0a,
|
0x6e, 0x5d, 0x28, 0x61, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x2c, 0x65, 0x29, 0x0a,
|
||||||
0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
|
0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
|
0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
|
||||||
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x64, 0x74, 0x2c, 0x20, 0x61, 0x73,
|
0x09, 0x09, 0x2d, 0x2d, 0x20, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x20, 0x64, 0x74, 0x2c, 0x20, 0x61, 0x73,
|
||||||
|
|||||||
@@ -1310,7 +1310,7 @@ do
|
|||||||
#define TransformProjectionMatrix gl_ModelViewProjectionMatrix
|
#define TransformProjectionMatrix gl_ModelViewProjectionMatrix
|
||||||
#define NormalMatrix gl_NormalMatrix
|
#define NormalMatrix gl_NormalMatrix
|
||||||
uniform sampler2D _tex0_;
|
uniform sampler2D _tex0_;
|
||||||
uniform vec2 love_ScreenParams;]]
|
uniform vec4 love_ScreenSize;]]
|
||||||
|
|
||||||
GLSLES.UNIFORMS = [[
|
GLSLES.UNIFORMS = [[
|
||||||
uniform mat4 TransformMatrix;
|
uniform mat4 TransformMatrix;
|
||||||
@@ -1319,7 +1319,7 @@ uniform mat4 TransformProjectionMatrix;
|
|||||||
// uniform mat4 NormalMatrix;
|
// uniform mat4 NormalMatrix;
|
||||||
uniform float love_PointSize;
|
uniform float love_PointSize;
|
||||||
uniform sampler2D _tex0_;
|
uniform sampler2D _tex0_;
|
||||||
uniform vec2 love_ScreenParams;]]
|
uniform vec4 love_ScreenSize;]]
|
||||||
|
|
||||||
GLSL.VERTEX = {
|
GLSL.VERTEX = {
|
||||||
HEADER = [[
|
HEADER = [[
|
||||||
@@ -1390,7 +1390,7 @@ void main() {
|
|||||||
float dummy = texture2D(_tex0_, vec2(.5)).r;
|
float dummy = texture2D(_tex0_, vec2(.5)).r;
|
||||||
|
|
||||||
// See Shader::checkSetScreenParams in Shader.cpp.
|
// See Shader::checkSetScreenParams in Shader.cpp.
|
||||||
vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenParams[0]) + love_ScreenParams[1]);
|
vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
|
||||||
|
|
||||||
gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord);
|
gl_FragColor = effect(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord);
|
||||||
}]],
|
}]],
|
||||||
@@ -1401,7 +1401,7 @@ void main() {
|
|||||||
float dummy = texture2D(_tex0_, vec2(.5)).r;
|
float dummy = texture2D(_tex0_, vec2(.5)).r;
|
||||||
|
|
||||||
// See Shader::checkSetScreenParams in Shader.cpp.
|
// See Shader::checkSetScreenParams in Shader.cpp.
|
||||||
vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenParams[0]) + love_ScreenParams[1]);
|
vec2 pixelcoord = vec2(gl_FragCoord.x, (gl_FragCoord.y * love_ScreenSize.z) + love_ScreenSize.w);
|
||||||
|
|
||||||
effects(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord);
|
effects(VaryingColor, _tex0_, VaryingTexCoord.st, pixelcoord);
|
||||||
}]],
|
}]],
|
||||||
|
|||||||
@@ -6299,8 +6299,8 @@ const unsigned char graphics_lua[] =
|
|||||||
0x69, 0x78, 0x20, 0x67, 0x6c, 0x5f, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x0a,
|
0x69, 0x78, 0x20, 0x67, 0x6c, 0x5f, 0x4e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x72, 0x69, 0x78, 0x0a,
|
||||||
0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20,
|
0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20,
|
||||||
0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x0a,
|
0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x0a,
|
||||||
0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f,
|
0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f,
|
||||||
0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3b, 0x5d, 0x5d, 0x0a,
|
0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x3b, 0x5d, 0x5d, 0x0a,
|
||||||
0x09, 0x47, 0x4c, 0x53, 0x4c, 0x45, 0x53, 0x2e, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x20, 0x3d,
|
0x09, 0x47, 0x4c, 0x53, 0x4c, 0x45, 0x53, 0x2e, 0x55, 0x4e, 0x49, 0x46, 0x4f, 0x52, 0x4d, 0x53, 0x20, 0x3d,
|
||||||
0x20, 0x5b, 0x5b, 0x0a,
|
0x20, 0x5b, 0x5b, 0x0a,
|
||||||
0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73,
|
0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x6d, 0x61, 0x74, 0x34, 0x20, 0x54, 0x72, 0x61, 0x6e, 0x73,
|
||||||
@@ -6316,8 +6316,8 @@ const unsigned char graphics_lua[] =
|
|||||||
0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x3b, 0x0a,
|
0x5f, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x53, 0x69, 0x7a, 0x65, 0x3b, 0x0a,
|
||||||
0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20,
|
0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x73, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x32, 0x44, 0x20,
|
||||||
0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x0a,
|
0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x3b, 0x0a,
|
||||||
0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x32, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f,
|
0x75, 0x6e, 0x69, 0x66, 0x6f, 0x72, 0x6d, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f,
|
||||||
0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3b, 0x5d, 0x5d, 0x0a,
|
0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x53, 0x69, 0x7a, 0x65, 0x3b, 0x5d, 0x5d, 0x0a,
|
||||||
0x09, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x20, 0x3d, 0x20, 0x7b, 0x0a,
|
0x09, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x20, 0x3d, 0x20, 0x7b, 0x0a,
|
||||||
0x09, 0x09, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
|
0x09, 0x09, 0x48, 0x45, 0x41, 0x44, 0x45, 0x52, 0x20, 0x3d, 0x20, 0x5b, 0x5b, 0x0a,
|
||||||
0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x0a,
|
0x23, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x20, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x0a,
|
||||||
@@ -6429,9 +6429,9 @@ const unsigned char graphics_lua[] =
|
|||||||
0x09, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d,
|
0x09, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d,
|
||||||
0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64,
|
0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64,
|
||||||
0x2e, 0x78, 0x2c, 0x20, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e,
|
0x2e, 0x78, 0x2c, 0x20, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e,
|
||||||
0x79, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72,
|
0x79, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x53, 0x69, 0x7a,
|
||||||
0x61, 0x6d, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72,
|
0x65, 0x2e, 0x7a, 0x29, 0x20, 0x2b, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e,
|
||||||
0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a,
|
0x53, 0x69, 0x7a, 0x65, 0x2e, 0x77, 0x29, 0x3b, 0x0a,
|
||||||
0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x65, 0x66,
|
0x09, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x20, 0x3d, 0x20, 0x65, 0x66,
|
||||||
0x66, 0x65, 0x63, 0x74, 0x28, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c,
|
0x66, 0x65, 0x63, 0x74, 0x28, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x2c,
|
||||||
0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x54, 0x65,
|
0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x54, 0x65,
|
||||||
@@ -6454,9 +6454,9 @@ const unsigned char graphics_lua[] =
|
|||||||
0x09, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d,
|
0x09, 0x76, 0x65, 0x63, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x20, 0x3d,
|
||||||
0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64,
|
0x20, 0x76, 0x65, 0x63, 0x32, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64,
|
||||||
0x2e, 0x78, 0x2c, 0x20, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e,
|
0x2e, 0x78, 0x2c, 0x20, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e,
|
||||||
0x79, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x50, 0x61, 0x72,
|
0x79, 0x20, 0x2a, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x53, 0x69, 0x7a,
|
||||||
0x61, 0x6d, 0x73, 0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2b, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72,
|
0x65, 0x2e, 0x7a, 0x29, 0x20, 0x2b, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x5f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e,
|
||||||
0x65, 0x65, 0x6e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0a,
|
0x53, 0x69, 0x7a, 0x65, 0x2e, 0x77, 0x29, 0x3b, 0x0a,
|
||||||
0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x28, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f,
|
0x09, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x73, 0x28, 0x56, 0x61, 0x72, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x6f,
|
||||||
0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69,
|
0x6c, 0x6f, 0x72, 0x2c, 0x20, 0x5f, 0x74, 0x65, 0x78, 0x30, 0x5f, 0x2c, 0x20, 0x56, 0x61, 0x72, 0x79, 0x69,
|
||||||
0x6e, 0x67, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x73, 0x74, 0x2c, 0x20, 0x70, 0x69, 0x78,
|
0x6e, 0x67, 0x54, 0x65, 0x78, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x73, 0x74, 0x2c, 0x20, 0x70, 0x69, 0x78,
|
||||||
|
|||||||
Reference in New Issue
Block a user