Back to index

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