nux-1.16.0
GLSh_ColorPicker.cpp
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 #include "NuxCore/NuxCore.h"
00023 #include "NuxCore/Math/Matrix4.h"
00024 #include "GLResource.h"
00025 #include "GpuDevice.h"
00026 #include "GLDeviceObjects.h"
00027 #include "GLResourceManager.h"
00028 #include "GLTextureResourceManager.h"
00029 #include "GLVertexResourceManager.h"
00030 #include "GLTemplatePrimitiveBuffer.h"
00031 #include "GraphicsEngine.h"
00032 #include "GLShaderParameter.h"
00033 
00034 #include "GLSh_ColorPicker.h"
00035 
00036 namespace nux
00037 {
00038 
00039 // The GLSL shaders may contain branches. Intel GPU so far fails on these shaders.
00040 // Use assembly shaders for Intel GPUs: ARB_fragment_program does not have the required
00041 // instruction to implement the HSV to RGB color conversion.
00042 
00043   static NString VtxShader = TEXT ("#version 110   \n\
00044         uniform mat4 ViewProjectionMatrix;      \n\
00045         attribute vec4 AVertex;                 \n\
00046         attribute vec4 VertexColor;             \n\
00047         void main()                             \n\
00048         {                                       \n\
00049             gl_Position = ViewProjectionMatrix * AVertex;   \n\
00050         }");
00051 
00052   static NString RedFrgShader = TEXT ("#version 110                            \n\
00053         uniform vec4 RectPosition;              \n\
00054         uniform vec4 RectDimension;             \n\
00055         uniform vec4 Color;                     \n\
00056         void main(void)                         \n\
00057         {                                       \n\
00058             float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x;  \n\
00059             float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y;  \n\
00060             gl_FragColor = vec4(Color.r, y, x, 1.0);                        \n\
00061         }");
00062 
00063   static NString GreenFrgShader = TEXT ("#version 110                            \n\
00064         uniform vec4 RectPosition;              \n\
00065         uniform vec4 RectDimension;             \n\
00066         uniform vec4 Color;                     \n\
00067         void main(void)                         \n\
00068         {                                       \n\
00069             float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x;  \n\
00070             float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y;  \n\
00071             gl_FragColor = vec4(y, Color.g, x, 1.0);                        \n\
00072         }");
00073 
00074   static NString BlueFrgShader = TEXT ("#version 110                            \n\
00075         uniform vec4 RectPosition;              \n\
00076         uniform vec4 RectDimension;             \n\
00077         uniform vec4 Color;                     \n\
00078         void main(void)                         \n\
00079         {                                       \n\
00080             float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x;  \n\
00081             float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y;  \n\
00082             gl_FragColor = vec4(x, y, Color.b, 1.0);                        \n\
00083         }");
00084 
00085   static NString HueFrgShader = TEXT ("#version 110        \n\
00086         vec3 HSV_To_RGB(vec3 HSV);                      \n\
00087         uniform vec4 RectPosition;                      \n\
00088         uniform vec4 RectDimension;                     \n\
00089         uniform vec4 Color;                             \n\
00090         void main(void)                                 \n\
00091         {                                               \n\
00092             float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x;  \n\
00093             float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y;  \n\
00094             vec3 rgb = HSV_To_RGB(vec3(Color.x, x, y));         \n\
00095             gl_FragColor = vec4(rgb, 1.0);                      \n\
00096         }");
00097 
00098   static NString SaturationFrgShader = TEXT ("#version 110     \n\
00099         vec3 HSV_To_RGB(vec3 HSV);                          \n\
00100         uniform vec4 RectPosition;                          \n\
00101         uniform vec4 RectDimension;                         \n\
00102         uniform vec4 Color;                                 \n\
00103         void main(void)                                     \n\
00104         {                                                   \n\
00105             float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x;  \n\
00106             float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y;  \n\
00107             vec3 rgb = HSV_To_RGB(vec3(x, Color.y, y));         \n\
00108             gl_FragColor = vec4(rgb, 1.0);                      \n\
00109         }");
00110 
00111   static NString ValueFrgShader = TEXT ("#version 110  \n\
00112         vec3 HSV_To_RGB(vec3 HSV);                  \n\
00113         uniform vec4 RectPosition;                  \n\
00114         uniform vec4 RectDimension;                 \n\
00115         uniform vec4 Color;                         \n\
00116         void main(void)                             \n\
00117         {                                           \n\
00118             float x = (gl_FragCoord.x - RectPosition.x) / RectDimension.x;  \n\
00119             float y = (gl_FragCoord.y - RectPosition.y) / RectDimension.y;  \n\
00120             vec3 rgb = HSV_To_RGB(vec3(x, y, Color.z));                     \n\
00121             gl_FragColor = vec4(rgb, 1.0);                                  \n\
00122         }");
00123 
00124   static NString HSV_To_RGBFrgShader = TEXT ("#version 110  \n\
00125         vec3 HSV_To_RGB(vec3 HSV)                                               \n\
00126         {                                                                       \n\
00127             vec3 RGB = vec3(HSV.z);                                             \n\
00128             if ( HSV.y != 0.0 )                                                 \n\
00129             {                                                                   \n\
00130                 float var_h = HSV.x * 6.0;                                      \n\
00131                 float var_i = floor(var_h);   // Or ... var_i = floor( var_h )  \n\
00132                 float var_1 = HSV.z * (1.0 - HSV.y);                            \n\
00133                 float var_2 = HSV.z * (1.0 - HSV.y * (var_h-var_i));            \n\
00134                 float var_3 = HSV.z * (1.0 - HSV.y * (1.0-(var_h-var_i)));      \n\
00135                 if      (var_i == 0.0) { RGB = vec3(HSV.z, var_3, var_1); }     \n\
00136                 else if (var_i == 1.0) { RGB = vec3(var_2, HSV.z, var_1); }     \n\
00137                 else if (var_i == 2.0) { RGB = vec3(var_1, HSV.z, var_3); }     \n\
00138                 else if (var_i == 3.0) { RGB = vec3(var_1, var_2, HSV.z); }     \n\
00139                 else if (var_i == 4.0) { RGB = vec3(var_3, var_1, HSV.z); }     \n\
00140                 else                 { RGB = vec3(HSV.z, var_1, var_2); }       \n\
00141             }                                                                   \n\
00142             return (RGB);                                                       \n\
00143         }");
00144 
00146 
00147   static NString AsmVtxShader = TEXT ("!!ARBvp1.0                                 \n\
00148         ATTRIB iPos         = vertex.position;      \n\
00149         PARAM  mvp[4]       = {state.matrix.mvp};   \n\
00150         OUTPUT oPos         = result.position;      \n\
00151         # Transform the vertex to clip coordinates. \n\
00152         DP4   oPos.x, mvp[0], iPos;      \n\
00153         DP4   oPos.y, mvp[1], iPos;      \n\
00154         DP4   oPos.z, mvp[2], iPos;      \n\
00155         DP4   oPos.w, mvp[3], iPos;      \n\
00156         END");
00157 
00158   NString AsmRedFrgShader = TEXT ("!!ARBfp1.0                  \n\
00159         PARAM RectPosition = program.local[0];              \n\
00160         PARAM RectDimension = program.local[1];             \n\
00161         PARAM Color = program.local[2];                     \n\
00162         TEMP temp0;                                         \n\
00163         TEMP temp1;                                         \n\
00164         SUB temp0.x, fragment.position.x, RectPosition.x;   \n\
00165         SUB temp0.y, fragment.position.y, RectPosition.y;   \n\
00166         RCP temp1.x, RectDimension.x;                       \n\
00167         RCP temp1.y, RectDimension.y;                       \n\
00168         MUL temp0.xy, temp0, temp1;                         \n\
00169         MOV temp1.x, Color;                                 \n\
00170         MOV temp1.yz, temp0.yyxx;                           \n\
00171         MOV temp1.w, {1, 1, 1, 1};                          \n\
00172         MOV result.color, temp1;                            \n\
00173         END");
00174 
00175   NString AsmGreenFrgShader = TEXT ("!!ARBfp1.0                  \n\
00176        PARAM RectPosition = program.local[0];              \n\
00177        PARAM RectDimension = program.local[1];             \n\
00178        PARAM Color = program.local[2];                     \n\
00179        TEMP temp0;                                         \n\
00180        TEMP temp1;                                         \n\
00181        SUB temp0.x, fragment.position.x, RectPosition.x;   \n\
00182        SUB temp0.y, fragment.position.y, RectPosition.y;   \n\
00183        RCP temp1.x, RectDimension.x;                       \n\
00184        RCP temp1.y, RectDimension.y;                       \n\
00185        MUL temp0.xy, temp0, temp1;                         \n\
00186        MOV temp1.y, Color;                                 \n\
00187        MOV temp1.xz, temp0.yyxx;                           \n\
00188        MOV temp1.w, {1, 1, 1, 1};                          \n\
00189        MOV result.color, temp1;                            \n\
00190        END");
00191 
00192   NString AsmBlueFrgShader = TEXT ("!!ARBfp1.0                \n\
00193        PARAM RectPosition = program.local[0];              \n\
00194        PARAM RectDimension = program.local[1];             \n\
00195        PARAM Color = program.local[2];                     \n\
00196        TEMP temp0;                                         \n\
00197        TEMP temp1;                                         \n\
00198        SUB temp0.x, fragment.position.x, RectPosition.x;   \n\
00199        SUB temp0.y, fragment.position.y, RectPosition.y;   \n\
00200        RCP temp1.x, RectDimension.x;                       \n\
00201        RCP temp1.y, RectDimension.y;                       \n\
00202        MUL temp0.xy, temp0, temp1;                         \n\
00203        MOV temp1.z, Color;                                 \n\
00204        MOV temp1.xy, temp0.xyxx;                           \n\
00205        MOV temp1.w, {1, 1, 1, 1};                          \n\
00206        MOV result.color, temp1;                            \n\
00207        END");
00208 
00209 
00210   NString AsmHueFrgShader = TEXT ("!!ARBfp1.0                  \n\
00211         MOV result.color, {0, 0, 0, 0};                     \n\
00212         END");
00213 
00214   NString AsmSaturationFrgShader = TEXT ("!!ARBfp1.0                  \n\
00215        MOV result.color, {0, 0, 0, 0};                      \n\
00216        END");
00217 
00218   NString AsmValueFrgShader = TEXT ("!!ARBfp1.0                  \n\
00219        MOV result.color, {0, 0, 0, 0};                      \n\
00220        END");
00221 
00222 
00223 
00224 GLSh_ColorPicker::GLSh_ColorPicker (color::Channel color_channel)
00225     :   _R (1.0)
00226     ,   _G (0.0)
00227     ,   _B (0.0)
00228     ,   _A (1.0)
00229     ,   _ScreenOffsetX (0)
00230     ,   _ScreenOffsetY (0)
00231   {
00232     NString FrgShaderCode;
00233 
00234     if (GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath() && (GetGraphicsDisplay()->GetGpuDevice()->GetGPUBrand() != GPU_BRAND_INTEL) )
00235     {
00236       switch (color_channel)
00237       {
00238         case color::RED:
00239         {
00240           FrgShaderCode = RedFrgShader;
00241           break;
00242         }
00243         case color::GREEN:
00244         {
00245           FrgShaderCode = GreenFrgShader;
00246           break;
00247         }
00248         case color::BLUE:
00249         {
00250           FrgShaderCode = BlueFrgShader;
00251           break;
00252         }
00253         case color::HUE:
00254         {
00255           FrgShaderCode = HueFrgShader;
00256           break;
00257         }
00258         case color::SATURATION:
00259         {
00260           FrgShaderCode = SaturationFrgShader;
00261           break;
00262         }
00263         case color::VALUE:
00264         {
00265           FrgShaderCode = ValueFrgShader;
00266           break;
00267         }
00268         default:
00269         {
00270           nuxDebugMsg (TEXT ("[GLSh_ColorPicker::GLSh_ColorPicker] Unknown color channel") );
00271           FrgShaderCode = RedFrgShader;
00272           break;
00273         }
00274       }
00275 
00276       GlobalPixelShader = GetGraphicsDisplay()->GetGpuDevice()->CreatePixelShader();
00277       sprog = GetGraphicsDisplay()->GetGpuDevice()->CreateShaderProgram();
00278 
00279       GlobalPixelShader->SetShaderCode (HSV_To_RGBFrgShader.GetTCharPtr() );
00280 
00281       sprog->AddShaderObject (GlobalPixelShader);
00282       sprog->LoadVertexShader (VtxShader.GetTCharPtr(), NULL);
00283       sprog->LoadPixelShader (FrgShaderCode.GetTCharPtr(), NULL);
00284       sprog->Link();
00285     }
00286     else
00287     {
00288       switch (color_channel)
00289       {
00290         case color::RED:
00291         {
00292           FrgShaderCode = AsmRedFrgShader;
00293           break;
00294         }
00295         case color::GREEN:
00296         {
00297           FrgShaderCode = AsmGreenFrgShader;
00298           break;
00299         }
00300         case color::BLUE:
00301         {
00302           FrgShaderCode = AsmBlueFrgShader;
00303           break;
00304         }
00305         case color::HUE:
00306         {
00307           FrgShaderCode = AsmHueFrgShader;
00308           break;
00309         }
00310         case color::SATURATION:
00311         {
00312           FrgShaderCode = AsmSaturationFrgShader;
00313           break;
00314         }
00315         case color::VALUE:
00316         {
00317           FrgShaderCode = AsmValueFrgShader;
00318           break;
00319         }
00320         default:
00321         {
00322           nuxDebugMsg (TEXT ("[GLSh_ColorPicker::GLSh_ColorPicker] Unknown color channel") );
00323           FrgShaderCode = RedFrgShader;
00324           break;
00325         }
00326       }
00327 
00328       m_AsmProg = GetGraphicsDisplay()->GetGpuDevice()->CreateAsmShaderProgram();
00329       m_AsmProg->LoadVertexShader (AsmVtxShader.GetTCharPtr() );
00330       m_AsmProg->LoadPixelShader (FrgShaderCode.GetTCharPtr() );
00331       m_AsmProg->Link();
00332     }
00333   }
00334 
00335   GLSh_ColorPicker::~GLSh_ColorPicker()
00336   {
00337     GlobalPixelShader = ObjectPtr<IOpenGLPixelShader> (0);
00338     sprog.Release();
00339     m_AsmProg.Release();
00340   }
00341 
00342   void GLSh_ColorPicker::SetColor (float R, float G, float B, float A)
00343   {
00344     _R = R;
00345     _G = G;
00346     _B = B;
00347     _A = A;
00348   }
00349 
00350   void GLSh_ColorPicker::SetScreenPositionOffset (float x, float y)
00351   {
00352     _ScreenOffsetX = x;
00353     _ScreenOffsetY = y;
00354   }
00355 
00356   void GLSh_ColorPicker::Render (int x, int y, int z, int width, int height, int WindowWidth, int WindowHeight)
00357   {
00358     float fx = x, fy = y;
00359     float VtxBuffer[] =
00360     {
00361       fx,          fy,          0.0f, 1.0f,
00362       fx,          fy + height, 0.0f, 1.0f,
00363       fx + width,  fy + height, 0.0f, 1.0f,
00364       fx + width,  fy,          0.0f, 1.0f,
00365     };
00366 
00367     if (GetGraphicsDisplay()->GetGraphicsEngine()->UsingGLSLCodePath() && (GetGraphicsDisplay()->GetGpuDevice()->GetGPUBrand() != GPU_BRAND_INTEL) )
00368     {
00369       CHECKGL (glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0) );
00370       CHECKGL (glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0) );
00371       sprog->Begin();
00372 
00373       int VertexLocation = sprog->GetAttributeLocation ("AVertex");
00374 
00375       int VPMatrixLocation = sprog->GetUniformLocationARB ("ViewProjectionMatrix");
00376       Matrix4 MVPMatrix = GetGraphicsDisplay()->GetGraphicsEngine ()->GetOpenGLModelViewProjectionMatrix ();
00377 
00378       sprog->SetUniformLocMatrix4fv ( (GLint) VPMatrixLocation, 1, false, (GLfloat *) & (MVPMatrix.m) );
00379 
00380       int ColorBase    = sprog->GetUniformLocationARB ("Color");
00381       int RectPosition    = sprog->GetUniformLocationARB ("RectPosition");
00382       int RectDimension   = sprog->GetUniformLocationARB ("RectDimension");
00383 
00384       if (ColorBase != -1)
00385         CHECKGL ( glUniform4fARB (ColorBase, _R, _G, _B, _A) );
00386 
00387       if (RectPosition != -1)
00388         CHECKGL ( glUniform4fARB (RectPosition, x + _ScreenOffsetX, WindowHeight - y - height - _ScreenOffsetY, z, 0.0f) );
00389 
00390       if (RectDimension != -1)
00391         CHECKGL ( glUniform4fARB (RectDimension, width, height, 0.0f, 0.0f) );
00392 
00393       CHECKGL ( glEnableVertexAttribArrayARB (VertexLocation) );
00394       CHECKGL ( glVertexAttribPointerARB ( (GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 16, VtxBuffer) );
00395 
00396       CHECKGL ( glDrawArrays (GL_TRIANGLE_FAN, 0, 4) );
00397 
00398       CHECKGL ( glDisableVertexAttribArrayARB (VertexLocation) );
00399 
00400       sprog->End();
00401     }
00402 #ifndef NUX_OPENGLES_20
00403     else
00404     {
00405       CHECKGL (glBindBufferARB (GL_ARRAY_BUFFER_ARB, 0) );
00406       CHECKGL (glBindBufferARB (GL_ELEMENT_ARRAY_BUFFER_ARB, 0) );
00407       m_AsmProg->Begin();
00408 
00409       CHECKGL ( glMatrixMode (GL_MODELVIEW) );
00410       CHECKGL ( glLoadIdentity() );
00411       CHECKGL ( glLoadMatrixf ( (FLOAT *) GetGraphicsDisplay()->GetGraphicsEngine()->GetOpenGLModelViewMatrix().m) );
00412       CHECKGL ( glMatrixMode (GL_PROJECTION) );
00413       CHECKGL ( glLoadIdentity() );
00414       CHECKGL ( glLoadMatrixf ( (FLOAT *) GetGraphicsDisplay()->GetGraphicsEngine()->GetOpenGLProjectionMatrix().m) );
00415 
00416       int VertexLocation          = VTXATTRIB_POSITION;
00417 
00418       CHECKGL ( glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 0, x + _ScreenOffsetX, WindowHeight - y - height - _ScreenOffsetY, z, 0.0f) );
00419       CHECKGL ( glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 1, width, height, 0.0f, 0.0f) );
00420       CHECKGL ( glProgramLocalParameter4fARB (GL_FRAGMENT_PROGRAM_ARB, 2, _R, _G, _B, _A) );
00421 
00422       CHECKGL ( glEnableVertexAttribArrayARB (VertexLocation) );
00423       CHECKGL ( glVertexAttribPointerARB ( (GLuint) VertexLocation, 4, GL_FLOAT, GL_FALSE, 16, VtxBuffer) );
00424 
00425       CHECKGL ( glDrawArrays (GL_TRIANGLE_FAN, 0, 4) );
00426 
00427       CHECKGL ( glDisableVertexAttribArrayARB (VertexLocation) );
00428 
00429       m_AsmProg->End();
00430     }
00431 #endif
00432   }
00433 
00434 }
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends