98 lines
3.3 KiB
C++
98 lines
3.3 KiB
C++
#include <glbinding/gl/gl.h>
|
|
#include <SDL2/SDL.h>
|
|
|
|
#include <glm/gtx/transform.hpp>
|
|
#include <glm/gtc/type_ptr.hpp>
|
|
|
|
#include "Overlay.hh"
|
|
#include "renderutil.hh"
|
|
#include "VBOManager.hh"
|
|
#include "ProgramProvider.hh"
|
|
#include "Renderer.hh"
|
|
|
|
using namespace gl;
|
|
|
|
namespace render {
|
|
namespace {
|
|
struct VertexAttribs {
|
|
int16_t vertex[2];
|
|
uint16_t texCoords[2];
|
|
} __attribute__((__packed__));
|
|
}
|
|
|
|
Overlay::Overlay(Renderer& renderer, int width, int height, int left, int top, int intWidth, int intHeight)
|
|
: Drawable(renderer), texture_(create2DTexture(intWidth, intHeight, false, 1)),
|
|
vbo_(VBOManager::getInstance().alloc(sizeof(VertexAttribs)*6)),
|
|
width_(width), height_(height), top_(top), left_(left), intWidth_(intWidth), intHeight_(intHeight)
|
|
{
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, static_cast<int>(GL_LINEAR));
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, static_cast<int>(GL_CLAMP_TO_EDGE));
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, static_cast<int>(GL_CLAMP_TO_EDGE));
|
|
program_ = ProgramProvider::getInstance().getProgram("overlay", "overlay");
|
|
|
|
glGenVertexArrays(1, &vertexArray_.get());
|
|
short int t = top_, l = left_, b = height+top_, r = width+left_;
|
|
std::vector<VertexAttribs> vertexAttribs{
|
|
{{l, t}, {0, 0}},
|
|
{{r, b}, {65535u, 65535u}},
|
|
{{r, t}, {65535u, 0}},
|
|
{{l, t}, {0, 0}},
|
|
{{l, b}, {0, 65535u}},
|
|
{{r, b}, {65535u, 65535u}}};
|
|
|
|
glBindBuffer(GL_ARRAY_BUFFER, vbo_.getVBOId());
|
|
glBindVertexArray(vertexArray_);
|
|
|
|
glEnableVertexAttribArray(0);
|
|
glVertexAttribPointer(0, 2, GL_SHORT, GL_FALSE, sizeof(VertexAttribs),
|
|
vbo_.getOfs(offsetof(VertexAttribs, vertex)));
|
|
glEnableVertexAttribArray(1);
|
|
glVertexAttribPointer(1, 2, GL_UNSIGNED_SHORT, GL_TRUE, sizeof(VertexAttribs),
|
|
vbo_.getOfs(offsetof(VertexAttribs, texCoords)));
|
|
|
|
glBufferSubData(GL_ARRAY_BUFFER, vbo_.getBase(),
|
|
sizeof(VertexAttribs)*6,
|
|
vertexAttribs.data());
|
|
|
|
ovlProj_ = glm::ortho(0.0f, static_cast<float>(renderer_.getWidth()),
|
|
static_cast<float>(renderer_.getHeight()), 0.0f);
|
|
}
|
|
|
|
void Overlay::draw()
|
|
{
|
|
glDisable(GL_DEPTH_TEST);
|
|
useProgram(program_);
|
|
glUniformMatrix4fv(0, 1, GL_FALSE, glm::value_ptr(ovlProj_));
|
|
glUniform1i(1, 0);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, texture_);
|
|
glBindVertexArray(vertexArray_);
|
|
|
|
glDrawArrays(GL_TRIANGLES, 0, 6);
|
|
}
|
|
|
|
void Overlay::setContent(SDL_Surface *content)
|
|
{
|
|
if (!content ||
|
|
(content->h != intHeight_) ||
|
|
(content->w != intWidth_))
|
|
throw Exception{"null or mismatched surface"};
|
|
|
|
glBindTexture(GL_TEXTURE_2D, texture_);
|
|
|
|
if (content->format->format != SDL_PIXELFORMAT_RGB24) {
|
|
SDLSurfaceUPtr tmpSurf(SDL_ConvertSurfaceFormat(content, SDL_PIXELFORMAT_RGB24, 0));
|
|
if (!tmpSurf)
|
|
throw SDLException{};
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, tmpSurf->w, tmpSurf->h, GL_RGB, GL_UNSIGNED_BYTE, tmpSurf->pixels);
|
|
} else
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, content->w, content->h, GL_RGB, GL_UNSIGNED_BYTE, content->pixels);
|
|
}
|
|
|
|
void Overlay::setContentRGB8(void *data)
|
|
{
|
|
glBindTexture(GL_TEXTURE_2D, texture_);
|
|
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, intWidth_, intHeight_, GL_RGB, GL_UNSIGNED_BYTE, data);
|
|
}
|
|
}
|