Refactor Overlay::rect() to use instead of direct GL calls
parent
35b53b22d5
commit
cfc225adc7
|
@ -11,14 +11,19 @@
|
|||
#include <cstdarg>
|
||||
#include <celutil/utf8.h>
|
||||
#include <GL/glew.h>
|
||||
#include <Eigen/Core>
|
||||
#include <fmt/printf.h>
|
||||
#include "vecgl.h"
|
||||
#include "overlay.h"
|
||||
#include "render.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace Eigen;
|
||||
|
||||
|
||||
Overlay::Overlay() :
|
||||
ostream(&sbuf)
|
||||
Overlay::Overlay(const Renderer& r) :
|
||||
ostream(&sbuf),
|
||||
renderer(r)
|
||||
{
|
||||
sbuf.setOverlay(this);
|
||||
}
|
||||
|
@ -161,27 +166,99 @@ void Overlay::print(const char* s)
|
|||
}
|
||||
}
|
||||
|
||||
void Overlay::rect(float x, float y, float w, float h, bool fill)
|
||||
static void drawRect(const Renderer& r,
|
||||
const array<float, 8>& vertices,
|
||||
const vector<Vector4f>& colors,
|
||||
Overlay::RectType type,
|
||||
float linewidth)
|
||||
{
|
||||
if (useTexture)
|
||||
uint32_t p = 0;
|
||||
switch (type)
|
||||
{
|
||||
case Overlay::RectType::Textured:
|
||||
p |= ShaderProperties::HasTexture;
|
||||
// [[ fallthrough ]]
|
||||
case Overlay::RectType::Outlined:
|
||||
case Overlay::RectType::Filled:
|
||||
switch (colors.size())
|
||||
{
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
p |= ShaderProperties::UniformColor;
|
||||
break;
|
||||
case 4:
|
||||
p |= ShaderProperties::PerVertexColor;
|
||||
break;
|
||||
default:
|
||||
fmt::fprintf(cerr, "Incorrect number of colors: %i\n", colors.size());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
auto prog = r.getShaderManager().getShader(ShaderProperties(p));
|
||||
if (prog == nullptr)
|
||||
return;
|
||||
|
||||
constexpr array<short, 8> texels = {0, 1, 1, 1, 1, 0, 0, 0};
|
||||
|
||||
auto s = static_cast<GLsizeiptr>(memsize(vertices) + memsize(texels) + 4*4*sizeof(GLfloat));
|
||||
static celgl::VertexObject vo{ GL_ARRAY_BUFFER, s, GL_DYNAMIC_DRAW };
|
||||
vo.bindWritable();
|
||||
|
||||
if (!vo.initialized())
|
||||
{
|
||||
vo.allocate();
|
||||
vo.setBufferData(texels.data(), memsize(vertices), memsize(texels));
|
||||
vo.setVertices(2, GL_FLOAT);
|
||||
vo.setTextureCoords(2, GL_SHORT, false, 0, memsize(vertices));
|
||||
vo.setColors(4, GL_FLOAT, false, 0, memsize(vertices) + memsize(texels));
|
||||
}
|
||||
|
||||
vo.setBufferData(vertices.data(), 0, memsize(vertices));
|
||||
if (colors.size() == 4)
|
||||
vo.setBufferData(colors.data(), memsize(vertices) + memsize(texels), 4*4*sizeof(GLfloat));
|
||||
|
||||
prog->use();
|
||||
if (type == Overlay::RectType::Textured)
|
||||
prog->samplerParam("tex") = 0;
|
||||
|
||||
if (colors.size() == 1)
|
||||
prog->vec4Param("color") = colors[0];
|
||||
|
||||
if (type != Overlay::RectType::Outlined)
|
||||
{
|
||||
vo.draw(GL_TRIANGLE_FAN, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (linewidth != 1.0f)
|
||||
glLineWidth(linewidth);
|
||||
vo.draw(GL_LINE_LOOP, 4);
|
||||
if (linewidth != 1.0f)
|
||||
glLineWidth(1.0f);
|
||||
}
|
||||
|
||||
glUseProgram(0);
|
||||
vo.unbind();
|
||||
}
|
||||
|
||||
void Overlay::rect(const Overlay::Rectangle& r)
|
||||
{
|
||||
if (useTexture && r.type != Overlay::RectType::Textured)
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
useTexture = false;
|
||||
}
|
||||
|
||||
if (fill)
|
||||
{
|
||||
glRectf(x, y, x + w, y + h);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(x, y, 0);
|
||||
glVertex3f(x + w, y, 0);
|
||||
glVertex3f(x + w, y + h, 0);
|
||||
glVertex3f(x, y + h, 0);
|
||||
glEnd();
|
||||
}
|
||||
vector<Vector4f> cv;
|
||||
for (const Color& c : r.colors)
|
||||
cv.push_back(c.toVector4());
|
||||
|
||||
array<float, 8> coord = { r.x, r.y, r.x+r.w, r.y, r.x+r.w, r.y+r.h, r.x, r.y+r.h };
|
||||
drawRect(renderer, coord, cv, r.type, r.lw);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,10 +12,13 @@
|
|||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <celtxf/texturefont.h>
|
||||
#include <celutil/color.h>
|
||||
|
||||
|
||||
class Overlay;
|
||||
class Renderer;
|
||||
|
||||
// Custom streambuf class to support C++ operator style output. The
|
||||
// output is completely unbuffered so that it can coexist with printf
|
||||
|
@ -47,7 +50,8 @@ class OverlayStreamBuf : public std::streambuf
|
|||
class Overlay : public std::ostream
|
||||
{
|
||||
public:
|
||||
Overlay();
|
||||
Overlay(const Renderer&);
|
||||
Overlay() = delete;
|
||||
~Overlay() = default;
|
||||
|
||||
void begin();
|
||||
|
@ -56,7 +60,32 @@ class Overlay : public std::ostream
|
|||
void setWindowSize(int, int);
|
||||
void setFont(TextureFont*);
|
||||
|
||||
void rect(float x, float y, float w, float h, bool fill = true);
|
||||
enum class RectType
|
||||
{
|
||||
Outlined = 0x0001,
|
||||
Filled = 0x0002,
|
||||
Textured = 0x0004
|
||||
};
|
||||
|
||||
struct Rectangle
|
||||
{
|
||||
Rectangle() = default;
|
||||
Rectangle(float _x, float _y, float _w, float _h, const Color& _c, RectType _t, float _lw = 1.0f) :
|
||||
x(_x), y(_y), w(_w), h(_h), type(_t), lw(_lw)
|
||||
{
|
||||
colors.push_back(_c);
|
||||
};
|
||||
Rectangle(float _x, float _y, float _w, float _h, const std::vector<Color>& _c, RectType _t, float _lw = 1.0f) :
|
||||
x(_x), y(_y), w(_w), h(_h), colors(_c), type(_t), lw(_lw)
|
||||
{
|
||||
};
|
||||
float x, y, w, h;
|
||||
float lw { 1.0f };
|
||||
RectType type { RectType::Filled };
|
||||
std::vector<Color> colors;
|
||||
};
|
||||
|
||||
void rect(const Rectangle&);
|
||||
|
||||
void beginText();
|
||||
void endText();
|
||||
|
@ -75,7 +104,11 @@ class Overlay : public std::ostream
|
|||
float xoffset{ 0.0f };
|
||||
float yoffset{ 0.0f };
|
||||
|
||||
float lineWidth { 1.0f };
|
||||
|
||||
OverlayStreamBuf sbuf;
|
||||
|
||||
const Renderer& renderer;
|
||||
};
|
||||
|
||||
#endif // _OVERLAY_H_
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
#include <cassert>
|
||||
#include <ctime>
|
||||
#include <fmt/printf.h>
|
||||
#include <celutil/color.h>
|
||||
#include <celengine/vecgl.h>
|
||||
|
||||
#ifdef CELX
|
||||
#include <celephem/scriptobject.h>
|
||||
|
@ -1344,7 +1346,7 @@ void CelestiaCore::charEntered(const char *c_p, int modifiers)
|
|||
{
|
||||
MarkerRepresentation markerRep(MarkerRepresentation::Diamond);
|
||||
markerRep.setSize(10.0f);
|
||||
markerRep.setColor(Color(0.0f, 1.0f, 0.0f, 0.9f));
|
||||
markerRep.setColor({0.0f, 1.0f, 0.0f, 0.9f});
|
||||
|
||||
sim->getUniverse()->markObject(sel, markerRep, 1);
|
||||
}
|
||||
|
@ -3249,17 +3251,6 @@ static void displaySelectionName(Overlay& overlay,
|
|||
#endif
|
||||
|
||||
|
||||
static void showViewFrame(const View* v, int width, int height)
|
||||
{
|
||||
glBegin(GL_LINE_LOOP);
|
||||
glVertex3f(v->x * width, v->y * height, 0.0f);
|
||||
glVertex3f(v->x * width, (v->y + v->height) * height - 1, 0.0f);
|
||||
glVertex3f((v->x + v->width) * width - 1, (v->y + v->height) * height - 1, 0.0f);
|
||||
glVertex3f((v->x + v->width) * width - 1, v->y * height, 0.0f);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
||||
void CelestiaCore::setScriptImage(float duration,
|
||||
float xoffset,
|
||||
float yoffset,
|
||||
|
@ -3270,7 +3261,7 @@ void CelestiaCore::setScriptImage(float duration,
|
|||
if (image == nullptr || image->isNewImage(filename))
|
||||
{
|
||||
delete image;
|
||||
image = new CelestiaCore::OverlayImage(filename);
|
||||
image = new CelestiaCore::OverlayImage(filename, overlay);
|
||||
}
|
||||
image->setStartTime((float) currentTime);
|
||||
image->setDuration(duration);
|
||||
|
@ -3280,10 +3271,10 @@ void CelestiaCore::setScriptImage(float duration,
|
|||
}
|
||||
|
||||
|
||||
CelestiaCore::OverlayImage::OverlayImage(string f)
|
||||
CelestiaCore::OverlayImage::OverlayImage(string f, Overlay* o) :
|
||||
filename(std::move(f)),
|
||||
overlay(o)
|
||||
{
|
||||
filename = std::move(f);
|
||||
delete texture;
|
||||
texture = LoadTextureFromFile(string("images/") + filename);
|
||||
}
|
||||
|
||||
|
@ -3315,16 +3306,10 @@ void CelestiaCore::OverlayImage::render(float curr_time, int width, int height)
|
|||
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();
|
||||
Overlay::Rectangle r(left, bottom, xSize, ySize, {Color::White, alpha}, Overlay::RectType::Textured);
|
||||
overlay->rect(r);
|
||||
}
|
||||
|
||||
|
||||
void CelestiaCore::renderOverlay()
|
||||
{
|
||||
#ifdef CELX
|
||||
|
@ -3354,37 +3339,45 @@ void CelestiaCore::renderOverlay()
|
|||
|
||||
if (views.size() > 1)
|
||||
{
|
||||
Overlay::Rectangle r(0, 0, 0, 0, frameColor, Overlay::RectType::Outlined, 1);
|
||||
|
||||
// Render a thin border arround all views
|
||||
if (showViewFrames || resizeSplit)
|
||||
{
|
||||
glLineWidth(1.0f);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glColor4f(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
for(const auto v : views)
|
||||
{
|
||||
if (v->type == View::ViewWindow)
|
||||
showViewFrame(v, width, height);
|
||||
{
|
||||
r.x = v->x * width;
|
||||
r.y = v->y * height;
|
||||
r.w = v->width * width - 1;
|
||||
r.h = v->height * height - 1;
|
||||
overlay->rect(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
glLineWidth(1.0f);
|
||||
|
||||
// Render a very simple border around the active view
|
||||
View* av = (*activeView);
|
||||
View* av = *activeView;
|
||||
|
||||
r.x = av->x * width;
|
||||
r.y = av->y * height;
|
||||
r.w = av->width * width - 1;
|
||||
r.h = av->height * height - 1;
|
||||
|
||||
if (showActiveViewFrame)
|
||||
{
|
||||
glLineWidth(2.0f);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
|
||||
showViewFrame(av, width, height);
|
||||
glLineWidth(1.0f);
|
||||
r.colors[0] = activeFrameColor;
|
||||
r.lw = 2;
|
||||
overlay->rect(r);
|
||||
}
|
||||
|
||||
if (currentTime < flashFrameStart + 0.5)
|
||||
{
|
||||
glLineWidth(8.0f);
|
||||
glColor4f(0.5f, 0.5f, 1.0f,
|
||||
(float) (1.0 - (currentTime - flashFrameStart) / 0.5));
|
||||
showViewFrame(av, width, height);
|
||||
glLineWidth(1.0f);
|
||||
float alpha = (float) (1.0 - (currentTime - flashFrameStart) / 0.5);
|
||||
r.colors[0] = {activeFrameColor, alpha};
|
||||
r.lw = 8;
|
||||
overlay->rect(r);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3764,8 +3757,8 @@ void CelestiaCore::renderOverlay()
|
|||
{
|
||||
overlay->setFont(titleFont);
|
||||
glPushMatrix();
|
||||
glColor4f(0.7f, 0.7f, 1.0f, 0.2f);
|
||||
overlay->rect(0.0f, 0.0f, (float) width, 100.0f);
|
||||
Overlay::Rectangle r(0, 0, width, 100, consoleColor, Overlay::RectType::Filled);
|
||||
overlay->rect(r);
|
||||
glTranslatef(0.0f, fontHeight * 3.0f + 35.0f, 0.0f);
|
||||
glColor4f(0.6f, 0.6f, 1.0f, 1.0f);
|
||||
overlay->beginText();
|
||||
|
@ -3844,11 +3837,15 @@ void CelestiaCore::renderOverlay()
|
|||
int movieWidth = movieCapture->getWidth();
|
||||
int movieHeight = movieCapture->getHeight();
|
||||
glPushMatrix();
|
||||
glColor4f(1, 0, 0, 1);
|
||||
overlay->rect((float) ((width - movieWidth) / 2 - 1),
|
||||
(float) ((height - movieHeight) / 2 - 1),
|
||||
(float) (movieWidth + 1),
|
||||
(float) (movieHeight + 1), false);
|
||||
Color color(1, 0, 0, 1);
|
||||
glColor(color);
|
||||
Overlay::Rectangle r((width - movieWidth) / 2 - 1,
|
||||
(height - movieHeight) / 2 - 1,
|
||||
movieWidth + 1,
|
||||
movieHeight + 1,
|
||||
color,
|
||||
Overlay::RectType::Outlined);
|
||||
overlay->rect(r);
|
||||
glTranslatef((float) ((width - movieWidth) / 2),
|
||||
(float) ((height + movieHeight) / 2 + 2), 0.0f);
|
||||
overlay->beginText();
|
||||
|
@ -3918,20 +3915,14 @@ void CelestiaCore::renderOverlay()
|
|||
}
|
||||
|
||||
logoTexture->bind();
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(0.8f, 0.8f, 1.0f, botAlpha);
|
||||
//glColor4f(1.0f, 1.0f, 1.0f, botAlpha);
|
||||
glTexCoord2f(0.0f, 1.0f);
|
||||
glVertex2i(left, bottom);
|
||||
glTexCoord2f(1.0f, 1.0f);
|
||||
glVertex2i(left + xSize, bottom);
|
||||
glColor4f(0.6f, 0.6f, 1.0f, topAlpha);
|
||||
//glColor4f(1.0f, 1.0f, 1.0f, topAlpha);
|
||||
glTexCoord2f(1.0f, 0.0f);
|
||||
glVertex2i(left + xSize, bottom + ySize);
|
||||
glTexCoord2f(0.0f, 0.0f);
|
||||
glVertex2i(left, bottom + ySize);
|
||||
glEnd();
|
||||
vector<Color> c = {
|
||||
{0.8f, 0.8f, 1.0f, botAlpha},
|
||||
{0.8f, 0.8f, 1.0f, botAlpha},
|
||||
{0.6f, 0.6f, 1.0f, topAlpha},
|
||||
{0.6f, 0.6f, 1.0f, topAlpha}
|
||||
};
|
||||
Overlay::Rectangle r(left, bottom, xSize, ySize, c, Overlay::RectType::Textured);
|
||||
overlay->rect(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4318,7 +4309,7 @@ bool CelestiaCore::initRenderer()
|
|||
titleFont = font;
|
||||
|
||||
// Set up the overlay
|
||||
overlay = new Overlay();
|
||||
overlay = new Overlay(*renderer);
|
||||
overlay->setWindowSize(width, height);
|
||||
|
||||
if (config->labelFont == "")
|
||||
|
|
|
@ -203,7 +203,7 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
class OverlayImage
|
||||
{
|
||||
public:
|
||||
OverlayImage(string);
|
||||
OverlayImage(string, Overlay*);
|
||||
~OverlayImage() { delete texture; }
|
||||
OverlayImage() =default;
|
||||
OverlayImage(OverlayImage&) =delete;
|
||||
|
@ -227,6 +227,7 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
bool fitscreen{ false };
|
||||
std::string filename;
|
||||
Texture* texture{ nullptr };
|
||||
Overlay* overlay;
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -412,7 +413,11 @@ class CelestiaCore // : public Watchable<CelestiaCore>
|
|||
int messageVOffset{ 0 };
|
||||
double messageStart{ 0.0 };
|
||||
double messageDuration{ 0.0 };
|
||||
Color textColor{ Color(1.0f, 1.0f, 1.0f) };
|
||||
Color textColor{ 1.0f, 1.0f, 1.0f };
|
||||
|
||||
const Color frameColor{ 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
const Color activeFrameColor{ 0.5f, 0.5f, 1.0f, 1.0f };
|
||||
const Color consoleColor{ 0.7f, 0.7f, 1.0f, 0.2f };
|
||||
|
||||
OverlayImage *image{ nullptr };
|
||||
|
||||
|
|
Loading…
Reference in New Issue