[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