Refactor Overlay::rect() to use instead of direct GL calls

pull/3/head
Gitea 2019-08-02 13:38:19 +03:00 committed by Hleb Valoshka
parent 35b53b22d5
commit cfc225adc7
4 changed files with 189 additions and 83 deletions

View File

@ -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);
}

View File

@ -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_

View File

@ -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 == "")

View File

@ -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 };