#include "timer.h" #include #include typedef struct vector_t { float x, y, z, w; } vector4 __attribute__((aligned(16))); typedef struct Colour_t { int x, y, z, w; } Colour __attribute__((aligned(16))); // Lighting constants #define AMBIENT_BRIGHTNESS 0.2f // Lighting components #define SPECULAR_COMPONENT 0.9f #define DIFFUSE0_COMPONENT 0.7f #define DIFFUSE1_COMPONENT 0.7f #define ENABLE_SPECULAR_LIGHTING // The position of the light in screen sapce ( calculated before drawing the patch ) static vector4 light0DirectionTransformed = { 1.0, 0.0, 0.0, 0.0 }; static vector4 light1DirectionTransformed = { 1.0, 1.0, 0.0, 0.0 }; inline vector4 crossproduct(vector4 a, vector4 b) { vector4 r; r.x = (a.y * b.z) - (b.y * a.z); r.y = (a.z * b.x) - (b.z * a.x); r.z = (a.x * b.y) - (b.x * a.y); r.w = 0; return r; } inline float dotproduct(vector4 a, vector4 b) { return (a.x*b.x) + (a.y*b.y) + (a.z*b.z); } inline float length(vector4 v) { return (v.x * v.x) + (v.y * v.y) + (v.z * v.z); } inline vector4 normalise ( vector4 a ) { float len = length ( a ); a.x /= len; a.y /= len; a.z /= len; a.w /= len; return a; } // Calculates a lit Colour based on a given normal and // the Colour of the object Colour CalculateColour ( vector4 ColourBase, vector4 position, vector4 normal ) { float diffuse, specular, normaldotLight; vector4 lightToPos, reflection; Colour c; // Light1 // Calculate diffuse lighting diffuse = ( dotproduct ( normal, light1DirectionTransformed ) * DIFFUSE1_COMPONENT ); if ( diffuse < 0 ) diffuse = 0; // Light0 normaldotLight = dotproduct ( normal, light0DirectionTransformed ); // Calculate diffuse lighting diffuse += ( normaldotLight * DIFFUSE0_COMPONENT ); if ( diffuse < 0 ) diffuse = 0; // Calculate the specular lighting #ifdef ENABLE_SPECULAR_LIGHTING // Calculate the point's position relative to the camera position = normalise ( position ); // Reflect the direction from camera to the point using the vertex normal reflection.x = light0DirectionTransformed.x - 2 * normaldotLight * normal.x; reflection.y = light0DirectionTransformed.y - 2 * normaldotLight * normal.y; reflection.z = light0DirectionTransformed.z - 2 * normaldotLight * normal.z; reflection.w = light0DirectionTransformed.w - 2 * normaldotLight * normal.w; // calculate the strength of the specular lighting for the light specular = dotproduct ( reflection, position ); if ( specular < 0 ) specular = 0; specular = specular * specular; specular = specular * specular; specular = specular * specular; specular = specular * specular; diffuse += SPECULAR_COMPONENT * specular; #endif // ENABLE_SPECULAR_LIGHTING // Set the maximum as 1 diffuse = diffuse; // Set minimum as ambient if ( diffuse < AMBIENT_BRIGHTNESS ) diffuse = AMBIENT_BRIGHTNESS; // Scale the colour apropriately c.x = ColourBase.x * diffuse; c.y = ColourBase.y * diffuse; c.z = ColourBase.z * diffuse; c.w = ColourBase.w * diffuse; return c; } static vector4 red = { 1.0, 0.0, 0.0, 0.0 }; Colour dostuff ( vector4 a, vector4 b, vector4 c ) { vector4 da, db, normal; da.x = a.x - b.x; da.y = a.y - b.y; da.z = a.z - b.z; da.w = a.w - b.w; db.x = c.x - b.x; db.y = c.y - b.y; db.z = c.z - b.z; db.w = c.w - b.w; normal = crossproduct ( da, db ); return CalculateColour ( red, a, normal ); } #define SIZE 2000000 vector4 vec[SIZE]; int main ( ) { unsigned a; for ( a = 0; a < SIZE; a++ ) { vec[a].x = ((float)a)/SIZE; vec[a].y = -((float)a)/SIZE; vec[a].z = ((float)a)/SIZE; vec[a].w = 1.0; } START_TIMER ( ); for ( a = 0; a < SIZE-3; a++ ) { CalculateColour ( red, vec[a], vec[a+1] ); // dostuff ( vec[a], vec[a+1], vec[a+2] ); } STOP_TIMER ( ); return 0; }