Refactor overlay image code to an own subclass
parent
974686cf15
commit
e546a53e19
|
@ -834,12 +834,12 @@ Command* CommandParser::parseCommand()
|
|||
}
|
||||
else if (commandName == "overlay")
|
||||
{
|
||||
double duration;
|
||||
float duration;
|
||||
float xoffset;
|
||||
float yoffset;
|
||||
float alpha;
|
||||
string filename;
|
||||
int fitscreen;
|
||||
bool fitscreen;
|
||||
|
||||
if(!paramList->getNumber("duration", duration))
|
||||
duration = 3;
|
||||
|
@ -851,8 +851,14 @@ Command* CommandParser::parseCommand()
|
|||
alpha = 1;
|
||||
if(!paramList->getString("filename", filename))
|
||||
filename = "";
|
||||
if(!paramList->getNumber("fitscreen", fitscreen))
|
||||
fitscreen = 0;
|
||||
if(!paramList->getBoolean("fitscreen", fitscreen))
|
||||
{
|
||||
int f;
|
||||
if(!paramList->getNumber("fitscreen", f))
|
||||
fitscreen = false;
|
||||
else
|
||||
fitscreen = (bool) f;
|
||||
}
|
||||
|
||||
cmd = new CommandScriptImage(duration, xoffset, yoffset, alpha, filename, fitscreen);
|
||||
}
|
||||
|
|
|
@ -1001,8 +1001,9 @@ double RepeatCommand::getDuration() const
|
|||
}
|
||||
|
||||
// ScriptImage command
|
||||
CommandScriptImage::CommandScriptImage(double _duration, float _xoffset,
|
||||
float _yoffset, float _alpha, std::string _filename, int _fitscreen) :
|
||||
CommandScriptImage::CommandScriptImage(float _duration, float _xoffset,
|
||||
float _yoffset, float _alpha,
|
||||
std::string _filename, bool _fitscreen) :
|
||||
duration(_duration),
|
||||
xoffset(_xoffset),
|
||||
yoffset(_yoffset),
|
||||
|
|
|
@ -768,8 +768,8 @@ class RepeatCommand : public Command
|
|||
class CommandScriptImage : public InstantaneousCommand
|
||||
{
|
||||
public:
|
||||
CommandScriptImage(double _duration, float _xoffset, float _yoffset,
|
||||
float _alpha, std::string, int _fitscreen);
|
||||
CommandScriptImage(float _duration, float _xoffset, float _yoffset,
|
||||
float _alpha, std::string, bool _fitscreen);
|
||||
void process(ExecutionEnvironment&);
|
||||
|
||||
private:
|
||||
|
|
|
@ -88,18 +88,6 @@ static void warning(string s)
|
|||
}
|
||||
|
||||
|
||||
struct OverlayImage
|
||||
{
|
||||
Texture* texture;
|
||||
int xSize;
|
||||
int ySize;
|
||||
int left;
|
||||
int bottom;
|
||||
};
|
||||
|
||||
vector<OverlayImage> overlayImages;
|
||||
|
||||
|
||||
// Extremely basic implementation of an ExecutionEnvironment for
|
||||
// running scripts.
|
||||
class CoreExecutionEnvironment : public ExecutionEnvironment
|
||||
|
@ -3288,29 +3276,75 @@ static void showViewFrame(const View* v, int width, int height)
|
|||
}
|
||||
|
||||
|
||||
void CelestiaCore::setScriptImage(double duration, float xoffset,
|
||||
float yoffset, float alpha, const string& filename, int fitscreen)
|
||||
void CelestiaCore::setScriptImage(float duration,
|
||||
float xoffset,
|
||||
float yoffset,
|
||||
float alpha,
|
||||
const string& filename,
|
||||
bool fitscreen)
|
||||
{
|
||||
imageStart = currentTime;
|
||||
imageDuration = duration;
|
||||
imageXoffset = xoffset;
|
||||
imageYoffset = yoffset;
|
||||
imageAlpha = alpha;
|
||||
imageFitscreen = fitscreen;
|
||||
if (scriptImageFilename != (string("images") + "/" + filename).c_str()) // Check if the image is already loaded
|
||||
if (!image || !image->isNewImage(filename))
|
||||
{
|
||||
delete scriptImage;
|
||||
scriptImageFilename = (string("images") + "/" + filename).c_str();
|
||||
scriptImage = LoadTextureFromFile(scriptImageFilename);
|
||||
delete image;
|
||||
image = new CelestiaCore::OverlayImage(filename);
|
||||
}
|
||||
image->setStartTime((float) currentTime);
|
||||
image->setDuration(duration);
|
||||
image->setOffset(xoffset, yoffset);
|
||||
image->setAlpha(alpha);
|
||||
image->fitScreen(fitscreen);
|
||||
}
|
||||
|
||||
|
||||
CelestiaCore::OverlayImage::OverlayImage(string f)
|
||||
{
|
||||
filename = std::move(f);
|
||||
delete texture;
|
||||
texture = LoadTextureFromFile(string("images/") + filename);
|
||||
}
|
||||
|
||||
|
||||
void CelestiaCore::OverlayImage::render(float curr_time, int width, int height)
|
||||
{
|
||||
if (!texture || (curr_time >= start + duration))
|
||||
return;
|
||||
|
||||
float xSize = texture->getWidth();
|
||||
float ySize = texture->getHeight();
|
||||
|
||||
// center overlay image horizontally if offsetX = 0
|
||||
float left = (width * (1 + offsetX) - xSize)/2;
|
||||
// center overlay image vertically if offsetY = 0
|
||||
float bottom = (height * (1 + offsetY) - ySize)/2;
|
||||
|
||||
if (fitscreen)
|
||||
{
|
||||
float coeffx = xSize / width; // overlay pict width/view window width ratio
|
||||
float coeffy = ySize / height; // overlay pict height/view window height ratio
|
||||
xSize = xSize / coeffx; // new overlay picture width size to fit viewport
|
||||
ySize = ySize / coeffy; // new overlay picture height to fit viewport
|
||||
|
||||
left = (width - xSize) / 2; // to be sure overlay pict is centered in viewport
|
||||
bottom = 0; // overlay pict locked at bottom of screen
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
texture->bind();
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, alpha);
|
||||
glTexCoord2f(0.0f, 1.0f); glVertex2f(left, bottom);
|
||||
glTexCoord2f(1.0f, 1.0f); glVertex2f(left + xSize, bottom);
|
||||
glTexCoord2f(1.0f, 0.0f); glVertex2f(left + xSize, bottom + ySize);
|
||||
glTexCoord2f(0.0f, 0.0f); glVertex2f(left, bottom + ySize);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
void CelestiaCore::renderOverlay()
|
||||
{
|
||||
|
||||
#ifdef CELX
|
||||
if (luaHook) luaHook->callLuaHook(this,"renderoverlay");
|
||||
if (luaHook) luaHook->callLuaHook(this, "renderoverlay");
|
||||
#endif
|
||||
if (font == nullptr)
|
||||
return;
|
||||
|
@ -3323,41 +3357,15 @@ void CelestiaCore::renderOverlay()
|
|||
|
||||
overlay->begin();
|
||||
|
||||
if (scriptImage != nullptr && currentTime < imageStart + imageDuration && (runningScript != nullptr || celxScript != nullptr))
|
||||
#ifdef CELX
|
||||
if (runningScript || celxScript)
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
float xSize = (scriptImage->getWidth());
|
||||
float ySize = (scriptImage->getHeight());
|
||||
|
||||
float left = (width*(1 + imageXoffset) - xSize)/2; // center overlay image horizontally if imageXoffset = 0
|
||||
float bottom = (height*(1 + imageYoffset) - ySize)/2; // center overlay image vertically if imageYoffset = 0
|
||||
|
||||
if (imageFitscreen == 1)
|
||||
{
|
||||
float coeffx = xSize/width; // compute overlay pict width/view window width ratio
|
||||
float coeffy = ySize/height; // compute overlay pict height/view window height ratio
|
||||
xSize = int (xSize/coeffx); // compute new overlay picture width size to fit viewport
|
||||
ySize = int (ySize/coeffy); // compute new overlay picture height to fit viewport
|
||||
|
||||
left = (width - xSize)/2; // almost useless, just to be sure overlay pict is perfectly centered in viewport
|
||||
bottom = 0; // overlay pict locked at bottom of screen
|
||||
}
|
||||
|
||||
scriptImage->bind();
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(1.0f, 1.0f, 1.0f, imageAlpha);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex2i(int (left), int (bottom));
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex2i(int (left) + int (xSize), int (bottom));
|
||||
|
||||
glColor4f(1.0f, 1.0f, 1.0f, imageAlpha);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex2i(int (left) + int (xSize), int (bottom) + int (ySize));
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2i(int (left), int (bottom) + int (ySize));
|
||||
glEnd();
|
||||
#else
|
||||
if (runningScript)
|
||||
{
|
||||
#endif
|
||||
if (image)
|
||||
image->render((float) currentTime, width, height);
|
||||
}
|
||||
|
||||
if (views.size() > 1)
|
||||
|
|
|
@ -190,15 +190,45 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
|
||||
enum
|
||||
{
|
||||
ShowNoElement = 0x001,
|
||||
ShowTime = 0x002,
|
||||
ShowNoElement = 0x001,
|
||||
ShowTime = 0x002,
|
||||
ShowVelocity = 0x004,
|
||||
ShowSelection = 0x008,
|
||||
ShowFrame = 0x010,
|
||||
ShowSelection = 0x008,
|
||||
ShowFrame = 0x010,
|
||||
};
|
||||
|
||||
typedef void (*ContextMenuFunc)(float, float, Selection);
|
||||
|
||||
private:
|
||||
class OverlayImage
|
||||
{
|
||||
public:
|
||||
OverlayImage(string);
|
||||
~OverlayImage() { delete texture; }
|
||||
OverlayImage() =default;
|
||||
OverlayImage(OverlayImage&) =delete;
|
||||
OverlayImage(OverlayImage&&) =delete;
|
||||
|
||||
void render(float, int, int);
|
||||
inline bool isNewImage(const string& f) { return filename != f; }
|
||||
|
||||
void setStartTime(float t) { start = t; }
|
||||
void setDuration(float t) { duration = t; }
|
||||
void setOffset(float x, float y) { offsetX = x; offsetY = y; }
|
||||
void setAlpha(float t) { alpha = t; }
|
||||
void fitScreen(bool t) { fitscreen = t; }
|
||||
|
||||
private:
|
||||
float start{ 0.0f };
|
||||
float duration{ 0.0f };
|
||||
float offsetX{ 0.0f };
|
||||
float offsetY{ 0.0f };
|
||||
float alpha{ 0.0f };
|
||||
bool fitscreen{ false };
|
||||
std::string filename;
|
||||
Texture* texture{ nullptr };
|
||||
};
|
||||
|
||||
public:
|
||||
CelestiaCore();
|
||||
~CelestiaCore();
|
||||
|
@ -346,6 +376,8 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
|
||||
void fatalError(const std::string&, bool visual = true);
|
||||
|
||||
void setScriptImage(float, float, float, float, const std::string&, bool);
|
||||
|
||||
protected:
|
||||
bool readStars(const CelestiaConfig&, ProgressNotifier*);
|
||||
void renderOverlay();
|
||||
|
@ -379,13 +411,7 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
double messageDuration{ 0.0 };
|
||||
Color textColor{ Color(1.0f, 1.0f, 1.0f) };
|
||||
|
||||
double imageStart{ 0.0 };
|
||||
double imageDuration{ 0.0 };
|
||||
float imageXoffset{ 0.0f };
|
||||
float imageYoffset{ 0.0f };
|
||||
float imageAlpha{ 0.0f };
|
||||
int imageFitscreen{ 0 };
|
||||
std::string scriptImageFilename;
|
||||
OverlayImage *image{ nullptr };
|
||||
|
||||
std::string typedText;
|
||||
std::vector<std::string> typedTextCompletion;
|
||||
|
@ -454,7 +480,6 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
ContextMenuFunc contextMenuCallback{ nullptr };
|
||||
|
||||
Texture* logoTexture{ nullptr };
|
||||
Texture* scriptImage{ nullptr };
|
||||
|
||||
Alerter* alerter{ nullptr };
|
||||
std::vector<CelestiaWatcher*> watchers;
|
||||
|
@ -483,9 +508,6 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
friend TextureFont* getFont(CelestiaCore*);
|
||||
friend TextureFont* getTitleFont(CelestiaCore*);
|
||||
#endif
|
||||
|
||||
public:
|
||||
void setScriptImage(double, float, float, float, const std::string&, int);
|
||||
};
|
||||
|
||||
#endif // _CELESTIACORE_H_
|
||||
|
|
|
@ -3471,12 +3471,16 @@ static int celestia_overlay(lua_State* l)
|
|||
Celx_CheckArgs(l, 2, 7, "One to Six arguments expected to function celestia:overlay");
|
||||
|
||||
CelestiaCore* appCore = this_celestia(l);
|
||||
double duration = Celx_SafeGetNumber(l, 2, WrongType, "First argument to celestia:overlay must be a number (duration)", 3.0);
|
||||
float duration = Celx_SafeGetNumber(l, 2, WrongType, "First argument to celestia:overlay must be a number (duration)", 3.0);
|
||||
float xoffset = Celx_SafeGetNumber(l, 3, WrongType, "Second argument to celestia:overlay must be a number (xoffset)", 0.0);
|
||||
float yoffset = Celx_SafeGetNumber(l, 4, WrongType, "Third argument to celestia:overlay must be a number (yoffset)", 0.0);
|
||||
float alpha = Celx_SafeGetNumber(l, 5, WrongType, "Fourth argument to celestia:overlay must be a number (alpha)", 1.0);
|
||||
const char* filename = Celx_SafeGetString(l, 6, AllErrors, "Fifth argument to celestia:overlay must be a string (filename)");
|
||||
int fitscreen = Celx_SafeGetNumber(l, 7, WrongType, "Sixth argument to celestia:overlay must be a number (fitscreen)", 0);
|
||||
bool fitscreen;
|
||||
if (lua_isboolean(l, 7))
|
||||
fitscreen = lua_toboolean(l, 7);
|
||||
else
|
||||
fitscreen = (bool) Celx_SafeGetNumber(l, 7, WrongType, "Sixth argument to celestia:overlay must be a number or a boolean(fitscreen)", 0);
|
||||
|
||||
appCore->setScriptImage(duration, xoffset, yoffset, alpha, filename, fitscreen);
|
||||
|
||||
|
|
Loading…
Reference in New Issue