From 0d4fe99398b649a5471417f8497a828b5f128da1 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Sat, 20 Jan 2018 16:20:37 +0200 Subject: [PATCH] nasty bug in Texture::create --- src/app.cc | 4 +-- src/rtarg.cc | 51 ++++++++++++++++++++++++---- src/rtarg.h | 4 ++- src/texture.cc | 2 +- src/ui_exhibit.cc | 98 +++++++++++++++++++++++++++++++++++++++++++---------- 5 files changed, 130 insertions(+), 29 deletions(-) diff --git a/src/app.cc b/src/app.cc index 7fc5c13..b1587f5 100644 --- a/src/app.cc +++ b/src/app.cc @@ -147,8 +147,6 @@ bool app_init(int argc, char **argv) float ambient[] = {0.0, 0.0, 0.0, 0.0}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient); - glClearColor(1, 1, 1, 1); - init_audio(); if(!init_vrhands()) { @@ -386,6 +384,8 @@ void app_display() ImGui::ShowTestWindow(); } + glClearColor(1, 1, 1, 1); + if(opt.vr) { // VR mode goatvr_draw_start(); diff --git a/src/rtarg.cc b/src/rtarg.cc index f90c1d3..12a4ddb 100644 --- a/src/rtarg.cc +++ b/src/rtarg.cc @@ -1,3 +1,4 @@ +#include #include "rtarg.h" struct RTStackItem { @@ -51,9 +52,11 @@ bool push_render_target(RenderTarget *rt) vp[2] = prev->get_width(); vp[3] = prev->get_height(); } else { - memcpy(vp, rstack[rtop].saved_vp, 4 * sizeof(int)); + glGetIntegerv(GL_VIEWPORT, vp); } rstack[++rtop].rt = rt; + + rt->bind(); return true; } @@ -79,6 +82,7 @@ RenderTarget::RenderTarget() { fbo = 0; rbdepth = 0; + rbdepth_fmt = 0; width = height = tex_width = tex_height = 0; auto_vport = true; rtcount = 0; @@ -87,6 +91,7 @@ RenderTarget::RenderTarget() tex[i] = 0; own_texture[i] = true; } + depth = 0; } RenderTarget::~RenderTarget() @@ -118,6 +123,7 @@ bool RenderTarget::create_mrt(int xsz, int ysz, int num, unsigned int fmt, unsig tex[i]->create(tex_width, tex_height, TEX_2D, fmt); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, tex[i]->get_id(), 0); + glBindTexture(GL_TEXTURE_2D, 0); own_texture[i] = true; } } else { @@ -131,30 +137,31 @@ bool RenderTarget::create_mrt(int xsz, int ysz, int num, unsigned int fmt, unsig } if(flags & (RT_DEPTH | RT_STENCIL)) { - unsigned int fmt, attachment; + unsigned int attachment; glGenRenderbuffers(1, &rbdepth); glBindRenderbuffer(GL_RENDERBUFFER, rbdepth); switch(flags & (RT_DEPTH | RT_STENCIL)) { case RT_DEPTH: - fmt = GL_DEPTH_COMPONENT24; + rbdepth_fmt = GL_DEPTH_COMPONENT24; attachment = GL_DEPTH_ATTACHMENT; break; case RT_STENCIL: - fmt = GL_STENCIL_INDEX8; + rbdepth_fmt = GL_STENCIL_INDEX8; attachment = GL_STENCIL_ATTACHMENT; break; case RT_DEPTH | RT_STENCIL: - fmt = GL_DEPTH24_STENCIL8; + rbdepth_fmt = GL_DEPTH24_STENCIL8; attachment = GL_DEPTH_STENCIL_ATTACHMENT; break; } - glRenderbufferStorage(GL_RENDERBUFFER, fmt, width, height); + glRenderbufferStorage(GL_RENDERBUFFER, rbdepth_fmt, width, height); glFramebufferRenderbuffer(GL_FRAMEBUFFER, attachment, GL_RENDERBUFFER, rbdepth); + glBindRenderbuffer(GL_RENDERBUFFER, 0); } else if(depth) { attach_depth_texture(depth); @@ -182,6 +189,36 @@ void RenderTarget::destroy() } } +bool RenderTarget::resize(int xsz, int ysz) +{ + int new_tx = next_pow2(xsz); + int new_ty = next_pow2(ysz); + + if(new_tx != tex_width || new_ty != tex_height) { + tex_width = new_tx; + tex_height = new_ty; + + for(int i=0; i<4; i++) { + if(tex[i]) { + tex[i]->create(new_tx, new_ty, TEX_2D, tex[i]->get_format()); + } + } + + if(depth) { + depth->create(new_tx, new_ty, TEX_2D, depth->get_format()); + } + } + + if(rbdepth) { + glBindRenderbuffer(GL_RENDERBUFFER, rbdepth); + glRenderbufferStorage(GL_RENDERBUFFER, rbdepth_fmt, xsz, ysz); + } + + width = xsz; + height = ysz; + return true; +} + int RenderTarget::get_width() const { return width; @@ -282,7 +319,7 @@ static void attach_depth_texture(Texture *tex) default: error_log("failed to attach depth/stencil texture: unexpected texture format: %x\n", fmt); - break; + return; } glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, tex->get_id(), 0); diff --git a/src/rtarg.h b/src/rtarg.h index f77682d..2cead11 100644 --- a/src/rtarg.h +++ b/src/rtarg.h @@ -22,7 +22,7 @@ private: int rtcount; // either the depth texture or a dummy depth render target is used Texture *depth; - unsigned int rbdepth; + unsigned int rbdepth, rbdepth_fmt; Mat4 texmat; // texture matrix to map tex coords from [0,1] to the useful area bool own_texture[4]; @@ -38,6 +38,8 @@ public: unsigned int flags = RT_COLOR | RT_DEPTH); void destroy(); + bool resize(int xsz, int ysz); + int get_width() const; int get_height() const; diff --git a/src/texture.cc b/src/texture.cc index ed34798..3af8116 100644 --- a/src/texture.cc +++ b/src/texture.cc @@ -185,7 +185,7 @@ void Texture::create(int xsz, int ysz, TextureType textype, unsigned int ifmt) glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - switch(type) { + switch(textype) { case TEX_2D: glTexImage2D(GL_TEXTURE_2D, 0, glifmt_from_ifmt(ifmt), xsz, ysz, 0, fmt, type, 0); break; diff --git a/src/ui_exhibit.cc b/src/ui_exhibit.cc index eda39c6..dd09678 100644 --- a/src/ui_exhibit.cc +++ b/src/ui_exhibit.cc @@ -4,6 +4,7 @@ #include "app.h" #include "snode.h" #include "shader.h" +#include "rtarg.h" struct Rect { float x, y, w, h; @@ -15,11 +16,15 @@ static void draw_tabs(const Rect &rect); static void draw_text(const Rect &rect); static void layout_text(const char *text); +static float aspect; +static int ui_width, ui_height; + +static RenderTarget *rtarg; static const SceneNode *parent; static Vec3 pos; static Vec2 size; -static float text_padding; -static float text_scale = 0.05f; +static int text_padding; +static float text_scale = 1.0f;//0.05f; static Exhibit *ex; static int vis_tab; static float scroll; @@ -38,13 +43,24 @@ bool exui_init() { size.x = 15; size.y = 18; - text_padding = size.x * 0.01; + text_padding = ui_width / 100; + + aspect = size.x / size.y; + ui_height = 512; + ui_width = ui_height * aspect; + + rtarg = new RenderTarget; + if(!rtarg->create(ui_width, ui_height, GL_RGB)) { + error_log("failed to create exui render target\n"); + return false; + } return true; } void exui_shutdown() { + delete rtarg; } void exui_setnode(const SceneNode *node) @@ -92,33 +108,28 @@ void exui_update(float dt) } } -void exui_draw() +static void draw_2d_ui() { - if(!exsel_active) return; - if(!ui_font) return; - dtx_use_font(ui_font, ui_font_size); float rowspc = dtx_line_height() * text_scale; - Rect rect = {-size.x / 2.0f, -size.y / 2.0f, size.x, size.y}; + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, ui_width, 0, ui_height, -1, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); - if(parent) { - glMultMatrixf(parent->get_matrix()[0]); - } - glTranslatef(pos.x, pos.y, pos.z); - glScalef(1, -1, 1); + glLoadIdentity(); bind_shader(0); glPushAttrib(GL_ENABLE_BIT); glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glDepthMask(0); + glDisable(GL_DEPTH_TEST); + Rect rect = {0, 0, (float)ui_width, (float)ui_height}; draw_frame(rect); Rect tbar_rect = {rect.x, rect.y, rect.w, rowspc}; draw_titlebar(tbar_rect); @@ -127,9 +138,60 @@ void exui_draw() Rect text_rect = {rect.x, tabs_rect.y + rowspc, rect.w, rect.h - tabs_rect.y - rowspc}; draw_text(text_rect); + glPopAttrib(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +} + +void exui_draw() +{ + if(!exsel_active) return; + if(!ui_font) return; + + // render the 2D UI in a texture + push_render_target(rtarg); + glClearColor(0, 1, 0, 0); + glClear(GL_COLOR_BUFFER_BIT); + draw_2d_ui(); + pop_render_target(); + + // place UI image into the scene + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + if(parent) { + glMultMatrixf(parent->get_matrix()[0]); + } + glTranslatef(pos.x, pos.y, pos.z); + + glPushAttrib(GL_ENABLE_BIT); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glEnable(GL_TEXTURE_2D); + glDepthMask(0); + + bind_shader(0); + bind_texture(rtarg->texture()); + + glMatrixMode(GL_TEXTURE); + glLoadMatrixf(rtarg->texture_matrix()[0]); + + glBegin(GL_QUADS); + glColor3f(1, 1, 1); + glTexCoord2f(0, 0); glVertex2f(-size.x / 2, -size.y / 2); + glTexCoord2f(1, 0); glVertex2f(size.x / 2, -size.y / 2); + glTexCoord2f(1, 1); glVertex2f(size.x / 2, size.y / 2); + glTexCoord2f(0, 1); glVertex2f(-size.x / 2, size.y / 2); + glEnd(); + + glLoadIdentity(); + glDepthMask(1); glPopAttrib(); + glMatrixMode(GL_MODELVIEW); glPopMatrix(); } @@ -212,10 +274,10 @@ static void layout_text(const char *text) last_break = text; } - if(pos >= size.x - text_padding) { + if(pos >= ui_width - text_padding) { if(text == text_lines.back()) { // not even a single character fits on a line... abort - warning_log("text layout failed. glyph %d doesn't fit in line (%g)\n", code, size.x - 2.0 * text_padding); + warning_log("text layout failed. glyph %d doesn't fit in line (%d)\n", code, ui_width - 2 * text_padding); text_lines.clear(); return; } -- 1.7.10.4