[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    playground/games/astrododge
From:       Rivo Laks <rivolaks () hot ! ee>
Date:       2009-07-19 20:12:35
Message-ID: 1248034355.989767.4991.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 999450 by rivol:

Use pseudo-instancing tehnique (possibly invented by NVidia) to render objects. This avoids some matrix
  math on CPU and results in an impressive 35% performance increase (and more with lower detail level).

 M  +2 -2      data/shaders/material-object.frag  
 M  +0 -4      data/shaders/material-object.vert  
 M  +2 -2      data/shaders/material-ship.frag  
 M  +0 -4      data/shaders/material-ship.vert  
 M  +12 -1     data/shaders/render-ambient.vert  
 M  +15 -2     data/shaders/render-light.vert  
 M  +13 -9     src/gameview.cpp  


--- trunk/playground/games/astrododge/data/shaders/material-object.frag #999449:999450
@@ -2,7 +2,7 @@
 uniform sampler2D glossTexture;
 uniform sampler2D emissionTexture;
 
-varying vec3 toCamera;
+varying vec4 vertexEye;
 
 
 vec3 calculateMaterial(vec3 L, vec3 Lcolor, vec3 N)
@@ -15,7 +15,7 @@
 
     float NdotL = dot(N, L);
     vec3 R = 2.0 * NdotL * N - L;
-    vec3 V = normalize(toCamera);
+    vec3 V = normalize(-vertexEye.xyz);
     float spec = pow(max(dot(R, V), 0.0), specularity);
 
     return texColor * NdotL + specular*spec;
--- trunk/playground/games/astrododge/data/shaders/material-object.vert #999449:999450
@@ -1,8 +1,4 @@
-varying vec3 toCamera;
-
-
 void calculateMaterialVertex()
 {
     gl_TexCoord[0] = gl_MultiTexCoord0;
-    toCamera = -(gl_ModelViewMatrix * gl_Vertex).xyz;
 }
--- trunk/playground/games/astrododge/data/shaders/material-ship.frag #999449:999450
@@ -1,4 +1,4 @@
-varying vec3 toCamera;
+varying vec4 vertexEye;
 
 vec3 shipBaseColor = vec3(1.0, 0.8, 0.4);
 
@@ -11,7 +11,7 @@
 
     float NdotL = dot(N, L);
     vec3 R = 2.0 * NdotL * N - L;
-    vec3 V = normalize(toCamera);
+    vec3 V = normalize(-vertexEye.xyz);
     float spec = pow(max(dot(R, V), 0.0), specularity);
 
     return shipBaseColor * Lcolor * (NdotL * diffuse + spec * specular);
--- trunk/playground/games/astrododge/data/shaders/material-ship.vert #999449:999450
@@ -1,7 +1,3 @@
-varying vec3 toCamera;
-
-
 void calculateMaterialVertex()
 {
-    toCamera = -(gl_ModelViewMatrix * gl_Vertex).xyz;
 }
--- trunk/playground/games/astrododge/data/shaders/render-ambient.vert #999449:999450
@@ -1,4 +1,15 @@
+// Vertex coordinates in eye space
+varying vec4 vertexEye;
+
+
 void main()
 {
-    gl_Position = ftransform();
+    vec4 positionWorld;
+    positionWorld.x = dot(gl_MultiTexCoord1, gl_Vertex);
+    positionWorld.y = dot(gl_MultiTexCoord2, gl_Vertex);
+    positionWorld.z = dot(gl_MultiTexCoord3, gl_Vertex);
+    positionWorld.w = 1.0;
+
+    vertexEye = gl_ModelViewMatrix * positionWorld;
+    gl_Position = gl_ProjectionMatrix * vertexEye;
 }
--- trunk/playground/games/astrododge/data/shaders/render-light.vert #999449:999450
@@ -1,3 +1,5 @@
+// Vertex coordinates in eye space
+varying vec4 vertexEye;
 varying vec3 normal;
 
 
@@ -7,9 +9,20 @@
 
 void main()
 {
-    gl_Position = ftransform();
+    vec4 positionWorld;
+    positionWorld.x = dot(gl_MultiTexCoord1, gl_Vertex);
+    positionWorld.y = dot(gl_MultiTexCoord2, gl_Vertex);
+    positionWorld.z = dot(gl_MultiTexCoord3, gl_Vertex);
+    positionWorld.w = 1.0;
 
-    normal = gl_NormalMatrix * gl_Normal;
+    vertexEye = gl_ModelViewMatrix * positionWorld;
+    gl_Position = gl_ProjectionMatrix * vertexEye;
+
+    normal.x = dot(gl_MultiTexCoord1.xyz, gl_Normal);
+    normal.y = dot(gl_MultiTexCoord2.xyz, gl_Normal);
+    normal.z = dot(gl_MultiTexCoord3.xyz, gl_Normal);
+    normal = (gl_ModelViewMatrix * vec4(normal, 0.0)).xyz;
+
     calculateLightVertex();
     calculateMaterialVertex();
 }
--- trunk/playground/games/astrododge/src/gameview.cpp #999449:999450
@@ -252,19 +252,23 @@
         }
         activeTextures = newActiveTextures;
 
-        // Transform
-        glPushMatrix();
-        obj->openglTransform();
-        if (obj->modelScale() != 1.0f) {
-            glScalef(obj->modelScale(), obj->modelScale(), obj->modelScale());
-        }
+        // Use pseudo-instancing: instead of modifying the modelview matrix for each object, send
+        //  the info about object's position/rotation to the vertex shader in OpenGL persistent
+        //  attributes (in this case, unused texture coordinates). This simplifies matrix
+        //  calculations and offloads them to the GPU, gaining an impressive performance increase
+        //  of about 35% (and more with low-poly object models).
+        // Using ODE's code here isn't pretty of course, but it's a bit faster than adding an extra
+        //  method into GameObject.
+        const dReal* pos = dBodyGetPosition(obj->body);
+        const dReal* rot = dBodyGetRotation(obj->body);
+        float s = obj->modelScale();
+        glMultiTexCoord4f(GL_TEXTURE1, s*rot[0], s*rot[1], s*rot[2], pos[0]);
+        glMultiTexCoord4f(GL_TEXTURE2, s*rot[4], s*rot[5], s*rot[6], pos[1]);
+        glMultiTexCoord4f(GL_TEXTURE3, s*rot[8], s*rot[9], s*rot[10], pos[2]);
 
         // Render
         int faces = model->render(obj->radius, obj->position(), cameraPos, mDetailLevel);
         renderInfo->addBatch(faces);
-
-        // Un-transform
-        glPopMatrix();
     }
 
     for (int i = 0; i < activeTextures; i++) {
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic