nux-1.14.0
|
00001 /* 00002 * Copyright 2010 Inalogic® Inc. 00003 * 00004 * This program is free software: you can redistribute it and/or modify it 00005 * under the terms of the GNU Lesser General Public License, as 00006 * published by the Free Software Foundation; either version 2.1 or 3.0 00007 * of the License. 00008 * 00009 * This program is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranties of 00011 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR 00012 * PURPOSE. See the applicable version of the GNU Lesser General Public 00013 * License for more details. 00014 * 00015 * You should have received a copy of both the GNU Lesser General Public 00016 * License along with this program. If not, see <http://www.gnu.org/licenses/> 00017 * 00018 * Authored by: Jay Taoko <jaytaoko@inalogic.com> 00019 * 00020 */ 00021 00022 00023 #include "Nux.h" 00024 #include "NuxGraphics/GLSh_DrawFunction.h" 00025 #include "FunctionGraph.h" 00026 00027 namespace nux 00028 { 00029 00030 FunctionGraph::FunctionGraph (NUX_FILE_LINE_DECL) 00031 : View (NUX_FILE_LINE_PARAM) 00032 , m_minX (0.0f) 00033 , m_minY (0.0f) 00034 , m_maxX (1.0f) 00035 , m_maxY (1.0f) 00036 , m_FunctionCallback (0) 00037 { 00038 InitializeLayout(); 00039 InitializeWidgets(); 00040 } 00041 00042 FunctionGraph::~FunctionGraph() 00043 { 00044 NUX_SAFE_DELETE (m_DrawFunctionShader); 00045 NUX_SAFE_DELETE (m_BackgroundLayer); 00046 } 00047 00048 void FunctionGraph::InitializeWidgets() 00049 { 00050 SetMinimumSize (200, 100); 00051 SetBaseSize (200, 100); 00052 00053 Texture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture (256, 4, 0, BITFMT_R8G8B8A8); 00054 m_DrawFunctionShader = new GLSh_DrawFunction(); 00055 00056 NString Path = NUX_FINDRESOURCELOCATION (TEXT ("UITextures/FunctionGraphBackground.tga") ); 00057 BaseTexture* BackgroundTexture = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture (); 00058 BackgroundTexture->Update (Path.GetTCharPtr() ); 00059 00060 TexCoordXForm texxform; 00061 texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD); 00062 texxform.SetWrap (TEXWRAP_REPEAT, TEXWRAP_REPEAT); 00063 m_BackgroundLayer = new TextureLayer (BackgroundTexture->GetDeviceTexture(), texxform, color::White); 00064 00065 BackgroundTexture->UnReference (); 00066 } 00067 00068 void FunctionGraph::InitializeLayout() 00069 { 00070 00071 } 00072 00073 long FunctionGraph::ProcessEvent (IEvent &ievent, long TraverseInfo, long ProcessEventInfo) 00074 { 00075 return TraverseInfo; 00076 } 00077 00078 void FunctionGraph::Draw (GraphicsEngine &GfxContext, bool force_draw) 00079 { 00080 Geometry base = GetGeometry(); 00081 00082 GetPainter().PaintBackground (GfxContext, base); 00083 GetPainter().Paint2DQuadWireframe (GfxContext, base, Color (COLOR_BACKGROUND_SECONDARY) ); 00084 00085 int W = GetBaseWidth() - 2; 00086 int H = GetBaseHeight() - 2; 00087 int X = GetBaseX() + 1; 00088 int Y = GetBaseY() + 1; 00089 00090 float dX = (m_maxX - m_minX) / W; 00091 00092 float x0, y0; 00093 x0 = m_minX; 00094 y0 = EvalFunction (x0); 00095 00096 //GetPainter().Draw2DLine(X, Y, X+W, Y+H, Color(0xFFFF0000)); 00097 00098 base.OffsetPosition (1, 1); 00099 base.OffsetSize (-2, -2); 00100 00101 GfxContext.PushClippingRectangle (base); 00102 00103 float tex_dx = (m_maxX - m_minX) / Texture->GetWidth(); 00104 SURFACE_LOCKED_RECT lockrect; 00105 Texture->LockRect (0, &lockrect, 0); 00106 BYTE *dest = (BYTE *) lockrect.pBits; 00107 00108 for (t_s32 i = 0; i < Texture->GetWidth(); i++) 00109 { 00110 float y = EvalFunction (m_minX + i * tex_dx); 00111 y = (y - m_minY) / (m_maxY - m_minY); 00112 00113 for (t_s32 j = 0; j < Texture->GetHeight(); j++) 00114 { 00115 dest[4*i + 0 + j *lockrect.Pitch] = 255 * Clamp<float> (y, 0.0f, 1.0f); 00116 dest[4*i + 1 + j *lockrect.Pitch] = 255 * Clamp<float> (y, 0.0f, 1.0f); 00117 dest[4*i + 2 + j *lockrect.Pitch] = 255 * Clamp<float> (y, 0.0f, 1.0f); 00118 dest[4*i + 3 + j *lockrect.Pitch] = 255 * Clamp<float> (y, 0.0f, 1.0f); 00119 } 00120 } 00121 00122 Texture->UnlockRect (0); 00123 00124 m_BackgroundLayer->SetGeometry (base); 00125 m_BackgroundLayer->Renderlayer (GfxContext); 00126 00127 GfxContext.GetRenderStates().SetBlend (TRUE, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00128 00129 m_DrawFunctionShader->SetTextureFunction (Texture); 00130 m_DrawFunctionShader->SetBackgroundColor(Color(0.1f, 0.1f, 0.1f, 0.6f)); 00131 m_DrawFunctionShader->Render (X, Y, 0, W, H, GfxContext.GetWindowWidth(), GfxContext.GetWindowHeight() ); 00132 00133 GfxContext.GetRenderStates().EnableLineSmooth (TRUE, 1, GL_FASTEST); //You need this blending formula to get anti-aliased lines 00134 00135 for (int i = 1; i < GetBaseWidth(); i++) 00136 { 00137 float x1, y1; 00138 x1 = x0 + dX; 00139 y1 = EvalFunction (x1); 00140 00141 int X0, Y0, X1, Y1; 00142 X0 = X + W * (x0 - m_minX) / (m_maxX - m_minX); 00143 Y0 = Y + H * ( 1 - (y0 - m_minY) / (m_maxY - m_minY) ); 00144 X1 = X + W * (x1 - m_minX) / (m_maxX - m_minX); 00145 Y1 = Y + H * ( 1 - (y1 - m_minY) / (m_maxY - m_minY) ); 00146 GetPainter().Draw2DLine (GfxContext, X0, Y0, X1, Y1, Color (0xFFFFFFFF) ); 00147 00148 x0 = x1; 00149 y0 = y1; 00150 } 00151 00152 GfxContext.GetRenderStates().EnableLineSmooth (FALSE); 00153 GfxContext.GetRenderStates().SetBlend (GL_FALSE); 00154 00155 GfxContext.PopClippingRectangle(); 00156 } 00157 00158 void FunctionGraph::DrawContent (GraphicsEngine &GfxContext, bool force_draw) 00159 { 00160 00161 } 00162 00163 void FunctionGraph::PostDraw (GraphicsEngine &GfxContext, bool force_draw) 00164 { 00165 00166 } 00167 00168 void FunctionGraph::SetXAxisBounds (float minX, float maxX) 00169 { 00170 m_minX = minX; 00171 m_maxX = maxX; 00172 QueueDraw(); 00173 } 00174 00175 void FunctionGraph::SetYAxisBounds (float minY, float maxY) 00176 { 00177 m_minY = minY; 00178 m_maxY = maxY; 00179 QueueDraw(); 00180 } 00181 00182 void FunctionGraph::SetFunctionCallback (FunctionCallback f) 00183 { 00184 m_FunctionCallback = f; 00185 QueueDraw(); 00186 } 00187 00188 float FunctionGraph::EvalFunction (float x) 00189 { 00190 if (m_FunctionCallback != 0) 00191 return (*m_FunctionCallback) (x); 00192 00193 return 0; 00194 } 00195 00196 void FunctionGraph::UpdateGraph() 00197 { 00198 QueueDraw(); 00199 } 00200 00201 }