NCBI C++ ToolKit
glrendernode.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: glrendernode.cpp 43891 2019-09-16 13:50:00Z evgeniev $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Bob Falk
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
34 #include <gui/opengl/glutils.hpp>
35 #include <gui/opengl/irender.hpp>
36 
38 
40 : m_Visible(true)
41 , m_PixelOffset(0.0f, 0.0f)
42 , m_RotAngleZ(0.0f)
43 {
44  m_State.Reset(new CGlState());
46 }
47 
49 {
50  IRender& gl = GetGl();
51 
52  m_State->MakeCurrent(gl.GetApi());
53 
54  x_Render();
55 }
56 
58 {
60 }
61 
63 {
64  return m_State.GetNCObject();
65 }
66 
68 {
69  return m_State.GetNCObject();
70 }
71 
73 {
74  vector<ERenderTarget>::iterator iter;
75 
76  iter = std::find(m_SkippedTargets.begin(), m_SkippedTargets.end(), target);
77 
78  // Not currently skipped. Add if skip==true
79  if (iter == m_SkippedTargets.end()) {
80  if (skip) {
81  m_SkippedTargets.push_back(target);
82  }
83  }
84  // Currently skipped. Remove if skip==false
85  else {
86  if (!skip) {
87  m_SkippedTargets.erase(iter);
88  }
89  }
90 
91  return;
92 }
93 
95 {
96  vector<ERenderTarget>::const_iterator iter;
97 
98  iter = std::find(m_SkippedTargets.begin(), m_SkippedTargets.end(), target);
99 
100  // Not currently skipped. Add if skip==true
101  if (iter != m_SkippedTargets.end())
102  return true;
103 
104  return false;
105 }
106 
108 {
109  ClearPositions();
110 
111  CMatrix4<float> mat;
112  mat.Identity();
113  m_Positions.push_back(mat);
114  m_RotAngleZ = 0.0f;
115 }
116 
118 {
119  if (m_Positions.size() == 1) {
120  m_Positions[0] = mat;
121  }
122  else {
123  ClearPositions();
124  m_Positions.push_back(mat);
125  }
126 }
127 
129 {
130  CMatrix4<float> mat(m_Positions[idx]);
131 
132  // Both pixel offsets and rotation are dependent on the current (non-uniform)
133  // scaling in x and y so if we want transformations that do not need to be
134  // completely updated every time we scale the view (zoom, resize window) we need
135  // to apply the scaling factors here. Get optional (z) rotation matrix first:
136  CMatrix4<float> rm;
137  rm.Identity();
138 
139  float xs = 1.0f;
140  float ys = 1.0f;
141 
142  if (m_RotAngleZ != 0.0) {
143  // Recompute the angle
144  float cos_a = cosf(m_RotAngleZ)*1.0f / (float)m_State->GetScaleFactor().X();
145  float sin_a = sinf(m_RotAngleZ)*1.0f / (float)m_State->GetScaleFactor().Y();
146  float a = atan2f(sin_a, cos_a);
147 
148  // Now create a standard 2D (rotate around z axis) rotation matrix:
149  rm(0, 0) = cosf(a);
150  rm(0, 1) = -sinf(a);
151  rm(1, 0) = sinf(a);
152  rm(1, 1) = cosf(a);
153 
154  xs = mat(0, 0);
155  ys = mat(1, 1);
156  mat(0, 0) = 1.0;
157  mat(1, 1) = 1.0;
158  }
159 
160  /// Apply optional pixel offset
161  if (m_PixelOffset.Length2() > 0.0f) {
162  CMatrix4<float> tm;
163 
164  tm.Identity();
165  CVect4<float> pix_offset = CVect4<float>(m_PixelOffset.X(), m_PixelOffset.Y(), 0.0f, 1.0f);
166 
167  // rotate the offset if needed
168  if (m_RotAngleZ != 0.0) {
169  pix_offset = rm*pix_offset;
170  }
171 
172  tm(0, 3) = pix_offset.X()*(float)m_State->GetScaleFactor().X();
173  tm(1, 3) = pix_offset.Y()*(float)m_State->GetScaleFactor().Y();
174 
175  mat *= tm;
176  }
177 
178  /// Scale the object to keep size invarient with zoom (this scale comes after rotate)
179  if (m_State->GetScaleInvarient()) {
180  CMatrix4<float> s;
181  s.Identity();
182  s(0, 0) = (float)m_State->GetScaleFactor().X();
183  s(1, 1) = (float)m_State->GetScaleFactor().Y();
184  s(2, 2) = 1.0f;
185  mat *= s;
186  }
187 
188  // Rotate an amount that is proportional to current scaling in 2D
189  // projection matrix
190  if (m_RotAngleZ != 0.0) {
191  mat *= rm;
192  }
193 
194  // Scale before rotate!
195  if (m_RotAngleZ != 0.0f) {
196  CMatrix4<float> s;
197  s.Identity();
198  s(0, 0) = xs;
199  s(1, 1) = ys;
200  s(2, 2) = 1.0f;
201  mat *= s;
202  }
203 
204  return mat;
205 }
206 
CGlState Class to encapsulate Rendering state so that a set of user-selected GL state options can be ...
Definition: glstate.hpp:195
#define true
Definition: bool.h:35
T & X()
Definition: vect2.hpp:107
void Identity()
Definition: matrix4.hpp:373
T & X()
Definition: vect4.hpp:111
T & Y()
Definition: vect4.hpp:113
float Length2() const
Definition: vect2.hpp:278
T & Y()
Definition: vect2.hpp:109
void ClearPositions()
void SkipTarget(ERenderTarget target, bool skip)
Turn off visibility for individual render targets.
void SetDefaultPosition()
Set 1 transformation and have it be the identity matrix.
virtual void Render()
Set state and call x_Render() to render geometry.
CMatrix4< float > GetTransformedPosition(size_t idx)
return the position with rotation and pixel offset baked in
IRender & GetGl()
convenience function for getting current render manager
CVect2< TModelUnit > GetScaleFactor() const
Definition: glstate.hpp:327
CVect2< float > m_PixelOffset
Pixel offset to apply to object.
vector< CMatrix4< float > > m_Positions
Set of positions (transformations) at which to render this node.
CGlState & GetState()
void SetPosition(const CMatrix4< float > &mat)
Set 1 transformation and have it be "mat".
virtual void x_Render()
Does actual rendering work.
void SetState(CGlState *state)
Set/get current OpenGL state.
CRef< CGlState > m_State
OpenGL state.
void MakeCurrent(ERenderTarget target)
Set current options.
Definition: glstate.cpp:87
float m_RotAngleZ
Optional rotation angle to rotate object around Z axis.
ERenderTarget
Different api levels based on information from OpenGL driver.
Definition: glstate.hpp:61
virtual ERenderTarget GetApi()=0
vector< ERenderTarget > m_SkippedTargets
Set of rendering targets for which this node will not be rendered even if m_Visible is true.
bool IsSkipped(ERenderTarget target) const
bool GetScaleInvarient() const
Definition: glstate.hpp:322
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
TObjectType & GetNCObject(void) const
Get object.
Definition: ncbiobj.hpp:1187
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
unsigned int a
Definition: ncbi_localip.c:102
Modified on Sat Jun 22 10:37:53 2024 by modify_doxy.py rev. 669887