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 #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 }