From patchwork Thu Jul 21 12:36:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexandros Frantzis X-Patchwork-Id: 2910 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 357B023F4D for ; Thu, 21 Jul 2011 12:36:43 +0000 (UTC) Received: from mail-qw0-f52.google.com (mail-qw0-f52.google.com [209.85.216.52]) by fiordland.canonical.com (Postfix) with ESMTP id 9F855A18287 for ; Thu, 21 Jul 2011 12:36:42 +0000 (UTC) Received: by mail-qw0-f52.google.com with SMTP id 8so850361qwb.11 for ; Thu, 21 Jul 2011 05:36:42 -0700 (PDT) Received: by 10.229.25.212 with SMTP id a20mr168918qcc.148.1311251802345; Thu, 21 Jul 2011 05:36:42 -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 hl14cs139332qcb; Thu, 21 Jul 2011 05:36:41 -0700 (PDT) Received: by 10.213.2.83 with SMTP id 19mr311059ebi.4.1311251794298; Thu, 21 Jul 2011 05:36:34 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com [91.189.90.139]) by mx.google.com with ESMTP id t4si872694wec.69.2011.07.21.05.36.33; Thu, 21 Jul 2011 05:36:34 -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 1QjsUS-0000DB-55 for ; Thu, 21 Jul 2011 12:36:32 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id D3EFB2E890D for ; Thu, 21 Jul 2011 12:36:29 +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: 1 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glmark2-dev/glmark2/trunk] Rev 1: Initial release of original OpenGL code. Message-Id: <20110721123629.17019.49876.launchpad@loganberry.canonical.com> Date: Thu, 21 Jul 2011 12:36:29 -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: 2159b566c349a545bc76ae29220435dd46bb689f ------------------------------------------------------------ revno: 1 committer: Alexandros Frantzis timestamp: Wed 2010-07-07 13:32:18 +0300 message: Initial release of original OpenGL code. added: data/ data/models/ data/models/cat.3ds data/models/cube.3ds data/models/horse.3ds data/shaders/ data/shaders/light-advanced.frag data/shaders/light-advanced.vert data/shaders/light-basic.frag data/shaders/light-basic.vert data/textures/ data/textures/crate-base.bmp main.cpp makefile mesh.cpp mesh.h model.cpp model.h oglsdl.h readme release scene.cpp scene.h scenebuild.cpp sceneshading.cpp scenetexture.cpp screen.cpp screen.h shader.cpp shader.h texture.cpp texture.h vector.cpp vector.h --- 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 === added directory 'data' === added directory 'data/models' === added file 'data/models/cat.3ds' Binary files data/models/cat.3ds 1970-01-01 00:00:00 +0000 and data/models/cat.3ds 2010-07-07 10:32:18 +0000 differ === added file 'data/models/cube.3ds' Binary files data/models/cube.3ds 1970-01-01 00:00:00 +0000 and data/models/cube.3ds 2010-07-07 10:32:18 +0000 differ === added file 'data/models/horse.3ds' Binary files data/models/horse.3ds 1970-01-01 00:00:00 +0000 and data/models/horse.3ds 2010-07-07 10:32:18 +0000 differ === added directory 'data/shaders' === added file 'data/shaders/light-advanced.frag' --- data/shaders/light-advanced.frag 1970-01-01 00:00:00 +0000 +++ data/shaders/light-advanced.frag 2010-07-07 10:32:18 +0000 @@ -0,0 +1,94 @@ +// 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; + +varying vec3 Normal; +varying vec3 Light; +varying vec3 HalfVector; + +void main(void) +{ + Normal = normalize(Normal); + + float Diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse * max(dot(Normal, Light),0.0); + + float Ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient; + Ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient; + + float Specular = gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(max(dot(Normal,HalfVector),0.0), gl_FrontMaterial.shininess); + + gl_FragColor = Ambient + (Diffuse * vec4(1,0,0,1)) + Specular; +} === added file 'data/shaders/light-advanced.vert' --- data/shaders/light-advanced.vert 1970-01-01 00:00:00 +0000 +++ data/shaders/light-advanced.vert 2010-07-07 10:32:18 +0000 @@ -0,0 +1,51 @@ +// 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. + +varying vec3 Normal; +varying vec3 Light; +varying vec3 HalfVector; + +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 === added file 'data/shaders/light-basic.frag' --- data/shaders/light-basic.frag 1970-01-01 00:00:00 +0000 +++ data/shaders/light-basic.frag 2010-07-07 10:32:18 +0000 @@ -0,0 +1,24 @@ +// Because we are using the varying float Diffuse in +// our vertex shader, if we wish to read it in here, we +// need to set the same variable, so I have done this +// first. + +// After that, I am simply changing the line: +// gl_FragColor = vec4(0,0,1,1) +// to +// gl_FragColor = Diffuse * vec4(0,0,1,1); +// This multiplies the intensity of the light by the +// color we originally set the cube to. + +// This can or cannot eliminate the need for materials, +// depending on your needs, but just for the record +// (and future tutorials), materials are worth while +// and can be read from inside GLSL :) + +varying float Diffuse; + +void main(void) +{ +//Multiply the light Diffuse intensity by the color of the cube + gl_FragColor = Diffuse * vec4(0,0,1,1); +} === added file 'data/shaders/light-basic.vert' --- data/shaders/light-basic.vert 1970-01-01 00:00:00 +0000 +++ data/shaders/light-basic.vert 2010-07-07 10:32:18 +0000 @@ -0,0 +1,72 @@ +// For this tutorial, I am going show you how to perform per +// vertex lighting using shaders. Yes, shaders support per pixel +// but this is just a starting point. + +// First I am going to teach you about varying variables. These +// are variables that can be shared between the vertex and fragment +// shaders. These variables are set inside the vertex shader, and +// then read from the fragment shader. In this case we are going +// to share a float type variable from the Vertex shader to the +// Fragment shader. This variable is going to be called Diffuse +// and will hold a number that will tell us how lit our vertex +// should be. + +// Because we are using per vertex lighting, the GLSL shader will +// automatically interpolate the color between the vertices. Just +// like OpenGL does. + +// Now first off we need to know the surface normal of the current +// vertex. Because I am using a GLUT cube, these are already +// calculated and sent off with the glNormal command. Any numbers +// sent from OpenGL through glNormal(1,2,3); can be read with +// the variable gl_Normal. In later tutorials, I will be using +// self calculated normals, using my own normal generation code. + +// Now as for our normal, I am storing it in the variable vec3 Normal. +// But first, I have to multiply the surface normal (gl_Normal) by +// the gl_NormalMatrix. This places the normal in coordinates that +// we can use. (Later on I will show you how to use tangent space +// normals). We also then have to normalize this multiplication so +// that all of the normal vectors are between (and including) -1 and 1. +// This makes sure that we have no scaling errors. + +// Next on, we are going to work with our light. I am storing this +// in a variable called vec3 Light. In this, I am calling for the +// position of glLight0. This is gathered by the call: +// gl_LightSource[0].position.xyz +// This gives us the position of glLight0, and to get the position of +// any other light, we just change the number 0 to the light number we +// are after. We do not need to multiply this expression by the +// gl_NormalMatrix, but we do have to normalize it still. + +// Now that we have our surface Normal and the position of our Light. +// We can now calculate the Diffuse value of our lighting at the +// given vertex. To do this we need to take the dot product of both +// the Normal and the Light together. If you have any idea on +// calculating Normals, then you should have a fair idea of what the +// dot product does. It works as such: +// dot(a,b) = (x1 * x2) + (y1 * y2) + (z1 * z3) +// If this happens to be equal to 0, then the vectors a and b are +// perpendicular (the light meets the surface at a 90 degree angle). +// Because this point is when the light is at its brightest, we need +// to set the maximum value for our diffuse value to 0.0. +// So our Diffuse equation becomes: +// Diffuse = max(dot(Normal, Light),0.0); + +// And from that, we have now calculated the intensity of the light +// at the given vertex. That started to turn into a bit of a maths +// lesson, but it even cleared up some stuff for me without even +// thinking about it. GO MATHS :) + +varying float Diffuse; + +void main(void) +{ + Normal = normalize(gl_NormalMatrix * gl_Normal); + + Light = normalize(gl_LightSource[0].position.xyz); + + Diffuse = max(dot(Normal, Light),0.0); + + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; +} \ No newline at end of file === added directory 'data/textures' === added file 'data/textures/crate-base.bmp' Binary files data/textures/crate-base.bmp 1970-01-01 00:00:00 +0000 and data/textures/crate-base.bmp 2010-07-07 10:32:18 +0000 differ === added file 'main.cpp' --- main.cpp 1970-01-01 00:00:00 +0000 +++ main.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,106 @@ +#include "oglsdl.h" + +#include "screen.h" +#include "scene.h" + +int main(int argc, char *argv[]) +{ + SDL_Event event; + int running = 1; + unsigned current_scene = 0; + Screen screen; + + SceneBuild scenebuild; + SceneTexture scenetexture; + SceneShading sceneshading; + + printf("===================================================\n"); + printf(" GLMark 08\n"); + printf("===================================================\n"); + + printf("Enter screen width: "); + scanf("%d", &screen.mWidth); + printf("Enter screen height: "); + scanf("%d", &screen.mHeight); + printf("Enter screen bpp: "); + scanf("%d", &screen.mBpp); + printf("Enter '1' for fullscreen '0' for windowed: "); + scanf("%d", &screen.mFullScreen); + + + printf("===================================================\n"); + if(!screen.init()) + return 0; + printf("===================================================\n"); + + if(!scenebuild.load() || !scenetexture.load() || !sceneshading.load()) + return 0; + + while(running) + { + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_QUIT: + running = 0; + break; + case SDL_KEYDOWN: + if(event.key.keysym.sym == SDLK_ESCAPE) + running = 0; + break; + } + } + + screen.clear(); + + switch(current_scene) + { + case 0: + current_scene++; + scenebuild.start(); +// scenebuild.mRunning = false; + break; + case 1: + scenebuild.update(); + scenebuild.draw(); + if(!scenebuild.mRunning) + { + current_scene++; + scenetexture.start(); +// scenetexture.mRunning = false; + } + break; + case 2: + scenetexture.update(); + scenetexture.draw(); + if(!scenetexture.mRunning) + { + current_scene++; + sceneshading.start(); +// sceneshading.mRunning = false; + } + break; + case 3: + sceneshading.update(); + sceneshading.draw(); + if(!sceneshading.mRunning) + running = false; + break; + } + + screen.update(); + } + + scenebuild.calculate_score(); + scenetexture.calculate_score(); + sceneshading.calculate_score(); + + unsigned score = scenebuild.mScore + scenetexture.mScore + sceneshading.mScore; + + printf("===================================================\n"); + printf("Your GLMark08 Score is %u ^_^\n", score); + printf("===================================================\n"); + + return 0; +} === added file 'makefile' --- makefile 1970-01-01 00:00:00 +0000 +++ makefile 2010-07-07 10:32:18 +0000 @@ -0,0 +1,2 @@ +all: + g++ *.cpp -o glmark -Wall -lSDL -lGL -lGLU -lGLEW === added file 'mesh.cpp' --- mesh.cpp 1970-01-01 00:00:00 +0000 +++ mesh.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,240 @@ +#include "mesh.h" + +Texel::Texel() +{ + u = 0; v = 0; +} + +Texel::Texel(GLfloat pU, GLfloat pV) +{ + u = pU; v = pV; +} + +Mesh::Mesh() +{ + mPolygonQty = 0; + mVertexQty = 0; + mMode = GL_QUADS; + mVertex = 0; +} + +Mesh::~Mesh() +{ + delete [] mVertex; + glDeleteLists(1, mBuildList); + //deleteArray +} + +void Mesh::make_cube() +{ + mPolygonQty = 6; + mVertexQty = 4 * mPolygonQty; + mMode = GL_QUADS; + mVertex = new Vertex[mVertexQty]; + + mVertex[0].v = Vector3f( 1.0f, 1.0f,-1.0f); + mVertex[1].v = Vector3f(-1.0f, 1.0f,-1.0f); + mVertex[2].v = Vector3f(-1.0f, 1.0f, 1.0f); + mVertex[3].v = Vector3f( 1.0f, 1.0f, 1.0f); + + mVertex[4].v = Vector3f( 1.0f,-1.0f, 1.0f); + mVertex[5].v = Vector3f(-1.0f,-1.0f, 1.0f); + mVertex[6].v = Vector3f(-1.0f,-1.0f,-1.0f); + mVertex[7].v = Vector3f( 1.0f,-1.0f,-1.0f); + + mVertex[8].v = Vector3f( 1.0f, 1.0f, 1.0f); + mVertex[9].v = Vector3f(-1.0f, 1.0f, 1.0f); + mVertex[10].v = Vector3f(-1.0f,-1.0f, 1.0f); + mVertex[11].v = Vector3f( 1.0f,-1.0f, 1.0f); + + mVertex[12].v = Vector3f( 1.0f,-1.0f,-1.0f); + mVertex[13].v = Vector3f(-1.0f,-1.0f,-1.0f); + mVertex[14].v = Vector3f(-1.0f, 1.0f,-1.0f); + mVertex[15].v = Vector3f( 1.0f, 1.0f,-1.0f); + + mVertex[16].v = Vector3f(-1.0f, 1.0f, 1.0f); + mVertex[17].v = Vector3f(-1.0f, 1.0f,-1.0f); + mVertex[18].v = Vector3f(-1.0f,-1.0f,-1.0f); + mVertex[19].v = Vector3f(-1.0f,-1.0f, 1.0f); + + mVertex[20].v = Vector3f(-1.0f, 1.0f, 1.0f); + mVertex[21].v = Vector3f(-1.0f, 1.0f,-1.0f); + mVertex[22].v = Vector3f(-1.0f,-1.0f,-1.0f); + mVertex[23].v = Vector3f(-1.0f,-1.0f, 1.0f); + + for(unsigned i = 0; i < mVertexQty / 4; i += 4) + { + Vector3f n; + n = normal(mVertex[i].v, mVertex[i + 1].v, mVertex[i + 2].v); + for(unsigned j = 0; j < 4; j++) + mVertex[i + j].n = n; + mVertex[i + 0].t = Texel(0.0f, 0.0f); + mVertex[i + 1].t = Texel(1.0f, 0.0f); + mVertex[i + 2].t = Texel(1.0f, 1.0f); + mVertex[i + 3].t = Texel(0.0f, 1.0f); + } +} + +void Mesh::make_torus() +{ + unsigned wraps_qty = 64; + unsigned per_wrap_qty = 64; + float major_radius = 0.8; + float minor_radius = 0.4; + unsigned i, j; + unsigned k = 0; + + Vector3f a, b, c, d, n; + + mMode = GL_TRIANGLES; + mVertexQty = wraps_qty * per_wrap_qty * 6; + mVertex = new Vertex[mVertexQty]; + + for(i = 0; i < wraps_qty; i++) + for(j = 0; j < per_wrap_qty; j++) + { + float wrap_frac = j / (float)per_wrap_qty; + float phi = 2 * M_PI * wrap_frac; + float theta = 2 * M_PI * (i + wrap_frac) / (float)wraps_qty; + float r = major_radius + minor_radius * (float)cos(phi); + a.x = (float)sin(theta) * r; + a.y = minor_radius * (float)sin(phi); + a.z = (float)cos(theta) * r; + + theta = 2 * M_PI * (i + wrap_frac + 1) / (float)wraps_qty; + b.x = (float)sin(theta) * r; + b.y = minor_radius * (float)sin(phi); + b.z = (float)cos(theta) * r; + + wrap_frac = (j + 1) / (float)per_wrap_qty; + phi = 2 * M_PI * wrap_frac; + theta = 2 * M_PI * (i + wrap_frac) / (float)wraps_qty; + r = major_radius + minor_radius * (float)cos(phi); + c.x = (float)sin(theta) * r; + c.y = minor_radius * (float)sin(phi); + c.z = (float)cos(theta) * r; + + theta = 2 * M_PI * (i + wrap_frac + 1) / (float)wraps_qty; + d.x = (float)sin(theta) * r; + d.y = minor_radius * (float)sin(phi); + d.z = (float)cos(theta) * r; + + n = normal(a, b, c); + mVertex[k].n = n; mVertex[k].v = a; k++; + mVertex[k].n = n; mVertex[k].v = b; k++; + mVertex[k].n = n; mVertex[k].v = c; k++; + n = normal(a, b, c); + mVertex[k].n = n; mVertex[k].v = b; k++; + mVertex[k].n = n; mVertex[k].v = c; k++; + mVertex[k].n = n; mVertex[k].v = d; k++; + } +} + +void Mesh::render() +{ + glBegin(mMode); + glColor3f(1.0f, 0.0f, 0.0f); + for(unsigned i = 0; i < mVertexQty; i++) + { + glNormal3f(mVertex[i].n.x, mVertex[i].n.y, mVertex[i].n.z); + glTexCoord2f(mVertex[i].t.u, mVertex[i].t.v); + glVertex3f(mVertex[i].v.x, mVertex[i].v.y, mVertex[i].v.z); + } + glEnd(); +} + +void Mesh::render_array() +{ + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &mVertex[0].v.x); + glNormalPointer(GL_FLOAT, sizeof(Vertex), &mVertex[0].n.x); + glDrawArrays(mMode, 0, mVertexQty); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_NORMAL_ARRAY); +} + +void Mesh::build_list() +{ +#ifdef _DEBUG + printf("Building list for mesh... "); +#endif + + mBuildList = glGenLists(1); + glNewList(mBuildList, GL_COMPILE); + render(); + glEndList(); + +#ifdef _DEBUG + printf("[ Done ]\n"); +#endif +} + +void Mesh::build_vbo() +{ +#ifdef _DEBUG + printf("Building vbo for mesh... "); +#endif + + Vector3f *vertex; + Texel *texel; + Vector3f *normal; + + vertex = new Vector3f[mVertexQty]; + texel = new Texel[mVertexQty]; + normal = new Vector3f[mVertexQty]; + + for(unsigned i = 0; i < mVertexQty; i++) + { + vertex[i] = mVertex[i].v; + texel[i] = mVertex[i].t; + normal[i] = mVertex[i].n; + } + + // Generate And Bind The Vertex Buffer + glGenBuffersARB(1, &mVBOVertices); // Get A Valid Name + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVBOVertices); // Bind The Buffer + // Load The Data + glBufferDataARB(GL_ARRAY_BUFFER_ARB, mVertexQty * sizeof(Vector3f), vertex, GL_STATIC_DRAW_ARB); + + // Generate And Bind The normal Buffer + glGenBuffersARB(1, &mVBONormals); // Get A Valid Name + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVBONormals); // Bind The Buffer + // Load The Data + glBufferDataARB(GL_ARRAY_BUFFER_ARB, mVertexQty * sizeof(Vector3f), normal, GL_STATIC_DRAW_ARB); + + // Generate And Bind The Texture Coordinate Buffer + glGenBuffersARB(1, &mVBOTexCoords); // Get A Valid Name + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVBOTexCoords); // Bind The Buffer + // Load The Data + glBufferDataARB(GL_ARRAY_BUFFER_ARB, mVertexQty * sizeof(Texel), texel, GL_STATIC_DRAW_ARB); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + delete [] vertex; + delete [] texel; + delete [] normal; +#ifdef _DEBUG + printf("[ Done ]\n"); +#endif +} + +void Mesh::render_vbo() +{ + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVBONormals); + glNormalPointer(GL_FLOAT, 0, 0); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mVBOVertices); + glVertexPointer(3, GL_FLOAT, 0, 0); + + glDrawArrays(GL_TRIANGLES, 0, mVertexQty); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + + glDisableClientState(GL_NORMAL_ARRAY); + glDisableClientState(GL_VERTEX_ARRAY); +} === added file 'mesh.h' --- mesh.h 1970-01-01 00:00:00 +0000 +++ mesh.h 2010-07-07 10:32:18 +0000 @@ -0,0 +1,55 @@ +#ifndef _MESH_H +#define _MESH_H + +#include "screen.h" +#include "vector.h" + +#include +#include + +class Texel +{ +public: + GLfloat u, v; + + Texel(); + Texel(GLfloat pU, GLfloat pV); +}; + +class Vertex +{ +public: + Vector3f v; + Vector3f n; + Texel t; +}; + +// Data for a mesh to be rendered by vertex arrays' or vbos' has 3 verticies per +// polygon and no polygonal data +class Mesh +{ +public: + unsigned mVertexQty; // Quantity of Verticies + unsigned mPolygonQty; // Quantity of polygons, not really needed + GLenum mMode; // Polygon mode, eg GL_QUADS, GL_TRIANGLES etc... + Vertex *mVertex; // Storage for the verticies + + GLuint mBuildList; // Build list name + + GLuint mVBOVertices; // Vertex VBO name + GLuint mVBONormals; // Texture coordinate VBO name + GLuint mVBOTexCoords; // Texture coordinate VBO name + + Mesh(); // Default Constructor, should set pointers to null + ~Mesh(); + + void make_cube(); + void make_torus(); + void render(); + void render_array(); + void build_list(); + void build_vbo(); + void render_vbo(); +}; + +#endif === added file 'model.cpp' --- model.cpp 1970-01-01 00:00:00 +0000 +++ model.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,254 @@ +#include "model.h" + +long filelength(int f) +{ + struct stat buf; + fstat(f, &buf); + return(buf.st_size); +} + +Model::Model() +{ + mPolygonQty = 0; + mVertexQty = 0; + mVertex = 0; // Set pointer to null + mPolygon = 0; // Set pointer to null +} + +Model::~Model() +{ + delete [] mVertex; + delete [] mPolygon; +} + +void Model::convert_to_mesh(Mesh *pMesh) +{ +#ifdef _DEBUG + printf("Converting model to mesh... "); +#endif + pMesh->mVertexQty = 3 * mPolygonQty; + pMesh->mPolygonQty = mPolygonQty; + pMesh->mMode = GL_TRIANGLES; + + pMesh->mVertex = new Vertex[pMesh->mVertexQty]; + + for(unsigned i = 0; i < pMesh->mVertexQty; i += 3) + { + pMesh->mVertex[i + 0].v = mVertex[mPolygon[i / 3].mA].v; + pMesh->mVertex[i + 1].v = mVertex[mPolygon[i / 3].mB].v; + pMesh->mVertex[i + 2].v = mVertex[mPolygon[i / 3].mC].v; + + pMesh->mVertex[i + 0].n = mVertex[mPolygon[i / 3].mA].n; + pMesh->mVertex[i + 1].n = mVertex[mPolygon[i / 3].mB].n; + pMesh->mVertex[i + 2].n = mVertex[mPolygon[i / 3].mC].n; + + pMesh->mVertex[i + 0].t = mVertex[mPolygon[i / 3].mA].t; + pMesh->mVertex[i + 1].t = mVertex[mPolygon[i / 3].mB].t; + pMesh->mVertex[i + 2].t = mVertex[mPolygon[i / 3].mC].t; + } + +#ifdef _DEBUG + printf("[ Done ]\n"); +#endif +} + +void Model::calculate_normals() +{ +#ifdef _DEBUG + printf("Calculating normals for model... "); +#endif + Vector3f n; + + for(unsigned i = 0; i < mPolygonQty; i++) + { + n = normal(mVertex[mPolygon[i].mA].v, mVertex[mPolygon[i].mB].v, mVertex[mPolygon[i].mC].v); + mVertex[mPolygon[i].mA].n += n; + mVertex[mPolygon[i].mB].n += n; + mVertex[mPolygon[i].mC].n += n; + } + + for(unsigned i = 0; i < mVertexQty; i++) + mVertex[i].n.normalize(); + +#ifdef _DEBUG + printf("[ Done ]\n"); +#endif +} + +void Model::center() +{ + Vector3f center; + Vector3f max = mVertex[0].v, min = mVertex[0].v; + + for(unsigned i = 1; i < mVertexQty; i++) + { + if(mVertex[i].v.x > max.x) max.x = mVertex[i].v.x; + if(mVertex[i].v.y > max.y) max.y = mVertex[i].v.y; + if(mVertex[i].v.z > max.z) max.z = mVertex[i].v.z; + + if(mVertex[i].v.x < min.x) min.x = mVertex[i].v.x; + if(mVertex[i].v.y < min.y) min.y = mVertex[i].v.y; + if(mVertex[i].v.z < min.z) min.z = mVertex[i].v.z; + } + + center = (max + min) / 2.0f; + + for(unsigned i = 0; i < mVertexQty; i++) + mVertex[i].v -= center; +} + +void Model::scale(GLfloat pAmount) +{ + for(unsigned i = 1; i < mVertexQty; i++) + mVertex[i].v *= pAmount; +} + +int Model::load_3ds(const char *pFileName) +{ +#ifdef _DEBUG + printf("Loading model from 3ds file... "); +#endif + int i; //Index variable + + FILE *l_file; //File pointer + + unsigned short l_chunk_id; //Chunk identifier + unsigned int l_chunk_lenght; //Chunk lenght + + unsigned char l_char; //Char variable + unsigned short l_qty; //Number of elements in each chunk + + if ((l_file=fopen (pFileName, "rb"))== NULL) + { +#ifdef _DEBUG + printf("[ Fail ]\n"); +#else + printf("Could not open 3ds file\n"); +#endif + return 0; + } + + while (ftell (l_file) < filelength (fileno (l_file))) //Loop to scan the whole file + //while(!EOF) + { + //getch(); //Insert this command for debug (to wait for keypress for each chuck reading) + + fread (&l_chunk_id, 2, 1, l_file); //Read the chunk header + fread (&l_chunk_lenght, 4, 1, l_file); //Read the lenght of the chunk + + switch (l_chunk_id) + { + //----------------- MAIN3DS ----------------- + // Description: Main chunk, contains all the other chunks + // Chunk ID: 4d4d + // Chunk Lenght: 0 + sub chunks + //------------------------------------------- + case 0x4d4d: + break; + + //----------------- EDIT3DS ----------------- + // Description: 3D Editor chunk, objects layout info + // Chunk ID: 3d3d (hex) + // Chunk Lenght: 0 + sub chunks + //------------------------------------------- + case 0x3d3d: + break; + + //--------------- EDIT_OBJECT --------------- + // Description: Object block, info for each object + // Chunk ID: 4000 (hex) + // Chunk Lenght: len(object name) + sub chunks + //------------------------------------------- + case 0x4000: + i=0; + do + { + fread (&l_char, 1, 1, l_file); + mName[i] = l_char; + i++; + } while(l_char != '\0' && i<20); + break; + + //--------------- OBJ_TRIMESH --------------- + // Description: Triangular mesh, contains chunks for 3d mesh info + // Chunk ID: 4100 (hex) + // Chunk Lenght: 0 + sub chunks + //------------------------------------------- + case 0x4100: + break; + + //--------------- TRI_VERTEXL --------------- + // Description: Vertices list + // Chunk ID: 4110 (hex) + // Chunk Lenght: 1 x unsigned short (number of vertices) + // + 3 x float (vertex coordinates) x (number of vertices) + // + sub chunks + //------------------------------------------- + case 0x4110: + fread (&l_qty, sizeof (unsigned short), 1, l_file); + mVertexQty = l_qty; + mVertex = new Vertex[mVertexQty]; + for (i=0; i +#include +#include + +class Polygon +{ +public: + unsigned short mA, mB, mC; + unsigned short mFaceFlags; +}; + +// A model as loaded from a 3ds file +class Model +{ +public: + unsigned mPolygonQty; + unsigned mVertexQty; + Vertex *mVertex; + Polygon *mPolygon; + char mName[20]; + + Model(); + ~Model(); + + int load_3ds(const char *pFileName); + void calculate_normals(); + void center(); + void scale(GLfloat pAmount); + void convert_to_mesh(Mesh *pMesh); +}; + +#endif === added file 'oglsdl.h' --- oglsdl.h 1970-01-01 00:00:00 +0000 +++ oglsdl.h 2010-07-07 10:32:18 +0000 @@ -0,0 +1,7 @@ +#ifndef _OGLSDL_H +#define _OGLSDL_H + +#include +#include + +#endif === added file 'readme' --- readme 1970-01-01 00:00:00 +0000 +++ readme 2010-07-07 10:32:18 +0000 @@ -0,0 +1,11 @@ +requires development libarays + sdl libsdl1.2-dev + gl libgl1-mesa-dev + glu libglu1-mesa-dev + glew libglew1.5-dev + +compile with + make + +execute with + ./glmark === added file 'release' --- release 1970-01-01 00:00:00 +0000 +++ release 2010-07-07 10:32:18 +0000 @@ -0,0 +1,51 @@ +GLMark 0.5.2 +======================== +- current tests + no precompilation + build lists + vertex arrays + vertex buffer objects + nearest texture filtering + linear texture filtering + mipmapped texture filtering + smooth shader model + glsl per vertex lighting + glsl per pixel lighting + +Updates 26-04-2008 +======================== +- Added GLSL shader tests +- Fixed some memory leaks +- Cleaned up the code a bit + +Updates 25-04-2008 +======================== +- Readded the texture filter test +- Improved score system + +Updates 24-04-2008 +======================== +- Completly rewritten source +- Now c++ +- 3dsloader +- vertex buffer objects +- havent done texture tests yet +- select any resolution, fullscreen or windowed + +Updates 20-04-2008 +======================== +- Selected color depth used instead of desktop depth +- Simple makefile included +- Torus model, which actually tests the different methods of precompilation + +Updates 19-04-2008 +======================== +- Tests now run for 30 seconds +- The score is calculated properly, thanks to Shuffle777. +- It is now possible to select resolution, color depth and fullscreen/windowed. + +Updates +======================== +- Tests now run for 60 seconds +- A score is calculated at the end of the benchmark, based on my computer +(I get exactly 5000) :). === added file 'scene.cpp' --- scene.cpp 1970-01-01 00:00:00 +0000 +++ scene.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,21 @@ +#include "scene.h" + +Scene::Scene() +{ +} + +Scene::~Scene() +{ + delete [] mPartDuration; + delete [] mAverageFPS; + delete [] mScoreScale; +} + +void Scene::calculate_score() +{ + mScore = 0; + for(unsigned i = 0; i < mPartsQty; i++) + mScore += mAverageFPS[i] * mScoreScale[i]; +} + + === added file 'scene.h' --- scene.h 1970-01-01 00:00:00 +0000 +++ scene.h 2010-07-07 10:32:18 +0000 @@ -0,0 +1,84 @@ +#ifndef _SCENE_H +#define _SCENE_H + +#include "oglsdl.h" + +#include "mesh.h" +#include "model.h" +#include "texture.h" +#include "shader.h" + +#include + +class Scene +{ +public: + Scene(); + ~Scene(); + + unsigned mPartsQty; // How many parts for the scene + unsigned mCurrentPart; // The current part being rendered + double *mPartDuration; // Duration per part in seconds + + double mLastTime, mCurrentTime, mDt; + unsigned mCurrentFrame; + bool mRunning; + + unsigned *mAverageFPS; // Average FPS per part + float *mScoreScale; + unsigned mScore; // Score + + void calculate_score(); + +protected: + double mStartTime; + double mElapsedTime; +}; + +class SceneBuild : public Scene +{ +public: + int load(); + void start(); + void update(); + void draw(); + + Mesh mMesh; + float mRotation; + float mRotationSpeed; +}; + +class SceneTexture : public Scene +{ +public: + int load(); + void start(); + void update(); + void draw(); + + ~SceneTexture(); + + Mesh mCubeMesh; + GLuint mTexture[3]; + Vector3f mRotation; + Vector3f mRotationSpeed; +}; + +class SceneShading : public Scene +{ +public: + int load(); + void start(); + void update(); + void draw(); + + ~SceneShading(); + + Shader mShader[2]; + + Mesh mMesh; + float mRotation; + float mRotationSpeed; +}; + +#endif === added file 'scenebuild.cpp' --- scenebuild.cpp 1970-01-01 00:00:00 +0000 +++ scenebuild.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,120 @@ +#include "scene.h" + +int SceneBuild::load() +{ + Model model; + + if(!model.load_3ds("data/models/horse.3ds")) + return 0; + + model.calculate_normals(); + model.convert_to_mesh(&mMesh); + + mMesh.build_list(); + mMesh.build_vbo(); + + mRotationSpeed = 36.0f; + + mRunning = false; + + mPartsQty = 4; + mPartDuration = new double[mPartsQty]; + mAverageFPS = new unsigned[mPartsQty]; + mScoreScale = new float[mPartsQty]; + + mScoreScale[0] = 1.898f; + mScoreScale[1] = 0.540f; + mScoreScale[2] = 0.488f; + mScoreScale[3] = 0.420f; + + mScore = 0; + + mPartDuration[0] = 10.0; + mPartDuration[1] = 10.0; + mPartDuration[2] = 10.0; + mPartDuration[3] = 10.0; + + mCurrentPart = 0; + + return 1; +} + +void SceneBuild::start() +{ + GLfloat lightAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f}; + GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f}; + GLfloat lightPosition[] = {20.0f, 20.0f, 10.0f, 1.0f}; + + glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHTING); + + mCurrentFrame = 0; + mRunning = true; + mStartTime = SDL_GetTicks() / 1000.0; + mLastTime = mStartTime; +} + +void SceneBuild::update() +{ + mCurrentTime = SDL_GetTicks() / 1000.0; + mDt = mCurrentTime - mLastTime; + mLastTime = mCurrentTime; + + mElapsedTime = mCurrentTime - mStartTime; + + if(mElapsedTime >= mPartDuration[mCurrentPart]) + { + mAverageFPS[mCurrentPart] = mCurrentFrame / mElapsedTime; + + switch(mCurrentPart) + { + case 0: + printf("Precompilation\n"); + printf(" No Precompilation FPS: %u\n", mAverageFPS[mCurrentPart]); + break; + case 1: + printf(" Build list FPS: %u\n", mAverageFPS[mCurrentPart]); + break; + case 2: + printf(" Vertex array FPS: %u\n", mAverageFPS[mCurrentPart]); + break; + case 3: + printf(" Vertex buffer object FPS: %u\n", mAverageFPS[mCurrentPart]); + break; + } + mScore += mAverageFPS[mCurrentPart]; + mCurrentPart++; + start(); + if(mCurrentPart >= mPartsQty) + mRunning = false; + } + + mRotation += mRotationSpeed * mDt; + + mCurrentFrame++; +} + +void SceneBuild::draw() +{ + glTranslatef(0.0f, 0.0f,-2.5f); + glRotated(mRotation, 0.0f, 1.0, 0.0f); + + glColor3f(0.0f, 1.0f, 1.0f); + switch(mCurrentPart) + { + case 0: + mMesh.render(); + break; + case 1: + glCallList(mMesh.mBuildList); + case 2: + mMesh.render_array(); + break; + case 3: + mMesh.render_vbo(); + break; + } +} === added file 'sceneshading.cpp' --- sceneshading.cpp 1970-01-01 00:00:00 +0000 +++ sceneshading.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,140 @@ +#include "scene.h" + +SceneShading::~SceneShading() +{ +} + +int SceneShading::load() +{ + Model model; + + if(!model.load_3ds("data/models/cat.3ds")) + return 0; + + model.calculate_normals(); + model.convert_to_mesh(&mMesh); + + mMesh.build_vbo(); + + mShader[0].load("data/shaders/light-basic.vert", "data/shaders/light-basic.frag"); + mShader[1].load("data/shaders/light-advanced.vert", "data/shaders/light-advanced.frag"); + + mRotationSpeed = 36.0f; + mRotation = 0.0f; + + mRunning = false; + + mPartsQty = 3; + mPartDuration = new double[mPartsQty]; + mAverageFPS = new unsigned[mPartsQty]; + mScoreScale = new float[mPartsQty]; + + mScoreScale[0] = 0.534f; + mScoreScale[1] = 0.532f; + mScoreScale[2] = 0.556f; + + mScore = 0; + + mPartDuration[0] = 10.0; + mPartDuration[1] = 10.0; + mPartDuration[2] = 10.0; + + mCurrentPart = 0; + + return 1; +} + +void SceneShading::start() +{ + GLfloat lightAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f}; + GLfloat lightDiffuse[] = {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_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); + + switch(mCurrentPart) + { + case 0: + glDisable(GL_TEXTURE_2D); + glShadeModel(GL_SMOOTH); + break; + case 1: + glDisable(GL_TEXTURE_2D); + mShader[0].use(); + break; + case 2: + glDisable(GL_TEXTURE_2D); + mShader[1].use(); + break; + }; + + mCurrentFrame = 0; + mRunning = true; + mStartTime = SDL_GetTicks() / 1000.0; + mLastTime = mStartTime; +} + +void SceneShading::update() +{ + mCurrentTime = SDL_GetTicks() / 1000.0; + mDt = mCurrentTime - mLastTime; + mLastTime = mCurrentTime; + + mElapsedTime = mCurrentTime - mStartTime; + + if(mElapsedTime >= mPartDuration[mCurrentPart]) + { + mAverageFPS[mCurrentPart] = mCurrentFrame / mElapsedTime; + + switch(mCurrentPart) + { + case 0: + printf("Shading\n"); + printf(" Smooth shader model FPS: %u\n", mAverageFPS[mCurrentPart]); + break; + case 1: + printf(" GLSL per vertex lighting FPS: %u\n", mAverageFPS[mCurrentPart]); + break; + case 2: + printf(" GLSL per pixel lighting FPS: %u\n", mAverageFPS[mCurrentPart]); + break; + } + mScore += mAverageFPS[mCurrentPart]; + mCurrentPart++; + start(); + if(mCurrentPart >= mPartsQty) + mRunning = false; + } + + mRotation += mRotationSpeed * mDt; + + mCurrentFrame++; +} + +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); + + mMesh.render_vbo(); +} + + + === added file 'scenetexture.cpp' --- scenetexture.cpp 1970-01-01 00:00:00 +0000 +++ scenetexture.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,127 @@ +#include "scene.h" + +SceneTexture::~SceneTexture() +{ + for(unsigned i = 0; i < 3; i++) + glDeleteTextures(1, &mTexture[i]); +} + +int SceneTexture::load() +{ + Model model; + + if(!model.load_3ds("data/models/cube.3ds")) + return 0; + + if(!load_texture("data/textures/crate-base.bmp", mTexture)) + return 0; + + model.calculate_normals(); + model.convert_to_mesh(&mCubeMesh); + mCubeMesh.build_list(); + + mRotationSpeed = Vector3f(36.0f, 36.0f, 36.0f); + + mRunning = false; + + mPartsQty = 3; + mPartDuration = new double[mPartsQty]; + mAverageFPS = new unsigned[mPartsQty]; + mScoreScale = new float[mPartsQty]; + + mScoreScale[0] = 0.471f; + mScoreScale[1] = 0.533f; + mScoreScale[2] = 0.405f; + + mScore = 0; + + mPartDuration[0] = 10.0; + mPartDuration[1] = 10.0; + mPartDuration[2] = 10.0; + + mCurrentPart = 0; + + return 1; +} + +void SceneTexture::start() +{ + GLfloat lightAmbient[] = {0.0f, 0.0f, 0.0f, 1.0f}; + GLfloat lightDiffuse[] = {0.8f, 0.8f, 0.8f, 1.0f}; + GLfloat lightPosition[] = {20.0f, 20.0f, 10.0f, 1.0f}; + + glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); + glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse); + glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); + glEnable(GL_LIGHT0); + + glEnable(GL_TEXTURE_2D); + + mCurrentFrame = 0; + mRunning = true; + mStartTime = SDL_GetTicks() / 1000.0; + mLastTime = mStartTime; +} + +void SceneTexture::update() +{ + mCurrentTime = SDL_GetTicks() / 1000.0; + mDt = mCurrentTime - mLastTime; + mLastTime = mCurrentTime; + + mElapsedTime = mCurrentTime - mStartTime; + + if(mElapsedTime >= mPartDuration[mCurrentPart]) + { + mAverageFPS[mCurrentPart] = mCurrentFrame / mElapsedTime; + + switch(mCurrentPart) + { + case 0: + printf("Texture filtering\n"); + printf(" Nearest FPS: %u\n", mAverageFPS[mCurrentPart]); + break; + case 1: + printf(" Linear FPS: %u\n", mAverageFPS[mCurrentPart]); + break; + case 2: + printf(" Mipmapped FPS: %u\n", mAverageFPS[mCurrentPart]); + break; + } + mScore += mAverageFPS[mCurrentPart]; + mCurrentPart++; + start(); + if(mCurrentPart >= mPartsQty) + mRunning = false; + } + + mRotation += mRotationSpeed * mDt; + + mCurrentFrame++; +} + +void SceneTexture::draw() +{ + glLoadIdentity(); + glColor3f(1.0f, 1.0f, 1.0f); + glTranslatef(0.0f, 0.0f, -4.0f); + + glRotatef(mRotation.x, 1.0f, 0.0f, 0.0f); + glRotatef(mRotation.y, 0.0f, 1.0f, 0.0f); + glRotatef(mRotation.z, 0.0f, 0.0f, 1.0f); + + switch(mCurrentPart) + { + case 0: + glBindTexture(GL_TEXTURE_2D, mTexture[0]); + glCallList(mCubeMesh.mBuildList); + break; + case 1: + glBindTexture(GL_TEXTURE_2D, mTexture[1]); + glCallList(mCubeMesh.mBuildList); + case 2: + glBindTexture(GL_TEXTURE_2D, mTexture[2]); + glCallList(mCubeMesh.mBuildList); + break; + } +} === added file 'screen.cpp' --- screen.cpp 1970-01-01 00:00:00 +0000 +++ screen.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,116 @@ +#include "screen.h" + +Screen::Screen() +{ + mWidth = 800; + mHeight = 600; + mBpp = 24; + mFlags = SDL_OPENGL; + mFullScreen = false; + + mInfo = SDL_GetVideoInfo(); +} + +Screen::~Screen() +{ + SDL_Quit(); +} + +Screen::Screen(int pWidth, int pHeight, int pBpp, int pFlags) +{ + mWidth = pWidth; + mHeight = pHeight; + mBpp = pBpp; + mFlags = SDL_OPENGL | pFlags; + + mInfo = SDL_GetVideoInfo(); +} + +int Screen::init() +{ +#ifdef _DEBUG + printf("Initializing Screen... "); +#endif + if(SDL_Init(SDL_INIT_VIDEO) < 0) + { + fprintf(stderr, "[ Fail ] - Video initialization failed: %s\n", SDL_GetError()); + return 0; + } + + if(mFullScreen) + mFlags = SDL_OPENGL | SDL_FULLSCREEN; + + mInfo = SDL_GetVideoInfo(); + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + if(SDL_SetVideoMode(mWidth, mHeight, mBpp, mFlags) == 0) + { + fprintf(stderr, "[ Fail ] - Video mode set failed: %s\n", SDL_GetError()); + return 0; + } + + SDL_WM_SetCaption("GLMark 08", NULL); + + GLenum err = glewInit(); + if(GLEW_OK != err) + { + fprintf(stderr, "[ Fail ] - Error: %s\n", glewGetErrorString(err)); + return 0; + } + + if(!GLEW_ARB_vertex_buffer_object) + { + fprintf(stderr, "[ Fail ] - VBO objects are not supported\n"); + return 0; + } + + glShadeModel(GL_SMOOTH); + glClearColor(0.0f, 0.0f, 0.0f, 0.5f); + glClearDepth(1.0f); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + glViewport(0, 0, mWidth, mHeight); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0, mWidth / (float)mHeight, 1.0, 1024.0); + glMatrixMode(GL_MODELVIEW); + + clear(); + +#ifdef _DEBUG + printf("[ Success ]\n"); +#endif + print_info(); + return 1; +} + +void Screen::clear() +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glLoadIdentity(); +} + +void Screen::update() +{ + SDL_GL_SwapBuffers(); +} + +void Screen::print_info() +{ + printf(" OpenGL Information\n"); + printf(" GL_VENDOR: %s\n", glGetString(GL_VENDOR)); + printf(" GL_RENDERER: %s\n", glGetString(GL_RENDERER)); + printf(" GL_VERSION: %s\n", glGetString(GL_VERSION)); +// printf("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS)); +} + === added file 'screen.h' --- screen.h 1970-01-01 00:00:00 +0000 +++ screen.h 2010-07-07 10:32:18 +0000 @@ -0,0 +1,29 @@ +#ifndef _SCREEN_H +#define _SCREEN_H + +#include "oglsdl.h" + +#include + +class Screen +{ +public: + const SDL_VideoInfo *mInfo; + + int mWidth; + int mHeight; + int mBpp; + int mFlags; + int mFullScreen; +// SDL_Surface *mScreen; + + Screen(); + ~Screen(); + Screen(int pWidth, int pHeight, int pBpp, int pFlags); + int init(); + void clear(); + void update(); + void print_info(); +}; + +#endif === added file 'shader.cpp' --- shader.cpp 1970-01-01 00:00:00 +0000 +++ shader.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,74 @@ +#include "shader.h" + +char *readShaderFile(const char *FileName) +{ + FILE *fp; + char *DATA = NULL; + + int flength = 0; + + fp = fopen(FileName,"rt"); + + fseek(fp, 0, SEEK_END); + + flength = ftell(fp); + + rewind(fp); + + + DATA = (char *)malloc(sizeof(char) * (flength+1)); + flength = fread(DATA, sizeof(char), flength, fp); + DATA[flength] = '\0'; + + fclose(fp); + + return DATA; +} + +Shader::~Shader() +{ + remove(); +} + +void Shader::load(const char *pVertexShaderFileName, const char *pFragmentShaderFileName) +{ + char *vertex_shader_source, *fragment_shader_source; + + mVertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER); + mFragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER); + + vertex_shader_source = readShaderFile(pVertexShaderFileName); + + fragment_shader_source = readShaderFile(pFragmentShaderFileName); + + const char *vs = vertex_shader_source; + const char *fs = fragment_shader_source; + + glShaderSourceARB(mVertexShader, 1, &vs, NULL); + glShaderSourceARB(mFragmentShader, 1, &fs, NULL); + + free(vertex_shader_source); + free(fragment_shader_source); + + glCompileShaderARB(mVertexShader); + glCompileShaderARB(mFragmentShader); + + mShaderProgram = glCreateProgramObjectARB(); + glAttachObjectARB(mShaderProgram, mFragmentShader); + glAttachObjectARB(mShaderProgram, mVertexShader); + + glLinkProgram(mShaderProgram); +} + +void Shader::use() +{ + glUseProgramObjectARB(mShaderProgram); +} + +void Shader::remove() +{ + glDetachObjectARB(mShaderProgram, mVertexShader); + glDetachObjectARB(mShaderProgram, mFragmentShader); + + glDeleteObjectARB(mShaderProgram); +} === added file 'shader.h' --- shader.h 1970-01-01 00:00:00 +0000 +++ shader.h 2010-07-07 10:32:18 +0000 @@ -0,0 +1,22 @@ +#ifndef _SHADER_H +#define _SHADER_H + +#include "oglsdl.h" + +#include +#include + +class Shader +{ +public: + ~Shader(); + void load(const char *pVertexShaderFileName, const char *pFragmentShaderFileName); + void remove(); + void use(); + + GLuint mVertexShader; + GLuint mFragmentShader; + int mShaderProgram; +}; + +#endif === added file 'texture.cpp' --- texture.cpp 1970-01-01 00:00:00 +0000 +++ texture.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,94 @@ +#include "texture.h" + +int load_texture(const char pFilename[], GLuint *pTexture) +{ + SDL_Surface *surface; + GLenum texture_format; + GLint nOfColors; + + if ((surface = SDL_LoadBMP(pFilename))) + { + if ((surface->w & (surface->w - 1)) != 0) + printf("warning: image.bmp's width is not a power of 2\n"); + + if ((surface->h & (surface->h - 1)) != 0) + printf("warning: image.bmp's height is not a power of 2\n"); + + nOfColors = surface->format->BytesPerPixel; + if (nOfColors == 4) + { + if (surface->format->Rmask == 0x000000ff) + texture_format = GL_RGBA; + else + texture_format = GL_BGRA; + } + else + { + if (nOfColors == 3) + { + if (surface->format->Rmask == 0x000000ff) + texture_format = GL_RGB; + else + texture_format = GL_BGR; + } + else + { + printf("warning: the image is not truecolor.. this will probably break\n"); + } + } + + glGenTextures(3, pTexture); + + // Create Nearest Filtered Texture + glBindTexture(GL_TEXTURE_2D, pTexture[0]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels); + + // Create Linear Filtered Texture + glBindTexture(GL_TEXTURE_2D, pTexture[1]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels); + + // Create MipMapped Texture + glBindTexture(GL_TEXTURE_2D, pTexture[2]); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST); + + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, surface->w, surface->h, texture_format, GL_UNSIGNED_BYTE, surface->pixels); + +/* + switch (filter) + { + case 0: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels); + break; + + case 1: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0, texture_format, GL_UNSIGNED_BYTE, surface->pixels); + break; + + case 2: + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); + gluBuild2DMipmaps(GL_TEXTURE_2D, 3, surface->w, surface->h, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels); + break; + } +*/ + } + else + { + fprintf(stderr, "SDL could not load image.bmp: %s\n", SDL_GetError()); + return 0; + } + + if (surface) + SDL_FreeSurface(surface); + + return 1; +} === added file 'texture.h' --- texture.h 1970-01-01 00:00:00 +0000 +++ texture.h 2010-07-07 10:32:18 +0000 @@ -0,0 +1,10 @@ +#ifndef _TEXTURE_H +#define _TEXTURE_H + +#include "oglsdl.h" + +#include + +int load_texture(const char pFilename[], GLuint *pTexture); + +#endif === added file 'vector.cpp' --- vector.cpp 1970-01-01 00:00:00 +0000 +++ vector.cpp 2010-07-07 10:32:18 +0000 @@ -0,0 +1,125 @@ +#include "vector.h" + +Vector3f::Vector3f() +{ + x = 0.0f; y = 0.0f; z = 0.0f; +} + +Vector3f::Vector3f(GLfloat pX, GLfloat pY, GLfloat pZ) +{ + x = pX; y = pY; z = pZ; +} + +void Vector3f::display() +{ + printf("(%f, %f, %f)\n", x, y, z); +} + +float Vector3f::length() +{ + return sqrt(x * x + y * y + z * z); +} + +void Vector3f::normalize() +{ + GLfloat l = length(); + x /= l; y /= l; z /= l; +} + +Vector3f &Vector3f::operator=(const Vector3f &pV) +{ + x = pV.x; + y = pV.y; + z = pV.z; + return *this; +} + +Vector3f &Vector3f::operator+=(const Vector3f &pV) +{ + x += pV.x; + y += pV.y; + z += pV.z; + return *this; +} + +Vector3f &Vector3f::operator-=(const Vector3f &pV) +{ + x -= pV.x; + y -= pV.y; + z -= pV.z; + return *this; +} + +Vector3f &Vector3f::operator*=(float pF) +{ + x *= pF; + y *= pF; + z *= pF; + return *this; +} + +Vector3f &Vector3f::operator*=(double pF) +{ + x *= pF; + y *= pF; + z *= pF; + return *this; +} + +Vector3f &Vector3f::operator/=(float pF) +{ + x /= pF; + y /= pF; + z /= pF; + return *this; +} + +Vector3f operator+(const Vector3f &pA, const Vector3f &pB) +{ + Vector3f v = pA; + return v += pB; +} + +Vector3f operator-(const Vector3f &pA, const Vector3f &pB) +{ + Vector3f v = pA; + return v -= pB; +} + +Vector3f operator*(const Vector3f &pA, const float &pB) +{ + Vector3f v = pA; + return v *= pB; +} + +Vector3f operator/(const Vector3f &pA, const float &pB) +{ + Vector3f v = pA; + return v /= pB; +} + +Vector3f operator*(const Vector3f &pA, const double &pB) +{ + Vector3f v = pA; + return v *= pB; +} + +Vector3f cross(const Vector3f &pA, const Vector3f &pB) +{ + return Vector3f(pA.y * pB.z - pA.z * pB.y, + pA.z * pB.x - pA.x * pB.z, + pA.x * pB.y - pA.y * pB.x); +} + +float dot(const Vector3f &pA, const Vector3f &pB) +{ + return pA.x * pB.x + pA.y * pB.y + pA.z * pB.z; +} + +Vector3f normal(const Vector3f &pA, const Vector3f &pB, const Vector3f &pC) +{ + Vector3f n = cross(pB - pA, pC - pA); + n.normalize(); + return n; +} + === added file 'vector.h' --- vector.h 1970-01-01 00:00:00 +0000 +++ vector.h 2010-07-07 10:32:18 +0000 @@ -0,0 +1,45 @@ +#ifndef _VECTOR_H +#define _VECTOR_H + +#include "oglsdl.h" + +#include +#include + +class Vector3f +{ + union + { + struct { GLfloat x; GLfloat y; GLfloat z; }; + GLfloat v[3]; + }; + +public: + + Vector3f(); + Vector3f(GLfloat pX, GLfloat pY, GLfloat pZ); + + void display(); + float length(); + void normalize(); + + Vector3f &operator=(const Vector3f &pV); + Vector3f &operator+=(const Vector3f &pV); + Vector3f &operator-=(const Vector3f &pV); + Vector3f &operator*=(float pF); + Vector3f &operator/=(float pF); + Vector3f &operator*=(double pF); +}; + +extern Vector3f operator+(const Vector3f &pA, const Vector3f &pB); +extern Vector3f operator-(const Vector3f &pA, const Vector3f &pB); +extern Vector3f operator*(const Vector3f &pA, const float &pB); +extern Vector3f operator/(const Vector3f &pA, const float &pB); + +extern Vector3f operator*(const Vector3f &pA, const double &pB); + +extern float dot(const Vector3f &pA, const Vector3f &pB); +extern Vector3f cross(const Vector3f &pA, const Vector3f &pB); +extern Vector3f normal(const Vector3f &pA, const Vector3f &pB, const Vector3f &pC); + +#endif