From b82ddacc097cd77c2a92a71740d307eb6bcd7c09 Mon Sep 17 00:00:00 2001 From: Heeyong Song Date: Wed, 28 Aug 2013 16:47:51 +0900 Subject: [PATCH] Enable light & material Change-Id: Id032c78903bc076b665a05750f8bdf3c93483cea --- src/ui/animations/FUiAnim_GlNode.cpp | 79 +++++++++++ src/ui/animations/FUiAnim_GlNode.h | 39 ++++++ src/ui/animations/FUiAnim_GlRenderManager.cpp | 164 +++++++++++++++++++++++ src/ui/animations/FUiAnim_GlRenderManager.h | 11 ++ src/ui/animations/FUiAnim_GlShaderProgram.cpp | 103 +++++++++++++- src/ui/animations/FUiAnim_GlShaderProgram.h | 49 +++++++ src/ui/animations/platform/FUiAnim_GlContext.cpp | 2 + 7 files changed, 446 insertions(+), 1 deletion(-) diff --git a/src/ui/animations/FUiAnim_GlNode.cpp b/src/ui/animations/FUiAnim_GlNode.cpp index 69d6692..fd35d8f 100644 --- a/src/ui/animations/FUiAnim_GlNode.cpp +++ b/src/ui/animations/FUiAnim_GlNode.cpp @@ -78,6 +78,9 @@ _GlNode::_GlNode(void) , __textureId(0) , __pLayer(null) , __pMesh(null) + , __pLight(null) + , __pMaterial(null) + , __pShaderProgram(null) { } @@ -120,6 +123,25 @@ _GlNode::Destruct(void) __pSharedSurface = null; } + if (__pMesh) + { + delete __pMesh; + __pMesh = null; + } + + // temp + if (__pLight) + { + delete __pLight; + __pLight = null; + } + + if (__pMaterial) + { + delete __pMaterial; + __pMaterial = null; + } + return E_SUCCESS; } @@ -350,6 +372,63 @@ _GlNode::SyncStatus(VisualElementSurface* pSurface, _VisualElementImpl& element) { // TODO: implement } + + // temp + if (__pLight == null) + { + __pLight = new (std::nothrow) _Light(); + + __objectColor.SetRGBAColor(0.0f, 0.0f, 1.0f, 1.0f); + + __pLight->__type = _Light::LIGHT_TYPE_DIRECTIONAL; + + __pLight->__ambient[0] = 0.2f; + __pLight->__ambient[1] = 0.2f; + __pLight->__ambient[2] = 0.2f; + __pLight->__ambient[3] = 1.0f; + + __pLight->__diffuse[0] = 0.8f; + __pLight->__diffuse[1] = 0.0f; + __pLight->__diffuse[2] = 0.0f; + __pLight->__diffuse[3] = 1.0f; + + __pLight->__specular[0] = 0.0f; + __pLight->__specular[1] = 0.0f; + __pLight->__specular[2] = 1.0f; + __pLight->__specular[3] = 1.0f; + + __pLight->__position[0] = 1.0f; + __pLight->__position[1] = -1.0f; + __pLight->__position[2] = 1.0f; + __pLight->__position[3] = 0.0f; + } + + if (__pMaterial == null) + { + __pMaterial = new (std::nothrow) _Material(); + + __pMaterial->__ambient[0] = 1.0f; + __pMaterial->__ambient[1] = 1.0f; + __pMaterial->__ambient[2] = 1.0f; + __pMaterial->__ambient[3] = 1.0f; + + __pMaterial->__diffuse[0] = 1.0f; + __pMaterial->__diffuse[1] = 1.0f; + __pMaterial->__diffuse[2] = 1.0f; + __pMaterial->__diffuse[3] = 1.0f; + + __pMaterial->__specular[0] = 1.0f; + __pMaterial->__specular[1] = 1.0f; + __pMaterial->__specular[2] = 1.0f; + __pMaterial->__specular[3] = 1.0f; + + __pMaterial->__emissive[0] = 0.0f; + __pMaterial->__emissive[1] = 0.0f; + __pMaterial->__emissive[2] = 0.0f; + __pMaterial->__emissive[3] = 0.0f; + + __pMaterial->__shiness = 10.0f; + } } else { diff --git a/src/ui/animations/FUiAnim_GlNode.h b/src/ui/animations/FUiAnim_GlNode.h index 7b86320..b31a23f 100644 --- a/src/ui/animations/FUiAnim_GlNode.h +++ b/src/ui/animations/FUiAnim_GlNode.h @@ -45,6 +45,42 @@ class VisualElementSurface; class _NativeLayer; class Mesh; +// temp +class _Light : public Tizen::Base::Object +{ +public: + enum LightType + { + LIGHT_TYPE_POINT = 0, + LIGHT_TYPE_SPOT = 1, + LIGHT_TYPE_DIRECTIONAL = 2 + }; + + LightType __type; + + float __ambient[4]; + float __diffuse[4]; + float __specular[4]; + + float __position[4]; + float __direction[3]; + + float __exponent; + float __cutOff; + float __attenuation[3]; +}; + +// temp +class _Material : public Tizen::Base::Object +{ +public: + float __ambient[4]; + float __diffuse[4]; + float __specular[4]; + float __emissive[4]; + float __shiness; +}; + class _OSP_EXPORT_ _GlNode : public _INativeNode { @@ -108,6 +144,9 @@ private: _NativeLayer* __pLayer; Mesh* __pMesh; + _Light* __pLight; + _Material* __pMaterial; + ShaderProgram* __pShaderProgram; friend class _INativeNode; diff --git a/src/ui/animations/FUiAnim_GlRenderManager.cpp b/src/ui/animations/FUiAnim_GlRenderManager.cpp index 41b266d..7c0c480 100644 --- a/src/ui/animations/FUiAnim_GlRenderManager.cpp +++ b/src/ui/animations/FUiAnim_GlRenderManager.cpp @@ -87,12 +87,16 @@ _GlRenderManager::_RenderObject::_RenderObject(void) , __stencilIndex(0) , __isMesh(false) , __mvp() + , __modelview() + , __invModelview() , __objectColor() , __opacity(0.0f) , __colorMask(true) , __textureId(0) , __pSurfaceInfo(null) , __bounds() + , __pLight(null) + , __pMaterial(null) , __pVertexBuffer(null) , __pTexCoordBuffer(null) , __geoType(0) @@ -333,6 +337,20 @@ _GlRenderManager::_RenderObject::SetObject(_GlNode* pNode, const _Matrix3Df& mvp } } + if (pNode->__pLight || pNode->__pMaterial) + { + __pLight = pNode->__pLight; + __pMaterial = pNode->__pMaterial; + + __modelview = _Matrix3Df(pNode->__transform); + + __invModelview.Assign(__modelview); + __invModelview.Invert(); + __invModelview.Transpose(); // TODO: optimize + + __pProgram = _GlRenderManager::GetInstance()->__pLightShader; + } + // Set program info __uMVP = __pProgram->GetMVPUniformLocation(); __uOpacity = __pProgram->GetOpacityUniformLocation(); @@ -443,6 +461,7 @@ _GlRenderManager::_GlRenderManager(void) , __pUniformColorShader(null) , __pTextureShader(null) , __pTextureOpacityShader(null) + , __pLightShader(null) { memset(&__threadInfo, 0x00, sizeof(pthread_t)); @@ -457,6 +476,7 @@ _GlRenderManager::_GlRenderManager(void) __pUniformColorShader = new (std::nothrow) _GlUniformColorShaderProgram; __pTextureShader = new (std::nothrow) _GlTextureShaderProgram; __pTextureOpacityShader = new (std::nothrow) _GlTextureOpacityShaderProgram; + __pLightShader = new (std::nothrow) _GlLightShaderProgram; } _GlRenderManager::~_GlRenderManager(void) @@ -714,6 +734,28 @@ _GlRenderManager::FlushRenderQueue(void) glVertexAttribPointer(__pRenderQueue[i].__aColor, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), __pRenderQueue[i].__pColors); glVertexAttribPointer(__pRenderQueue[i].__aNormal, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), __pRenderQueue[i].__pNormals); + if (__pRenderQueue[i].__pLight) + { + glUniformMatrix4fv(__pLightShader->__uniformLocModelView, 1, GL_FALSE, __pRenderQueue[i].__modelview.GetItems()); + glUniformMatrix4fv(__pLightShader->__uniformLocInvModelView, 1, GL_FALSE, __pRenderQueue[i].__invModelview.GetItems()); + + glUniform1i(__pLightShader->__uniformLocLightType, __pRenderQueue[i].__pLight->__type); + glUniform4fv(__pLightShader->__uniformLocLightAmbient, 1, __pRenderQueue[i].__pLight->__ambient); + glUniform4fv(__pLightShader->__uniformLocLightDiffuse, 1, __pRenderQueue[i].__pLight->__diffuse); + glUniform4fv(__pLightShader->__uniformLocLightSpecular, 1, __pRenderQueue[i].__pLight->__specular); + glUniform4fv(__pLightShader->__uniformLocLightPosition, 1, __pRenderQueue[i].__pLight->__position); + glUniform3fv(__pLightShader->__uniformLocLightDirection, 1, __pRenderQueue[i].__pLight->__direction); + glUniform1f(__pLightShader->__uniformLocLightExponent, __pRenderQueue[i].__pLight->__exponent); + glUniform1f(__pLightShader->__uniformLocLightCutOff, __pRenderQueue[i].__pLight->__cutOff); + glUniform3fv(__pLightShader->__uniformLocLightAttenuation, 1, __pRenderQueue[i].__pLight->__attenuation); + + glUniform4fv(__pLightShader->__uniformLocMaterialAmbient, 1, __pRenderQueue[i].__pMaterial->__ambient); + glUniform4fv(__pLightShader->__uniformLocMaterialDiffuse, 1, __pRenderQueue[i].__pMaterial->__diffuse); + glUniform4fv(__pLightShader->__uniformLocMaterialSpecular, 1, __pRenderQueue[i].__pMaterial->__specular); + glUniform4fv(__pLightShader->__uniformLocMaterialEmissive, 1, __pRenderQueue[i].__pMaterial->__emissive); + glUniform1f(__pLightShader->__uniformLocMaterialShiness, __pRenderQueue[i].__pMaterial->__shiness); + } + if (__pRenderQueue[i].__textureId > 0) { __pGlContext->BindTexture(__pRenderQueue[i].__textureId); @@ -1535,6 +1577,126 @@ _GlRenderManager::PrepareShaders(void) " gl_FragColor = texture2D(u_tex2d, v_texcoord) * u_opacity;\n" "}\n"; + static const char strVertexShader_light[] = + "struct light\n" + "{\n" + " int type;\n" + " vec4 ambient;\n" + " vec4 diffuse;\n" + " vec4 specular;\n" + " vec4 position;\n" + " vec3 direction;\n" + " float exponent;\n" + " float cutoff;\n" + " vec3 attenuation;\n" + "};\n" + "struct material\n" + "{\n" + " vec4 ambient;\n" + " vec4 diffuse;\n" + " vec4 specular;\n" + " vec4 emissive;\n" + " float shiness;\n" + "};\n" + "\n" + "const float c_zero = 0.0;\n" + "const float c_one = 1.0;\n" + "const int indx_zero = 0;\n" + "const int indx_one = 1;\n" + "\n" + "uniform mat4 u_mvp;\n" + "uniform mat4 u_modelview;\n" + "//uniform mat3 u_inv_modelview;\n" + "uniform mat4 u_inv_modelview;\n" + "\n" + "uniform material u_material;\n" + "uniform light u_light;\n" + "\n" + "attribute vec4 a_position;\n" + "attribute vec4 a_texcoord;\n" + "attribute vec4 a_color;\n" + "attribute vec3 a_normal;\n" + "\n" + "varying vec2 v_texcoord;\n" + "varying vec4 v_color;\n" + "\n" + "vec4\n" + "do_lighting()\n" + "{\n" + " vec3 lightdir, n, h;\n" + " vec4 color = vec4(c_zero, c_zero, c_zero, c_zero);\n" + " float ndotl, ndoth;\n" + "\n" + " n = normalize((u_inv_modelview * vec4(a_normal, 1.0)).xyz);\n" + "\n" + " if (u_light.type < 2)\n" + " {\n" + " vec3 att_dist;\n" + "\n" + " // point or spot case\n" + " lightdir = u_light.position.xyz - (u_modelview * a_position).xyz;\n" + "\n" + " // compute distance attenuation\n" + " // TODO\n" + "\n" + " lightdir = normalize(lightdir);\n" + "\n" + " if (u_light.cutoff < 180.0)\n" + " {\n" + " // compute spot factor\n" + " // TODO\n" + " }\n" + " }\n" + " else\n" + " {\n" + " lightdir = u_light.position.xyz;\n" + " }\n" + "\n" + "// if (attenuation > c_zero) // TODO: enable\n" + " {\n" + " color = u_light.ambient * u_material.ambient;\n" + "\n" + " ndotl = max(c_zero, dot(n, lightdir));\n" + " color += ndotl * u_light.diffuse * u_material.diffuse;\n" + "\n" + " h = normalize(lightdir + vec3(c_zero, c_zero, c_one));\n" + " ndoth = dot(n, h);\n" + "\n" + " if (ndoth > c_zero)\n" + " {\n" + " color += pow(ndoth, u_material.shiness) * u_material.specular * u_light.specular;\n" + " }\n" + "\n" + "// color *= att_factor; // TODO: enable\n" + " }\n" + "\n" + " color += u_material.emissive;\n" + "// color += u_material.emissive + u_material.ambient * u_scene_ambient;\n" + "\n" + " color.a = u_material.diffuse.a;\n" + "\n" + " return color;\n" + "}\n" + "\n" + "void\n" + "main()\n" + "{\n" + " v_color = do_lighting();\n" + " v_texcoord = a_texcoord.xy;\n" + " gl_Position = u_mvp * a_position;\n" + "}\n"; + + static const char strFragmentShader_light[] = + "precision highp float;\n" + "uniform sampler2D u_tex2d;\n" + "varying vec2 v_texcoord;\n" + "varying vec4 v_color;\n" + "void main()\n" + "{\n" + " gl_FragColor.rgba = v_color;\n" + "// gl_FragColor.rgba = texture2D(u_tex2d, v_texcoord).bgra * v_color;\n" + "}\n"; + // CHECK // enable poistion @@ -1553,6 +1715,8 @@ _GlRenderManager::PrepareShaders(void) __pTextureShader->LoadShader(strVertexShader_texture, strFragmentShader_texture); __pTextureOpacityShader->LoadShader(strVertexShader_texture, strFragmentShader_texture_opacity); } + + __pLightShader->LoadShader(strVertexShader_light, strFragmentShader_light); } void* diff --git a/src/ui/animations/FUiAnim_GlRenderManager.h b/src/ui/animations/FUiAnim_GlRenderManager.h index 8b02b04..17b55e6 100644 --- a/src/ui/animations/FUiAnim_GlRenderManager.h +++ b/src/ui/animations/FUiAnim_GlRenderManager.h @@ -52,6 +52,11 @@ class _GlColorShaderProgram; class _GlUniformColorShaderProgram; class _GlTextureShaderProgram; class _GlTextureOpacityShaderProgram; +class _GlLightShaderProgram; + +// temp +class _Light; +class _Material; struct TextureInfo; @@ -191,6 +196,8 @@ private: bool __isMesh; _Matrix3Df __mvp; + _Matrix3Df __modelview; + _Matrix3Df __invModelview; _Colorf __objectColor; float __opacity; @@ -201,6 +208,9 @@ private: _Rectanglef __bounds; + _Light* __pLight; + _Material* __pMaterial; + float* __pVertexBuffer; float* __pTexCoordBuffer; @@ -251,6 +261,7 @@ private: _GlUniformColorShaderProgram* __pUniformColorShader; _GlTextureShaderProgram* __pTextureShader; _GlTextureOpacityShaderProgram* __pTextureOpacityShader; + _GlLightShaderProgram* __pLightShader; friend class _RenderObject; }; // _GlRenderManager diff --git a/src/ui/animations/FUiAnim_GlShaderProgram.cpp b/src/ui/animations/FUiAnim_GlShaderProgram.cpp index 4c11c15..ab3c8b9 100644 --- a/src/ui/animations/FUiAnim_GlShaderProgram.cpp +++ b/src/ui/animations/FUiAnim_GlShaderProgram.cpp @@ -33,7 +33,7 @@ using namespace std; using namespace Tizen::Graphics; using namespace Tizen::Ui::Animations; -//#define PRINT fprintf(stderr, __VA_ARGS__) +//#define PRINT(...) fprintf(stderr, __VA_ARGS__) #define PRINT(...) namespace Tizen { namespace Ui { namespace Animations @@ -92,6 +92,11 @@ _GlShaderProgram::GetAttribLocation(const char* name) shaderVariable.value = glGetAttribLocation(__program, name); + if (shaderVariable.value == -1) + { + PRINT("_GlShaderProgram::GetAttribLocation: Invalid location! [%s]\n", name); + } + __shaderVariableList.push_back(shaderVariable); return shaderVariable.value; @@ -107,6 +112,11 @@ _GlShaderProgram::GetUniformLocation(const char* name) { int location = glGetUniformLocation(__program, name); + if (location == -1) + { + PRINT("_GlShaderProgram::GetUniformLocation: Invalid location! [%s]\n", name); + } + return location; } @@ -288,4 +298,95 @@ _GlTextureOpacityShaderProgram::OnProgramDereferenced(void) glDisableVertexAttribArray(__attrLocationTextureCoordinates); } +//================================================================================================================ + +_GlLightShaderProgram::_GlLightShaderProgram(void) + : __attrLocationPosition(-1) + , __attrLocationTextureCoordinates(-1) + , __attrLocationColor(-1) + , __attrLocationNormal(-1) + , __uniformLocationMVP(-1) + , __uniformLocationTexture2D(-1) + , __uniformLocModelView(-1) + , __uniformLocInvModelView(-1) + , __uniformLocLightType(-1) + , __uniformLocLightAmbient(-1) + , __uniformLocLightDiffuse(-1) + , __uniformLocLightSpecular(-1) + , __uniformLocLightPosition(-1) + , __uniformLocLightDirection(-1) + , __uniformLocLightExponent(-1) + , __uniformLocLightCutOff(-1) + , __uniformLocLightAttenuation(-1) + , __uniformLocMaterialAmbient(-1) + , __uniformLocMaterialDiffuse(-1) + , __uniformLocMaterialSpecular(-1) + , __uniformLocMaterialEmissive(-1) + , __uniformLocMaterialShiness(-1) +{ +} + +_GlLightShaderProgram::~_GlLightShaderProgram(void) +{ +} + +void +_GlLightShaderProgram::OnProgramCreated(void) +{ + _GlShaderProgram::OnProgramCreated(); + + __attrLocationPosition = GetAttribLocation("a_position"); + __attrLocationTextureCoordinates = GetAttribLocation("a_texcoord"); + __attrLocationColor = GetAttribLocation("a_color"); + __attrLocationNormal = GetAttribLocation("a_normal"); + + __uniformLocationMVP = GetUniformLocation("u_mvp"); + __uniformLocationTexture2D = GetUniformLocation("u_tex2d"); + + __uniformLocModelView = GetUniformLocation("u_modelview"); + __uniformLocInvModelView = GetUniformLocation("u_inv_modelview"); + + __uniformLocLightType = GetUniformLocation("u_light.type"); + __uniformLocLightAmbient = GetUniformLocation("u_light.ambient"); + __uniformLocLightDiffuse = GetUniformLocation("u_light.diffuse"); + __uniformLocLightSpecular = GetUniformLocation("u_light.specular"); + __uniformLocLightPosition = GetUniformLocation("u_light.position"); + __uniformLocLightDirection = GetUniformLocation("u_light.direction"); + __uniformLocLightExponent = GetUniformLocation("u_light.exponent"); + __uniformLocLightCutOff = GetUniformLocation("u_light.cutoff"); + __uniformLocLightAttenuation = GetUniformLocation("u_light.attenuation"); + + __uniformLocMaterialAmbient = GetUniformLocation("u_material.ambient"); + __uniformLocMaterialDiffuse = GetUniformLocation("u_material.diffuse"); + __uniformLocMaterialSpecular = GetUniformLocation("u_material.specular"); + __uniformLocMaterialEmissive = GetUniformLocation("u_material.emissive"); + __uniformLocMaterialShiness = GetUniformLocation("u_material.shiness"); + + glUseProgram(GetProgram()); + + glUniform1i(GetTexture2DUniformLocation(), 0); +} + +void +_GlLightShaderProgram::OnProgramReferenced(void) +{ + _GlShaderProgram::OnProgramReferenced(); + + glEnableVertexAttribArray(__attrLocationPosition); + glEnableVertexAttribArray(__attrLocationTextureCoordinates); + glEnableVertexAttribArray(__attrLocationColor); + glEnableVertexAttribArray(__attrLocationNormal); +} + +void +_GlLightShaderProgram::OnProgramDereferenced(void) +{ + _GlShaderProgram::OnProgramDereferenced(); + + glDisableVertexAttribArray(__attrLocationPosition); + glDisableVertexAttribArray(__attrLocationTextureCoordinates); + glDisableVertexAttribArray(__attrLocationColor); + glDisableVertexAttribArray(__attrLocationNormal); +} + }}} // Tizen::Ui::Animations diff --git a/src/ui/animations/FUiAnim_GlShaderProgram.h b/src/ui/animations/FUiAnim_GlShaderProgram.h index 23d5d10..3a05d2e 100644 --- a/src/ui/animations/FUiAnim_GlShaderProgram.h +++ b/src/ui/animations/FUiAnim_GlShaderProgram.h @@ -195,6 +195,55 @@ private: int __uniformLocationTexture2D; }; +class _GlLightShaderProgram + : public _GlShaderProgram +{ +public: + _GlLightShaderProgram(void); + virtual ~_GlLightShaderProgram(void); + + virtual void OnProgramCreated(void); + virtual void OnProgramReferenced(void); + virtual void OnProgramDereferenced(void); + + virtual int GetMVPUniformLocation(void) const { return __uniformLocationMVP; } + virtual int GetTexture2DUniformLocation(void) const { return __uniformLocationTexture2D; } + + virtual int GetPositionAttributeLocation(void) const { return __attrLocationPosition; } + virtual int GetTextureCoordinatesAttributeLocation(void) const { return __attrLocationTextureCoordinates; } + virtual int GetColorAttributeLocation(void) const { return __attrLocationColor; } + virtual int GetNormalAttributeLocation(void) const { return __attrLocationNormal; } + +private: + int __attrLocationPosition; + int __attrLocationTextureCoordinates; + int __attrLocationColor; + int __attrLocationNormal; + + int __uniformLocationMVP; + int __uniformLocationTexture2D; + +public: + int __uniformLocModelView; + int __uniformLocInvModelView; + + int __uniformLocLightType; + int __uniformLocLightAmbient; + int __uniformLocLightDiffuse; + int __uniformLocLightSpecular; + int __uniformLocLightPosition; + int __uniformLocLightDirection; + int __uniformLocLightExponent; + int __uniformLocLightCutOff; + int __uniformLocLightAttenuation; + + int __uniformLocMaterialAmbient; + int __uniformLocMaterialDiffuse; + int __uniformLocMaterialSpecular; + int __uniformLocMaterialEmissive; + int __uniformLocMaterialShiness; +}; + }}} //Tizen::Ui::Animations #endif //_FUI_ANIM_INTERNAL_GL_SHADER_PROGRAM_H_ diff --git a/src/ui/animations/platform/FUiAnim_GlContext.cpp b/src/ui/animations/platform/FUiAnim_GlContext.cpp index cda2445..12d84be 100644 --- a/src/ui/animations/platform/FUiAnim_GlContext.cpp +++ b/src/ui/animations/platform/FUiAnim_GlContext.cpp @@ -569,6 +569,7 @@ _GlContext::BuildShader(unsigned int type, const char* pShaderSource) char* infoLog = (char*)malloc(sizeof(char) * infoLen); glGetShaderInfoLog(shaderId, infoLen, NULL, infoLog); SysLog(NID_UI_ANIM, "Failed to compile shader - %s", infoLog); + PRINT("_GlContext::BuildShader: %s\n", infoLog); free(infoLog); } @@ -612,6 +613,7 @@ _GlContext::BuildShaderProgram(unsigned int vertexShader, unsigned int fragmentS char* infoLog = (char*)malloc(sizeof(char) * infoLen); glGetShaderInfoLog(programId, infoLen, NULL, infoLog); SysLog(NID_UI_ANIM, "Failed to link shader program- %s", infoLog); + PRINT("_GlContext::BuildShaderProgram: %s\n", infoLog); free(infoLog); } -- 2.7.4