From patchwork Thu Jul 21 12:36:31 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandros Frantzis X-Patchwork-Id: 3012 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 5BDB923F52 for ; Thu, 21 Jul 2011 12:44:49 +0000 (UTC) Received: from mail-qy0-f180.google.com (mail-qy0-f180.google.com [209.85.216.180]) by fiordland.canonical.com (Postfix) with ESMTP id 14A91A185A2 for ; Thu, 21 Jul 2011 12:44:48 +0000 (UTC) Received: by mail-qy0-f180.google.com with SMTP id 30so847148qyk.11 for ; Thu, 21 Jul 2011 05:44:48 -0700 (PDT) Received: by 10.229.217.3 with SMTP id hk3mr210746qcb.38.1311252288819; Thu, 21 Jul 2011 05:44:48 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.217.78 with SMTP id hl14cs139611qcb; Thu, 21 Jul 2011 05:44:48 -0700 (PDT) Received: by 10.216.167.81 with SMTP id h59mr492158wel.85.1311251795309; Thu, 21 Jul 2011 05:36:35 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com [91.189.90.139]) by mx.google.com with ESMTP id x14si2112575weq.139.2011.07.21.05.36.34; Thu, 21 Jul 2011 05:36:35 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) client-ip=91.189.90.139; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) smtp.mail=bounces@canonical.com Received: from loganberry.canonical.com ([91.189.90.37]) by adelie.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1QjsUT-0000D3-90 for ; Thu, 21 Jul 2011 12:36:33 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id B7E762EA03C for ; Thu, 21 Jul 2011 12:36:31 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glmark2 X-Launchpad-Branch: ~glmark2-dev/glmark2/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 25 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glmark2-dev/glmark2/trunk] Rev 25: Change advanced shader to use user-defined vertex attributes exclusively. Message-Id: <20110721123631.17019.10901.launchpad@loganberry.canonical.com> Date: Thu, 21 Jul 2011 12:36:31 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13475"; Instance="initZopeless config overlay" X-Launchpad-Hash: e1cd7b66b9c4a094153d81819851f31fc4f2dfe7 ------------------------------------------------------------ revno: 25 committer: Alexandros Frantzis timestamp: Fri 2010-07-09 12:48:40 +0300 message: Change advanced shader to use user-defined vertex attributes exclusively. Fix Shading Scene so that it work with the new shader. modified: data/shaders/light-advanced.frag data/shaders/light-advanced.vert sceneshading.cpp --- lp:glmark2 https://code.launchpad.net/~glmark2-dev/glmark2/trunk You are subscribed to branch lp:glmark2. To unsubscribe from this branch go to https://code.launchpad.net/~glmark2-dev/glmark2/trunk/+edit-subscription === modified file 'data/shaders/light-advanced.frag' --- data/shaders/light-advanced.frag 2010-07-08 09:08:36 +0000 +++ data/shaders/light-advanced.frag 2010-07-09 09:48:40 +0000 @@ -1,94 +1,31 @@ -// Make sure you remember to add the varying variables: -// varying vec3 Normal; -// varying vec3 Light; -// varying vec3 HalfVector; -// To the fragment shader so that we can read them in. - -// First off here, we have to make sure that our Normal -// has been normalized so to make sure, we are just going -// to normalize it with the line: -// Normal = normalize(Normal); - -// Next off we want to calculate our diffuse portion of -// the lighting. Now unlike the basic lighting tutorial, -// I am going to take into account the materials we have -// attached to the object, and the settings we have applied -// to our light. - -// Now for our diffuse portion of our equation we get the line: -// float Diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse * max(dot(Normal, Light),0.0); -// Now the variable gl_FrontMaterial.diffuse is the diffuse -// material we have assigned to the front face of our object, -// and to get the diffuse portion of our light, we call the -// variable gl_LightSource[0].diffuse. Then to take into account -// how intense this should be, we multiply it by: -// max(dot(Normal, Light),0.0) -// Which from our previous tutorial, we used to calculate how -// intense the light should be, using the angle of the surface -// compared to the position of the light. - -// Seeing as though we now have the diffuse part of our lighting -// we now need the Ambient term. In this term there are no real -// calculations like the dot product, used in the diffuse term. -// Here we are just taking values set inside our OpenGL program -// and applying them to our object. The variables that we need -// to use are: -// gl_FrontMaterial.ambient -// gl_LightSource[0].ambient -// gl_LightModel.ambient -// For our Ambient term to work, we need to multiply -// gl_FrontMaterial.ambient and gl_LightSource[0].ambient -// and then add the product of gl_LightModel.ambient and -// gl_FrontMaterial.ambient -// So our equation looks like: -// float Ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient; -// Ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient; - -// In this tutorial, I am not going to cover the emissive term -// that OpenGL supports (I will in a later tutorial), so I am -// going to jump straight to the most complicated term in the -// lighting equation. Which is the specular term. The reason -// that this term is the most complicated, is that it needs -// to find the reflection of the lighting from the surface of -// the object, to the 'camera'. The first part of the equation -// is similar to the start of the previous equations and takes -// the materials specular term, and the lights specular term -// and multiplies them together to look like: -// gl_FrontMaterial.specular * gl_LightSource[0].specular -// and then comes the tricky part, we need to multiply this by -// pow(max(dot(Normal,HalfVector),0.0), gl_FrontMaterial.shininess); -// This takes the dot product of our Normal and HalfVector, and as -// we have seen in the diffuse term, sets a max of 0.0 -// With the number we have just calculated, we need to raise that -// to the power of our shininess term set inside our OpenGL program. - -// Because we are using the halfVector at this stage, we don't need -// to use the reflect() expression, but we will when we get into -// normal mapping. - -// So in the end our specular expression looks like: -// float Specular = gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(max(dot(Normal,HalfVector),0.0), gl_FrontMaterial.shininess); - -// Now for the combining of all the expressions. We still need to -// multiply the diffuse term by the objects color. And with that -// we then need to add the Ambient term and the Specular term. -// So our final gl_FragColor call looks like: -// gl_FragColor = Ambient + (Diffuse * vec4(1,0,0,1)) + Specular; +uniform vec3 LightSourceAmbient; +uniform vec3 LightSourceDiffuse; +uniform vec3 LightSourceSpecular; +uniform vec3 MaterialAmbient; +uniform vec3 MaterialDiffuse; +uniform vec3 MaterialSpecular; varying vec3 Normal; varying vec3 Light; varying vec3 HalfVector; void main(void) -{ - vec3 N = normalize(Normal); - - vec4 Diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse * max(dot(N, Light),0.0); - - vec4 Ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient; - Ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient; - - vec4 Specular = gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(max(dot(Normal,HalfVector),0.0), gl_FrontMaterial.shininess); - - gl_FragColor = Ambient + (Diffuse * vec4(0,0,1,1)) + Specular; +{ + vec3 N = normalize(Normal); + vec3 L = normalize(Light); + vec3 H = normalize(HalfVector); + + // Calculate the diffuse color according to Lambertian reflectance + vec3 diffuse = MaterialDiffuse * LightSourceDiffuse * max(dot(N, L), 0.0); + + // Calculate the ambient color + vec3 ambient = MaterialAmbient * LightSourceAmbient; + + // Calculate the specular color according to the Blinn-Phong model + vec3 specular = MaterialSpecular * LightSourceSpecular * + pow(max(dot(N,H), 0.0), 100.0); + + // Calculate the final color + gl_FragColor = vec4(ambient, 1.0) + vec4(specular, 1.0) + + vec4(diffuse, 1.0) * vec4(0.0, 0.0, 1.0, 1.0); } === modified file 'data/shaders/light-advanced.vert' --- data/shaders/light-advanced.vert 2010-07-07 10:32:18 +0000 +++ data/shaders/light-advanced.vert 2010-07-09 09:48:40 +0000 @@ -1,39 +1,11 @@ -// First off, I am going to explain a little thing -// with shaders, that will help you to optimize them -// in the future. Vertex shaders are called for every -// vertex passed through, and Fragment shaders are -// called for every pixel on the screen. Because of this -// it is wise to do as many calculations in the vertex -// shader as possible, as they are called less, and if -// the calculation does not need to be called on a per -// pixel basis, why do it? - -// Now as for the tutorial, you will see that I have -// removed the variable Diffuse from our vertex shader. -// This is because we are now going to calculate that in -// the fragment shader so we can get per pixel lighting. - -// In our vertex shader, I have added the varying variables: -// varying vec3 Normal; -// varying vec3 Light; -// varying vec3 HalfVector; -// These hold the surface normal of our vertex, the direction -// vector of the light source, and the half vector of the -// light source (you may want to look into the maths behind -// lighting, I may add something in the maths section at a -// later date). - -// These variables are going to be calculated here, and passed -// through to our fragment shader. This is because these variables -// will not change, so there is no need calculating them on a -// per pixel basis. - -// Now that we have these variables, we need to calculate them. -// Our Normal and Light variables stay exactly the same -// as in the previous tutorial. The only new one is the HalfVector -// which is called similar to our Light variable, just replace -// position with halfVector, and we get the light sources half -// vector supplied by OpenGL. +attribute vec3 position; +attribute vec3 normal; +attribute vec2 texture; + +uniform mat4 ModelViewProjectionMatrix; +uniform mat4 NormalMatrix; +uniform vec4 LightSourcePosition; +uniform vec3 LightSourceHalfVector; varying vec3 Normal; varying vec3 Light; @@ -41,11 +13,16 @@ void main(void) { - Normal = normalize(gl_NormalMatrix * gl_Normal); - - Light = normalize(gl_LightSource[0].position.xyz); - - HalfVector = normalize(gl_LightSource[0].halfVector.xyz); - - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; -} \ No newline at end of file + // Transform the normal to eye coordinates + Normal = normalize(vec3(NormalMatrix * vec4(normal, 1.0))); + + // The LightSourcePosition is actually its direction for directional light + Light = normalize(LightSourcePosition.xyz); + + // The HalfVector is used in the Blinn-Phong shading model for calculating + // specular lighting. + HalfVector = normalize(LightSourceHalfVector); + + // Transform the position to clip coordinates + gl_Position = ModelViewProjectionMatrix * vec4(position, 1.0); +} === modified file 'sceneshading.cpp' --- sceneshading.cpp 2010-07-08 15:17:11 +0000 +++ sceneshading.cpp 2010-07-09 09:48:40 +0000 @@ -49,26 +49,14 @@ void SceneShading::start() { - GLfloat lightAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f}; + GLfloat lightAmbient[] = {0.1f, 0.1f, 0.1f, 1.0f}; GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f}; + GLfloat lightSpecular[] = {0.8f, 0.8f, 0.8f, 1.0f}; GLfloat lightPosition[] = {20.0f, 20.0f, 10.0f, 1.0f}; - float no_mat[] = {0.0f, 0.0f, 0.0f, 1.0f}; - float mat_diffuse[] = {0.1f, 0.5f, 0.8f, 1.0f}; + float mat_ambient[] = {1.0f, 1.0f, 1.0f, 1.0f}; + float mat_diffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; float mat_specular[] = {1.0f, 1.0f, 1.0f, 1.0f}; - float high_shininess = 100.0f; - - glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat); - glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); - glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); - glMaterialf(GL_FRONT, GL_SHININESS, high_shininess); - glMaterialfv(GL_FRONT, GL_EMISSION, no_mat); - - glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); - glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHTING); switch(mCurrentPart) { @@ -82,15 +70,24 @@ break; } - if (mCurrentPart == 0) { - glUniform4fv(mShader[mCurrentPart].mLocations.LightSourcePosition, 1, - lightPosition); - glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceDiffuse, 1, - lightDiffuse); - glUniform3fv(mShader[mCurrentPart].mLocations.MaterialDiffuse, 1, - mat_diffuse); - } - + // Load lighting and material uniforms + glUniform4fv(mShader[mCurrentPart].mLocations.LightSourcePosition, 1, lightPosition); + + glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceAmbient, 1, lightAmbient); + glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceDiffuse, 1, lightDiffuse); + glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceSpecular, 1, lightSpecular); + + glUniform3fv(mShader[mCurrentPart].mLocations.MaterialAmbient, 1, mat_ambient); + glUniform3fv(mShader[mCurrentPart].mLocations.MaterialDiffuse, 1, mat_diffuse); + glUniform3fv(mShader[mCurrentPart].mLocations.MaterialSpecular, 1, mat_specular); + + // Calculate and load the half vector + Vector3f halfVector = Vector3f(lightPosition[0], lightPosition[1], lightPosition[2]); + halfVector.normalize(); + halfVector += Vector3f(0.0, 0.0, 1.0); + halfVector.normalize(); + glUniform3fv(mShader[mCurrentPart].mLocations.LightSourceHalfVector, 1, + (GLfloat *)&halfVector); mCurrentFrame = 0; mRunning = true; @@ -134,32 +131,22 @@ void SceneShading::draw() { - glTranslatef(0.0f, 0.0f,-5.0f); - glRotated(mRotation, 0.0f, 1.0, 0.0f); - - glColor3f(0.0f, 1.0f, 1.0f); - - if (mCurrentPart == 0) { - // Load the ModelViewProjectionMatrix uniform in the shader - Matrix4f model_view(1.0f, 1.0f, 1.0f); - Matrix4f model_view_proj(mScreen.mProjection); - - model_view.translate(0.0f, 0.0f, -5.0f); - model_view.rotate(2 * M_PI * mRotation / 360.0, 0.0f, 1.0f, 0.0f); - model_view_proj *= model_view; - - glUniformMatrix4fv(mShader[mCurrentPart].mLocations.ModelViewProjectionMatrix, 1, - GL_FALSE, model_view_proj.m); - - // Load the NormalMatrix uniform in the shader - // The NormalMatrix is the inverse transpose of the model view matrix. - model_view.invert().transpose(); - glUniformMatrix4fv(mShader[mCurrentPart].mLocations.NormalMatrix, 1, - GL_FALSE, model_view.m); - - mMesh.render_vbo_attrib(); - } - else { - mMesh.render_vbo(); - } + // Load the ModelViewProjectionMatrix uniform in the shader + Matrix4f model_view(1.0f, 1.0f, 1.0f); + Matrix4f model_view_proj(mScreen.mProjection); + + model_view.translate(0.0f, 0.0f, -5.0f); + model_view.rotate(2 * M_PI * mRotation / 360.0, 0.0f, 1.0f, 0.0f); + model_view_proj *= model_view; + + glUniformMatrix4fv(mShader[mCurrentPart].mLocations.ModelViewProjectionMatrix, 1, + GL_FALSE, model_view_proj.m); + + // Load the NormalMatrix uniform in the shader. The NormalMatrix is the + // inverse transpose of the model view matrix. + model_view.invert().transpose(); + glUniformMatrix4fv(mShader[mCurrentPart].mLocations.NormalMatrix, 1, + GL_FALSE, model_view.m); + + mMesh.render_vbo_attrib(); }