Vbo added.

This commit is contained in:
Federico Ponchio 2004-10-15 16:45:27 +00:00
parent d403de71f8
commit 2acaf1a503
8 changed files with 212 additions and 77 deletions

View File

@ -164,6 +164,9 @@ unsigned int Nexus::AddPatch(unsigned int nvert, unsigned int nface,
return index.size() -1;
}
void Nexus::SetRamBufferSize(unsigned int r_size) {
patches.SetRamBufferSize(r_size);
}
void Nexus::Join(const std::set<unsigned int> &patches,
std::vector<Point3f> &newvert,

View File

@ -64,7 +64,9 @@ class Nexus {
bool HasColors() { return (signature & NXS_COLORS) != 0; }
bool HasNormalsShort() { return (signature & NXS_NORMALS_SHORT) != 0; }
bool HasNormalsFloat() { return (signature & NXS_NORMALS_FLOAT) != 0; }
void SetRamBufferSize(unsigned int ram_size);
//MOVE to nexus_build.cpp
void Join(const std::set<unsigned int> &patches,
std::vector<vcg::Point3f> &vert,

View File

@ -89,7 +89,7 @@ void Policy::NodeVisited(Node *node) {
}
}
NexusMt::NexusMt(): vbo(VBO_AUTO), vbo_size(0),
NexusMt::NexusMt(): vbo_mode(VBO_AUTO),
metric(NULL), mode(SMOOTH) {
metric = new FrustumMetric();
metric->index = &index;
@ -115,18 +115,26 @@ bool NexusMt::Load(const string &filename, bool readonly) {
SetComponent(TEXTURE, true);
SetComponent(DATA, true);
patches.vbos.resize(index.size());
return true;
}
bool NexusMt::InitGL() {
bool NexusMt::InitGL(Vbo mode, unsigned int vbosize) {
GLenum ret = glewInit();
if(ret != GLEW_OK) return false;
if(!GLEW_ARB_vertex_buffer_object)
vbo = VBO_OFF;
if(!GLEW_ARB_vertex_buffer_object) {
cerr << "No vbo available!" << endl;
vbo_mode = VBO_OFF;
}
if(vbo_mode == VBO_OFF) {
patches.vbo_size = vbosize / patches.chunk_size;
patches.vbos.resize(0);
}
return true;
}
void NexusMt::Render() {
patches.Flush();
Frustumf frustum;
frustum.GetView();
@ -156,15 +164,36 @@ void NexusMt::Render() {
tri_rendered += entry.nface;
Patch &patch = GetPatch(cell);
Patch &patch = GetPatch(cell, false);
char *fstart;
char *vstart;
char *cstart;
char *nstart;
assert(patch.start);
if(vbo_mode != VBO_OFF) {
VboBuffer &vbo = patches.GetVbo(cell);
assert(vbo.index);
assert(vbo.vertex);
glVertexPointer(3, GL_FLOAT, 0, patch.VertBegin());
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo.vertex);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, vbo.index);
fstart = NULL;
vstart = NULL;
cstart = (char *)(sizeof(float) * patch.cstart);
nstart = (char *)(sizeof(float) * patch.nstart);
} else {
fstart = (char *)patch.FaceBegin();
vstart = (char *)patch.VertBegin();
cstart = (char *)patch.ColorBegin();
nstart = (char *)patch.Norm16Begin();
}
glVertexPointer(3, GL_FLOAT, 0, vstart);
if(use_colors)
glColorPointer(4, GL_UNSIGNED_BYTE, 0, patch.ColorBegin());
glColorPointer(4, GL_UNSIGNED_BYTE, 0, cstart);
if(use_normals)
glNormalPointer(GL_SHORT, 8, patch.Norm16Begin());
glNormalPointer(GL_SHORT, 8, nstart);
switch(mode) {
case POINTS:
@ -174,10 +203,10 @@ void NexusMt::Render() {
case SMOOTH:
if(signature & NXS_FACES)
glDrawElements(GL_TRIANGLES, patch.nf * 3,
GL_UNSIGNED_SHORT, patch.FaceBegin());
GL_UNSIGNED_SHORT, fstart);
else if(signature & NXS_STRIP)
glDrawElements(GL_TRIANGLE_STRIP, patch.nf,
GL_UNSIGNED_SHORT, patch.FaceBegin());
GL_UNSIGNED_SHORT, fstart);
break;
default:
cerr << "Unsupported rendering mode sorry\n";
@ -190,7 +219,7 @@ void NexusMt::Render() {
glDisableClientState(GL_NORMAL_ARRAY);
}
void NexusMt::SetRamSize(unsigned int r_size) {
void NexusMt::SetRamExtractionSize(unsigned int r_size) {
policy.ram_size = r_size/patches.chunk_size;
}
@ -203,13 +232,8 @@ void NexusMt::SetError(float error) {
policy.error = error;
}
void NexusMt::SetVbo(Vbo _vbo, unsigned int _vbo_size,
unsigned int _ram_size) {
vbo = _vbo;
if(!GLEW_ARB_vertex_buffer_object)
vbo = VBO_OFF;
vbo_size = _vbo_size;
patches.ram_size = _ram_size/chunk_size;
void NexusMt::SetVboSize(unsigned int _vbo_size) {
patches.vbo_size = _vbo_size;
}
bool NexusMt::SetMode(Mode _mode) {
@ -448,4 +472,5 @@ void NexusMt::VisitNode(Node *node, vector<TNode> &heap) {
node->visited = true;
policy.NodeVisited(node);
}
}

View File

@ -28,7 +28,7 @@ namespace nxs {
TNode(Node *n, float e): node(n), error(e) {}
bool operator<(const TNode &n) { return error < n.error; }
};
class Metric {
public:
vector<Nexus::PatchInfo> *index;
@ -74,11 +74,11 @@ namespace nxs {
class NexusMt: public Nexus {
private:
std::vector<Node> nodes;
std::vector<VboBuffer> vbos;
public:
//Vertex buffer object mode
enum Vbo { VBO_AUTO, //autodetect best size (fallback if not VBO)
VBO_AUTO_ON, //autodetect best size must use VBO
enum Vbo { VBO_AUTO, //autodetect best size
VBO_OFF, //no vertex buffer object
VBO_FIXED }; //user supplied size
@ -99,8 +99,7 @@ class NexusMt: public Nexus {
TEXTURE = 0x4,
DATA = 0x8};
Vbo vbo;
unsigned int vbo_size;
Vbo vbo_mode;
Metric *metric;
Policy policy;
@ -121,15 +120,14 @@ class NexusMt: public Nexus {
~NexusMt();
bool Load(const std::string &filename, bool readonly = true);
bool InitGL();
bool InitGL(Vbo mode = VBO_AUTO, unsigned int vbo_size = 0);
void Render();
void SetMetric(MetricKind kind);
void SetError(float error);
void SetRamSize(unsigned int ram_size);
void SetVbo(Vbo mode, unsigned int vbo_size = 0,
unsigned int ram_size = 128000000);
void SetRamExtractionSize(unsigned int ram_size);
void SetVboSize(unsigned int vbo_size);
bool SetMode(Mode mode);
bool SetComponent(Component c, bool on);

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.14 2004/10/14 13:52:02 ponchio
Small changes.
Revision 1.13 2004/10/14 13:41:34 ponchio
Added statistics.
@ -47,7 +50,6 @@ Backup
Revision 1.6 2004/09/17 15:25:09 ponchio
First working (hopefully) release.
Revision 1.5 2004/09/16 14:25:16 ponchio
Backup. (lot of changes).
@ -94,7 +96,7 @@ using namespace std;
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#include <wrap/gui/trackball.h>
#include "stopwatch.h"
@ -107,7 +109,7 @@ bool fullscreen = false;
int width =1024;
int height = 768;
//TrackHand hand;
void gl_print(float x, float y, char *str);
SDL_Surface *screen = NULL;
@ -206,9 +208,11 @@ int main(int argc, char *argv[]) {
unsigned int ram_size = 640000;
nexus.SetError(error);
nexus.SetRamSize(ram_size);
nexus.SetRamExtractionSize(ram_size);
nexus.SetMetric(NexusMt::FRUSTUM);
if(!nexus.InitGL()) {
cerr << "Could not init glew.\n";
}
glClearColor(0, 0, 0, 0);
glEnable(GL_LIGHTING);
@ -242,11 +246,11 @@ int main(int argc, char *argv[]) {
case SDLK_LEFT:
ram_size *= 0.7;
nexus.SetRamSize(ram_size);
nexus.SetRamExtractionSize(ram_size);
cerr << "Max extraction ram size: " << ram_size << endl; break;
case SDLK_RIGHT:
ram_size *= 1.5;
nexus.SetRamSize(ram_size);
nexus.SetRamExtractionSize(ram_size);
cerr << "Max extraction ram size: " << ram_size << endl; break;
case SDLK_s: metric = NexusMt::FRUSTUM; break;
@ -356,13 +360,50 @@ int main(int argc, char *argv[]) {
//cerr Do some reporting:
if(show_statistics) {
cerr << "Ram used : " << nexus.policy.ram_used << endl;
cerr << "Tri drawn: " << nexus.tri_rendered << endl;
cerr << "Tri tot : " << nexus.tri_total << endl;
cerr << "Ram flushed: " << nexus.patches.ram_flushed << endl;
cerr << "Ram readed: " << nexus.patches.ram_readed << endl;
nexus.patches.ram_flushed = 0;
nexus.patches.ram_readed = 0;
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, 1, 0, 1);
glDisable(GL_DEPTH_TEST);
glDisable(GL_LIGHTING);
char buffer[1024];
glColor3f(1.0f, 1.0f, 1.0f);
sprintf(buffer, "Ram size : %.3fMb (max) %.3fMb (cur)",
nexus.patches.ram_size * nexus.chunk_size/(float)(1<<20),
nexus.patches.ram_used * nexus.chunk_size/(float)(1<<20));
gl_print(0.03, 0.12, buffer);
sprintf(buffer, "Extr size: %.3fMb(max) %.3fMb(cur)",
nexus.policy.ram_size * nexus.chunk_size/(float)(1<<20),
nexus.policy.ram_used * nexus.chunk_size/(float)(1<<20));
gl_print(0.03, 0.09, buffer);
sprintf(buffer, "Vbo size : %.3fMb(max) %.3fMb(cur)",
nexus.patches.vbo_size * nexus.chunk_size/(float)(1<<20),
nexus.patches.vbo_used * nexus.chunk_size/(float)(1<<20));
gl_print(0.03, 0.06, buffer);
sprintf(buffer, "Triangles: %.2fK (tot) %.2fK (vis)",
nexus.tri_total/(float)(1<<10),
nexus.tri_rendered/(float)(1<<10));
gl_print(0.03, 0.03, buffer);
/* cerr << "Ram flushed: " << nexus.patches.ram_flushed << endl;
cerr << "Ram readed: " << nexus.patches.ram_readed << endl;*/
nexus.patches.ram_flushed = 0;
nexus.patches.ram_readed = 0;
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
SDL_GL_SwapBuffers();
@ -374,4 +415,11 @@ int main(int argc, char *argv[]) {
return -1;
}
void gl_print(float x, float y, char *str) {
glRasterPos2f(x, y);
int len = strlen(str);
for(int i = 0; i < len; i++)
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, str[i]);
}

View File

@ -2,6 +2,8 @@
#include <iostream>
#include <algorithm>
#include <GL/glew.h>
using namespace std;
using namespace nxs;
@ -16,6 +18,9 @@ bool PatchServer::Create(const std::string &filename,
ram_size = rsize;
ram_used = 0;
vbo_size = 0;
vbo_used = 0;
ram_readed = 0;
ram_flushed = 0;
lru.clear();
@ -33,6 +38,8 @@ bool PatchServer::Load(const std::string &filename, Signature sig,
ram_readed = 0;
ram_flushed = 0;
vbo_size = 0;
vbo_used = 0;
lru.clear();
return File::Load(filename, readonly);
}
@ -146,6 +153,38 @@ Patch &PatchServer::GetPatch(unsigned int idx,
return *(entry.patch);
}
VboBuffer &PatchServer::GetVbo(unsigned int p) {
VboBuffer &buffer = vbos[p];
if(buffer.index) return buffer;
//TODO cerr << "Adding vbo: " << p << endl;
assert(patches[p].patch);
Patch &patch = *patches[p].patch;
glGenBuffersARB(1, &buffer.index);
assert(buffer.index);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, buffer.index);
unsigned int size = patch.nf * sizeof(unsigned short);
if((signature & NXS_FACES) != 0) size *= 3;
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, size, patch.FaceBegin(),
GL_STATIC_DRAW_ARB);
//TODO fix this when we allow data :p
size = sizeof(float) * patch.dstart;
glGenBuffersARB(1, &buffer.vertex);
glBindBufferARB(GL_ARRAY_BUFFER_ARB, buffer.vertex);
glBufferDataARB(GL_ARRAY_BUFFER_ARB, size, patch.VertBegin(),
GL_STATIC_DRAW_ARB);
vbo_used += patches[p].ram_size;
return buffer;
}
void PatchServer::Flush() {
if(ram_used < ram_size * 1.1) return;
@ -215,10 +254,22 @@ void PatchServer::Flush(unsigned int patch) {
delete entry.patch;
entry.patch = NULL;
entry.lru_pos = 0xffffffff;
if(FlushVbo(patch))
vbo_used -= entry.ram_size;
ram_used -= entry.ram_size;
ram_flushed += entry.ram_size;
}
bool PatchServer::FlushVbo(unsigned int patch) {
//TODO
//cerr << "Flushing vbo: " << patch << endl;
VboBuffer &buffer = vbos[patch];
if(!buffer.index) return false;
glDeleteBuffersARB(1, &buffer.index);
glDeleteBuffersARB(1, &buffer.vertex);
return true;
}
void PatchServer::SetRamBufferSize(unsigned int r_buffer) {
ram_size = (unsigned int)(r_buffer/chunk_size) + 1;
}

View File

@ -16,6 +16,14 @@ struct PatchEntry {
unsigned int lru_pos;
};
struct VboBuffer {
VboBuffer(unsigned int v = 0, unsigned int i = 0):
vertex(v), index(i) {}
unsigned int vertex;
unsigned int index;
};
class PatchServer: public File {
public:
struct PTime {
@ -34,6 +42,8 @@ class PatchServer: public File {
unsigned int ram_size;
unsigned int ram_used;
unsigned int vbo_size;
unsigned int vbo_used;
unsigned int frame;
//statistics:
@ -53,15 +63,22 @@ class PatchServer: public File {
bool WriteEntries(FILE *fp);
void AddPatch(unsigned short nvert, unsigned short nface);
Patch &GetPatch(unsigned int patch, unsigned short nvert, unsigned short nface,
Patch &GetPatch(unsigned int patch,
unsigned short nvert, unsigned short nface,
bool flush = true);
VboBuffer &GetVbo(unsigned int patch);
void Flush(unsigned int patch);
//return false if was not allocated.
bool FlushVbo(unsigned int patch);
void Flush();
void FlushAll();
void Flush(unsigned int patch);
void SetRamBufferSize(unsigned int ram_buffer);
std::vector<PatchEntry> patches;
std::vector<VboBuffer> vbos;
std::vector<PTime> lru;
};

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.12 2004/10/15 11:41:03 ponchio
Tests and small changes.
Revision 1.11 2004/10/10 17:19:42 ponchio
Added compression and debugged.
@ -127,7 +130,7 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
for(unsigned int v = 0; v < fine.size(); v++) {
if(fcount[v] == 0) continue;
fine[v].p = fcentroids[v]/(float)fcount[v];
fine[v].weight = (float)pow(fcount[v]/(float)fine_vmean, 0.3f);
fine[v].weight = (float)pow(fcount[v]/(float)fine_vmean, 0.2f);
}
fine.Init();
}
@ -138,7 +141,10 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
if(fcount[i] > min_size)
seeds.push_back(fine[i]);
}
swap(fine, seeds);
fine.clear();
for(unsigned int i = 0; i < seeds.size(); i++)
fine.push_back(seeds[i]);
if(fine.size() == 0) fine.push_back(Point3f(0,0,0));
fine.Init();
@ -167,31 +173,12 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
if(ccount[v] == 0) continue;
coarse[v].p = ccentroids[v]/(float)ccount[v];
coarse[v].weight = (float)pow(ccount[v]/(float)coarse_vmean, 0.3f);
coarse[v].weight = (float)pow(ccount[v]/(float)coarse_vmean, 0.2f);
if(radius[v] == 0) continue;
//repel from fine seeds
unsigned int atarget;
float closest = fine.Closest(coarse[v].p, atarget);
Point3f dir = (coarse[v].p - fine[atarget].p).Normalize();
Point3f a = coarse[v].p;
Point3f b = fine[atarget].p + dir*radius[v]*1.1;
unsigned int btarget;
closest = fine.Closest(b, btarget);
if(atarget == btarget) {
continue;
}
Point3f m;
for(unsigned int i = 0; i < 10; i++) {
m = (a + b)/2;
unsigned int mtarget;
fine.Closest(m, mtarget);
if(mtarget == atarget) a = m;
else if(mtarget == btarget) b = m;
else break;
}
coarse[v].p = m;
// coarse[v].p = fine.FindBorder(coarse[v].p, radius[v]);
}
coarse.Init();
}
@ -203,7 +190,10 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
if(ccount[i] > (int)min_size)
seeds.push_back(coarse[i]);
}
swap(coarse, seeds);
coarse.clear();
for(unsigned int i = 0; i < seeds.size(); i++)
coarse.push_back(seeds[i]);
if(coarse.size() == 0) coarse.push_back(Point3f(0,0,0));
coarse.Init();
@ -429,14 +419,11 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset,
coarse[v].p = ccentroids[v]/(float)ccount[v];
//0.3 is related to the fact is doubled the box size.
coarse[v].weight = (float)pow(ccount[v]/(float)coarse_vmean, 0.3f);
coarse[v].weight = (float)pow(ccount[v]/(float)coarse_vmean, 0.2f);
if(radius[v] == 0) continue;
//repel from fine seeds
//coarse[v].p = fine.FindBorder(coarse[v].p, radius[v]);
}
// fine.Init(fine.bbox);
coarse.Init();
}
vector<Seed> seeds;
@ -444,7 +431,11 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset,
if(ccount[i] > (int)min_size)
seeds.push_back(coarse[i]);
}
swap(coarse, seeds);
coarse.clear();
for(unsigned int i = 0; i < seeds.size(); i++)
coarse.push_back(seeds[i]);
if(coarse.size() == 0) coarse.push_back(Point3f(0,0,0));
coarse.Init();