1 /* 2 Copyright (C) 2010-2014 Kristian Duske 3 4 This file is part of TrenchBroom. 5 6 TrenchBroom is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 TrenchBroom is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with TrenchBroom. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #include "RenderView.h" 21 #include "Exceptions.h" 22 #include "PreferenceManager.h" 23 #include "Preferences.h" 24 #include "Renderer/Transformation.h" 25 #include "Renderer/VertexArray.h" 26 #include "Renderer/VertexSpec.h" 27 #include "View/GLContextManager.h" 28 #include "View/wxUtils.h" 29 30 #include <wx/dcclient.h> 31 #include <wx/settings.h> 32 33 #include <iostream> 34 35 namespace TrenchBroom { 36 namespace View { RenderView(wxWindow * parent,GLContextManager & contextManager,const GLAttribs & attribs)37 RenderView::RenderView(wxWindow* parent, GLContextManager& contextManager, const GLAttribs& attribs) : 38 wxGLCanvas(parent, wxID_ANY, &attribs.front(), wxDefaultPosition, wxDefaultSize, wxBORDER_NONE), 39 m_glContext(contextManager.createContext(this)), 40 m_attribs(attribs), 41 m_initialized(false) { 42 const wxColour color = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT); 43 m_focusColor = fromWxColor(color); 44 45 bindEvents(); 46 } 47 OnPaint(wxPaintEvent & event)48 void RenderView::OnPaint(wxPaintEvent& event) { 49 if (IsBeingDeleted()) return; 50 51 if (m_glContext->SetCurrent(this)) { 52 if (!m_initialized) 53 initializeGL(); 54 55 wxPaintDC paintDC(this); 56 render(); 57 SwapBuffers(); 58 } 59 } 60 OnSize(wxSizeEvent & event)61 void RenderView::OnSize(wxSizeEvent& event) { 62 if (IsBeingDeleted()) return; 63 64 updateViewport(); 65 event.Skip(); 66 } 67 OnSetFocus(wxFocusEvent & event)68 void RenderView::OnSetFocus(wxFocusEvent& event) { 69 if (IsBeingDeleted()) return; 70 71 Refresh(); 72 event.Skip(); 73 } 74 OnKillFocus(wxFocusEvent & event)75 void RenderView::OnKillFocus(wxFocusEvent& event) { 76 if (IsBeingDeleted()) return; 77 78 Refresh(); 79 event.Skip(); 80 } 81 vertexVbo()82 Renderer::Vbo& RenderView::vertexVbo() { 83 return m_glContext->vertexVbo(); 84 } 85 indexVbo()86 Renderer::Vbo& RenderView::indexVbo() { 87 return m_glContext->indexVbo(); 88 } 89 fontManager()90 Renderer::FontManager& RenderView::fontManager() { 91 return m_glContext->fontManager(); 92 } 93 shaderManager()94 Renderer::ShaderManager& RenderView::shaderManager() { 95 return m_glContext->shaderManager(); 96 } 97 depthBits() const98 int RenderView::depthBits() const { 99 return m_attribs[3]; 100 } 101 multisample() const102 bool RenderView::multisample() const { 103 return m_attribs[4] != 0; 104 } 105 bindEvents()106 void RenderView::bindEvents() { 107 Bind(wxEVT_PAINT, &RenderView::OnPaint, this); 108 Bind(wxEVT_SIZE, &RenderView::OnSize, this); 109 Bind(wxEVT_SET_FOCUS, &RenderView::OnSetFocus, this); 110 Bind(wxEVT_KILL_FOCUS, &RenderView::OnKillFocus, this); 111 } 112 initializeGL()113 void RenderView::initializeGL() { 114 const bool firstInitialization = m_glContext->initialize(); 115 doInitializeGL(firstInitialization); 116 m_initialized = true; 117 } 118 updateViewport()119 void RenderView::updateViewport() { 120 const wxSize clientSize = GetClientSize(); 121 doUpdateViewport(0, 0, clientSize.x, clientSize.y); 122 } 123 render()124 void RenderView::render() { 125 clearBackground(); 126 doRender(); 127 renderFocusIndicator(); 128 } 129 clearBackground()130 void RenderView::clearBackground() { 131 PreferenceManager& prefs = PreferenceManager::instance(); 132 const Color& backgroundColor = prefs.get(Preferences::BackgroundColor); 133 134 glAssert(glClearColor(backgroundColor.r(), backgroundColor.g(), backgroundColor.b(), backgroundColor.a())); 135 glAssert(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); 136 } 137 renderFocusIndicator()138 void RenderView::renderFocusIndicator() { 139 if (!doShouldRenderFocusIndicator() || !HasFocus()) 140 return; 141 142 const Color& outer = m_focusColor; 143 const Color& inner = m_focusColor; 144 145 const wxSize clientSize = GetClientSize(); 146 const float w = static_cast<float>(clientSize.x); 147 const float h = static_cast<float>(clientSize.y); 148 const float t = 1.0f; 149 150 typedef Renderer::VertexSpecs::P3C4::Vertex Vertex; 151 Vertex::List vertices(16); 152 153 // top 154 vertices[ 0] = Vertex(Vec3f(0.0f, 0.0f, 0.0f), outer); 155 vertices[ 1] = Vertex(Vec3f(w, 0.0f, 0.0f), outer); 156 vertices[ 2] = Vertex(Vec3f(w-t, t, 0.0f), inner); 157 vertices[ 3] = Vertex(Vec3f(t, t, 0.0f), inner); 158 159 // right 160 vertices[ 4] = Vertex(Vec3f(w, 0.0f, 0.0f), outer); 161 vertices[ 5] = Vertex(Vec3f(w, h, 0.0f), outer); 162 vertices[ 6] = Vertex(Vec3f(w-t, h-t, 0.0f), inner); 163 vertices[ 7] = Vertex(Vec3f(w-t, t, 0.0f), inner); 164 165 // bottom 166 vertices[ 8] = Vertex(Vec3f(w, h, 0.0f), outer); 167 vertices[ 9] = Vertex(Vec3f(0.0f, h, 0.0f), outer); 168 vertices[10] = Vertex(Vec3f(t, h-t, 0.0f), inner); 169 vertices[11] = Vertex(Vec3f(w-t, h-t, 0.0f), inner); 170 171 // left 172 vertices[12] = Vertex(Vec3f(0.0f, h, 0.0f), outer); 173 vertices[13] = Vertex(Vec3f(0.0f, 0.0f, 0.0f), outer); 174 vertices[14] = Vertex(Vec3f(t, t, 0.0f), inner); 175 vertices[15] = Vertex(Vec3f(t, h-t, 0.0f), inner); 176 177 glAssert(glViewport(0, 0, clientSize.x, clientSize.y)); 178 179 const Mat4x4f projection = orthoMatrix(-1.0f, 1.0f, 0.0f, 0.0f, w, h); 180 Renderer::Transformation transformation(projection, Mat4x4f::Identity); 181 182 glAssert(glDisable(GL_DEPTH_TEST)); 183 Renderer::VertexArray array = Renderer::VertexArray::swap(vertices); 184 185 Renderer::ActivateVbo activate(vertexVbo()); 186 array.prepare(vertexVbo()); 187 array.render(GL_QUADS); 188 glAssert(glEnable(GL_DEPTH_TEST)); 189 } 190 doInitializeGL(const bool firstInitialization)191 void RenderView::doInitializeGL(const bool firstInitialization) {} 192 doUpdateViewport(const int x,const int y,const int width,const int height)193 void RenderView::doUpdateViewport(const int x, const int y, const int width, const int height) {} 194 } 195 } 196