#include #include #include #include #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(GL_LINEAR)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, static_cast(GL_CLAMP_TO_EDGE)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, static_cast(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{ {{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(renderer_.getWidth()), static_cast(renderer_.getHeight()), 0.0f); } void Overlay::draw() { glDisable(GL_DEPTH_TEST); glUseProgram(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); } }