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

List:       kde-commits
Subject:    playground/games/astrododge/src
From:       Rivo Laks <rivolaks () hot ! ee>
Date:       2009-07-17 18:07:43
Message-ID: 1247854063.945726.22747.nullmailer () svn ! kde ! org
[Download RAW message or body]

SVN commit 998468 by rivol:

Updates to model rendering: most GameObjects are now rendered in a single loop, with \
as little state  changes as possible. This should bring some performance \
improvements.

 M  +1 -1      asteroid.cpp  
 M  +10 -18    datastore.cpp  
 M  +1 -27     gameobject.cpp  
 M  +2 -4      gameobject.h  
 M  +74 -52    gameview.cpp  
 M  +2 -3      gameview.h  
 M  +22 -17    model.cpp  
 M  +19 -12    model.h  


--- trunk/playground/games/astrododge/src/asteroid.cpp #998467:998468
@@ -49,7 +49,7 @@
 void Asteroid::setModel(Model* model)
 {
     mModel = model;
-    Mesh* collisionmesh = model->collisionMesh();
+    Batch* collisionmesh = model->collisionMesh();
     const Vector3f* originalVertices = reinterpret_cast<const \
Vector3f*>(collisionmesh->verticesArray());  collVertexData = new \
Vector3f[collisionmesh->vertexCount()];  for (unsigned int i = 0; i < \
                collisionmesh->vertexCount(); i++) {
--- trunk/playground/games/astrododge/src/datastore.cpp #998467:998468
@@ -100,6 +100,7 @@
         if (!model->isValid()) {
             return false;
         }
+        model->setTexture(texture("asteroid.png"));
         mNonFinalizedModels[modelName] = model;
         mAsteroidModels.append(model);
     }
@@ -122,29 +123,20 @@
     KConfigGroup modelconf(&objectconf, "Model");
     Model* model = new Model(mDataDir + "objects/" + name + ".index", mDataDir + \
"models/");  
-    Program* prog = program(modelconf.readEntry("Program", "object"));
-
     if (!model->isValid()) {
         kError() << "Couldn't load model" << name;
         return false;
-    } else if (!prog) {
-        // Error was already given
-        kDebug() << "No prog";
-        return false;
-    } else {
-        model->load();
+    }
+    model->load();
 
-        model->setProgram(prog);
-
-        foreach (const QString& texkey, modelconf.keyList().filter("Texture-")) {
-            bool isnum = false;
-            int texnum = texkey.mid(8).toInt(&isnum);
-            if (!isnum) {
-                kError() << "Invalid texture key" << texkey;
-                continue;
-            }
-            model->setTexture(texnum, texture(modelconf.readEntry(texkey)));
+    foreach (const QString& texkey, modelconf.keyList().filter("Texture-")) {
+        bool isnum = false;
+        int texnum = texkey.mid(8).toInt(&isnum);
+        if (!isnum) {
+            kError() << "Invalid texture key" << texkey;
+            continue;
         }
+        model->setTexture(texnum, texture(modelconf.readEntry(texkey)));
     }
     mNonFinalizedModels[name] = model;
 
--- trunk/playground/games/astrododge/src/gameobject.cpp #998467:998468
@@ -161,37 +161,11 @@
     glMultMatrixf(matrix);
 }
 
-void GameObject::render(const Vector3f& camerapos, float detail, bool bind) const
-{
-    if (!mModel) {
-        return;
-    }
-
-    glPushMatrix();
-    openglTransform();
-    if (mModelScale != 1.0f) {
-        glScalef(mModelScale, mModelScale, mModelScale);
-    }
-
-    if (bind) {
-        mModel->render(radius, position(), camerapos, detail);
-    } else {
-        mModel->renderOnce(radius, position(), camerapos, detail);
-    }
-
-    glPopMatrix();
-}
-
-int GameObject::getLod(const Vector3f& camerapos, float detail) const
-{
-    return mModel->getLod(radius, position(), camerapos, detail);
-}
-
 void GameObject::setModel(Model* m)
 {
     mModel = m;
     // Set ODE's geometry
-    KGLLib::Mesh* cm = mModel->collisionMesh();
+    KGLLib::Batch* cm = mModel->collisionMesh();
     createGeomFromMesh((const Vector3f*)cm->verticesArray(), cm->vertexCount(),
                        (const unsigned int*)cm->indicesArray(), cm->indicesCount());
 }
--- trunk/playground/games/astrododge/src/gameobject.h #998467:998468
@@ -51,10 +51,6 @@
     virtual void addForce(const Vector3f& force);
     virtual void collision(const Vector3f& force)  {}
 
-    virtual void render(const Vector3f& camerapos, float detail, bool bind = true) \
                const;
-
-    virtual int getLod(const Vector3f& camerapos, float detail) const;
-
     inline static void setVectorFromOde(const dReal* odeVector, Vector3f* myVector)
     {
         myVector->x() = odeVector[0];
@@ -91,6 +87,8 @@
     Model* model() const  { return mModel; }
     virtual void setModel(Model* m);
 
+    float modelScale() const  { return mModelScale; }
+
 public:
     float radius;
     int id;
--- trunk/playground/games/astrododge/src/gameview.cpp #998467:998468
@@ -22,6 +22,7 @@
 #include "asteroid.h"
 #include "model.h"
 #include "bullet.h"
+#include "datastore.h"
 
 #include <kgllib/camera.h>
 #include <kgllib/widgetproxy.h>
@@ -29,6 +30,7 @@
 #include <kgllib/fpscounter.h>
 #include <kgllib/texture.h>
 #include <kgllib/shapes.h>
+#include <kgllib/program.h>
 
 #include <KDebug>
 #include <KStandardDirs>
@@ -98,29 +100,16 @@
 
     // Render space (background). For this, we don't want depth testing, lighting, \
etc  glDisable(GL_DEPTH_TEST);
+    glEnable(GL_CULL_FACE);
     renderSpace();
 
     // Setup light pos
     glLightfv(GL_LIGHT0, GL_POSITION, Vector4f(-100000.0, 60000.0, 20000.0, \
1.0).data());  glEnable(GL_DEPTH_TEST);
 
-    foreach (Planet* p, *mWorld->planets()) {
-        p->render();
-    }
+    renderObjects(mWorld->objects());
+    glDisable(GL_CULL_FACE);
 
-    // Render asteroids
-    renderAsteroids();
-
-    // Misc objects
-    Ship* ship = mWorld->ship();
-    const QList<GameObject*>* objects = mWorld->objects();
-    for (int i = 0; i < objects->count(); i++) {
-        GameObject* obj = objects->at(i);
-        if (obj->type() != GameObject::T_Asteroid) {
-            obj->render(ship->position(), mDetailLevel);
-        }
-    }
-
     glLineWidth(2.0);
     glPointSize(3.0);
     Vector4f bulletcolor(0.6, 0.5, 0.2, 1.0);
@@ -152,7 +141,7 @@
     // Track
     QList<Vector3f> track(mWorld->trackPoints());
     if (!track.isEmpty()) {
-        track.prepend(ship->position());
+        track.prepend(mWorld->ship()->position());
         glColor4f(1, 1, 0, 1);
         glBegin(GL_LINE_STRIP);
         for (int i = 0; i < track.count(); i++) {
@@ -169,53 +158,86 @@
     QTimer::singleShot(0, this, SLOT(update()));
 }
 
-void GameView::renderAsteroids()
+void GameView::renderObjects(const QList<GameObject*>* objects)
 {
-//     if (mInput->renderWireframe()) {
-//         glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-//     }
+    Vector3f cameraPos = mWorld->ship()->position();
 
-//     if (mEnableCullFace) {
-//         glEnable(GL_CULL_FACE);
-//     }
+    GeometryBuffer* buffer = 0;
+    QString material;
+    const int maxTextures = 4;
+    Texture* texture[maxTextures];
+    for (int i = 0; i < maxTextures; i++) {
+        texture[i] = 0;
+    }
+    int activeTextures = 0;
 
-    const QList<GameObject*>* objects = mWorld->objects();
-    Mesh* firstAsteroidModel = 0;
-    for (int i = 0; i < objects->count(); i++) {
-        GameObject* obj = objects->at(i);
-        if (obj->type() != GameObject::T_Asteroid) {
+    Program* prog = mWorld->data()->program("asteroid");
+    prog->bind();
+
+    foreach (const GameObject* obj, *objects) {
+        Model* model = obj->model();
+        if (!model) {
             continue;
         }
-        Asteroid* a = static_cast<Asteroid*>(obj);
 
-        if (!firstAsteroidModel) {
-            firstAsteroidModel = a->model()->lod(0);
-            firstAsteroidModel->bind();
+        if (model->buffer() != buffer) {
+            if (buffer) {
+                buffer->unbind();
+            }
+            model->buffer()->bind();
+            buffer = model->buffer();
         }
+        int newActiveTextures = qMin(maxTextures, model->textureCount());
+        for (int i = 0; i < qMax(activeTextures, newActiveTextures); i++) {
+            Texture* newTex = model->texture(i);
+            if (newTex == texture[i]) {
+                // No need to change anything
+                continue;
+            }
+            glActiveTexture(GL_TEXTURE0 + i);
+            if (newTex && texture[i]) {
+                // Just change the active texture
+                newTex->bind();
+            } else if (!texture[i]) {
+                // Enable (and bind)
+                newTex->enable();
+            } else {
+                // Disable old texture
+                texture[i]->disable();
+            }
 
-        renderAsteroid(a);
-    }
-    if (firstAsteroidModel) {
-        firstAsteroidModel->unbind();
-    }
+            texture[i] = newTex;
+        }
+        activeTextures = newActiveTextures;
 
-    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-    glDisable(GL_CULL_FACE);
-}
+        // Transform
+        glPushMatrix();
+        obj->openglTransform();
+        if (obj->modelScale() != 1.0f) {
+            glScalef(obj->modelScale(), obj->modelScale(), obj->modelScale());
+        }
 
-void GameView::renderAsteroid(const Asteroid* a)
-{
-    Ship* ship = mWorld->ship();
+        // Render
+        model->render(obj->radius, obj->position(), cameraPos, mDetailLevel);
 
-    a->render(ship->position(), mDetailLevel, false);
+        // Un-transform
+        glPopMatrix();
 
-//     int lod = a->getLod(ship->position(), mDetailLevel);
-//
-//     int tris = a->model()->lod(lod)->indicesCount()/3;
-//     mRenderInfo.totalTriangles += tris;
-//     mRenderInfo.trianglesPerLod[lod] += tris;
-//     mRenderInfo.asteroidsPerLod[lod]++;
-//     mRenderInfo.totalAsteroids++;
+    }
+
+    for (int i = 0; i < activeTextures; i++) {
+        if (texture[i]) {
+            glActiveTexture(GL_TEXTURE0 + i);
+            texture[i]->disable();
+            kDebug() << "disable" << i;
+        }
+    }
+    glActiveTexture(GL_TEXTURE0);
+    prog->unbind();
+    if (buffer) {
+        buffer->unbind();
+    }
+    glColor3f(1, 1, 1);
 }
 
 void GameView::renderSpace()
--- trunk/playground/games/astrododge/src/gameview.h #998467:998468
@@ -22,7 +22,7 @@
 #include "glview.h"
 
 class GameWorld;
-class Asteroid;
+class GameObject;
 
 namespace KGLLib
 {
@@ -47,9 +47,8 @@
     protected:
         void setupWorldView();
 
-        void renderAsteroids();
-        void renderAsteroid(const Asteroid* a);
         void renderSpace();
+        void renderObjects(const QList<GameObject*>* objects);
 
     private:
         GameWorld* mWorld;
--- trunk/playground/games/astrododge/src/model.cpp #998467:998468
@@ -31,6 +31,7 @@
 
 Model::Model(const QString& filename, const QString& modeldir)
 {
+    mConfigFile = filename;
     kDebug() << "Loading from" << filename;
     mValid = false;
 
@@ -42,6 +43,8 @@
     KConfig conf(filename);
     KConfigGroup modelconf(&conf, "Model");
 
+    mMaterial = modelconf.readEntry("Material", "object");
+
     int lodCount = qMin(5, modelconf.readEntry("LODs", 0));
     if (lodCount == 0) {
         // We have a single model, specified by Model key
@@ -96,30 +99,38 @@
     return count;
 }
 
-void Model::setProgram(Program* program)
+void Model::setTexture(Texture* texture)
 {
-    foreach (Mesh* m, mLODs) {
-        m->setProgram(program);
+    setTexture(0, texture);
+}
+
+void Model::setTexture(int index, Texture* texture)
+{
+    if (mTextures.size() <= index) {
+        mTextures.resize(index+1);
     }
+    mTextures[index] = texture;
 }
 
-void Model::setTexture(Texture* texture)
+void Model::setMaterial(const QString& material)
 {
-    setTexture(0, texture);
+    mMaterial = material;
 }
 
-void Model::setTexture(int index, Texture* texture)
+GeometryBuffer* Model::buffer()
 {
-    foreach (Mesh* m, mLODs) {
-        m->setTexture(index, texture);
+    if (mLODs.isEmpty()) {
+        return 0;
     }
+
+    return mLODs[0]->buffer();
 }
 
 void Model::load(GeometryBuffer* buffer, int* vertexoffset, int* indexoffset)
 {
     for (int lod = 0; lod < mLoaders.count(); lod++) {
         kDebug() << "Creating mesh for lod" << lod;
-        Mesh* mesh = new Mesh(buffer, *vertexoffset, *indexoffset);
+        Batch* mesh = new Batch(buffer, *vertexoffset, *indexoffset);
 
         mLoaders[lod]->loadIntoBatch(mesh);
         mesh->update();
@@ -137,7 +148,7 @@
     // TODO: some code duplication here
     for (int lod = 0; lod < mLoaders.count(); lod++) {
         kDebug() << "Creating mesh for lod" << lod;
-        Mesh* mesh = new Mesh();
+        Batch* mesh = new Batch();
 
         mLoaders[lod]->loadIntoBatch(mesh);
         mesh->update();
@@ -159,7 +170,7 @@
     return loader;
 }
 
-Mesh* Model::collisionMesh() const
+Batch* Model::collisionMesh() const
 {
     int lod = qMin(4, mLODs.count()-1);
     return mLODs[lod];
@@ -168,12 +179,6 @@
 void Model::render(float radius, const Vector3f& position, const Vector3f& \
camerapos, float detail) const  {
     int lod = getLod(radius, position, camerapos, detail);
-    mLODs[lod]->render();
-}
-
-void Model::renderOnce(float radius, const Vector3f& position, const Vector3f& \
                camerapos, float detail) const
-{
-    int lod = getLod(radius, position, camerapos, detail);
     mLODs[lod]->renderOnce();
 }
 
--- trunk/playground/games/astrododge/src/model.h #998467:998468
@@ -26,7 +26,7 @@
 namespace KGLLib
 {
 class ModelLoader;
-class Mesh;
+class Batch;
 class GeometryBuffer;
 class Program;
 class Texture;
@@ -35,6 +35,9 @@
 using namespace KGLLib;
 using namespace Eigen;
 
+/**
+ * Model is used by most GameObjects for rendering.
+ **/
 class Model
 {
 public:
@@ -47,18 +50,22 @@
     Model(const QString& file, const QString& modeldir = QString());
     ~Model();
 
+    QString configFile() const  { return mConfigFile; }
+
     /**
-     * Sets program of the model.
-     * This has to be called after @ref load().
-     **/
-    void setProgram(Program* program);
-    /**
      * Sets texture of the model.
      * This has to be called after @ref load().
     **/
     void setTexture(Texture* texture);
     void setTexture(int index, Texture* texture);
+    int textureCount() const  { return mTextures.count(); }
+    Texture* texture(int i)  { return (i < textureCount()) ? mTextures.at(i) : 0; }
 
+    void setMaterial(const QString& material);
+    QString material() const  { return mMaterial; }
+
+    GeometryBuffer* buffer();
+
     /**
      * Loads the model and creates meshes, using the shared GeometryBuffer.
     **/
@@ -73,11 +80,10 @@
     int indexCount() const;
 
 
-    Mesh* lod(int i) const  { return mLODs[i]; }
-    Mesh* collisionMesh() const;
+    Batch* lod(int i) const  { return mLODs[i]; }
+    Batch* collisionMesh() const;
 
     void render(float radius, const Vector3f& position, const Vector3f& camerapos, \
                float detail) const;
-    void renderOnce(float radius, const Vector3f& position, const Vector3f& \
camerapos, float detail) const;  
     inline float getDetailLevel(float radius, const Vector3f& position, const \
Vector3f& camerapos, float detail) const  {
@@ -101,12 +107,13 @@
     ModelLoader* createModelLoader(const QString& modelfile);
 
 private:
+    QString mConfigFile;
     QVector<ModelLoader*> mLoaders;
-    QVector<Mesh*> mLODs;
+    QVector<Batch*> mLODs;
     bool mValid;
 
-    Program* mProgram;
-    Texture* mTexture;
+    QVector<Texture*> mTextures;
+    QString mMaterial;
 };
 
 #endif


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

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