Realtime viz
This commit is contained in:
parent
9bb65dd0c3
commit
7fb2c4b831
|
@ -1,8 +1,11 @@
|
||||||
#include <GL/glew.h>
|
|
||||||
#include "nexusmt.h"
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
#include <ptypes/pasync.h>
|
||||||
|
|
||||||
|
#include "nexusmt.h"
|
||||||
|
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
using namespace vcg;
|
using namespace vcg;
|
||||||
|
@ -104,6 +107,8 @@ NexusMt::NexusMt(): vbo_mode(VBO_AUTO),
|
||||||
NexusMt::~NexusMt() {
|
NexusMt::~NexusMt() {
|
||||||
if(metric)
|
if(metric)
|
||||||
delete metric;
|
delete metric;
|
||||||
|
prefetch.signal();
|
||||||
|
prefetch.waitfor();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NexusMt::Load(const string &filename) {
|
bool NexusMt::Load(const string &filename) {
|
||||||
|
@ -174,6 +179,9 @@ bool NexusMt::Load(const string &filename) {
|
||||||
SetComponent(DATA, true);
|
SetComponent(DATA, true);
|
||||||
|
|
||||||
SetPrefetchSize(patches.ram_max/2);
|
SetPrefetchSize(patches.ram_max/2);
|
||||||
|
cerr << "Start!\n";
|
||||||
|
prefetch.start();
|
||||||
|
cerr << "Started\n";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,7 +212,7 @@ void NexusMt::Render() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void NexusMt::Draw(vector<unsigned int> &cells) {
|
void NexusMt::Draw(vector<unsigned int> &cells) {
|
||||||
|
prefetch.init(this, cells, visited);
|
||||||
tri_total = 0;
|
tri_total = 0;
|
||||||
tri_rendered = 0;
|
tri_rendered = 0;
|
||||||
|
|
||||||
|
@ -218,29 +226,56 @@ void NexusMt::Draw(vector<unsigned int> &cells) {
|
||||||
glEnableClientState(GL_NORMAL_ARRAY);
|
glEnableClientState(GL_NORMAL_ARRAY);
|
||||||
//TODO textures and data.
|
//TODO textures and data.
|
||||||
|
|
||||||
for(unsigned int i = 0; i < cells.size(); i++) {
|
unsigned int count = cells.size();
|
||||||
unsigned int cell = cells[i];
|
while(count) {
|
||||||
|
// cerr << "Getting message: " << count << endl;
|
||||||
|
pt::message *msg = patches.queue.getmessage();
|
||||||
|
QueuePServer::Data *data = (QueuePServer::Data *)(msg->param);
|
||||||
|
if(msg->id == QueuePServer::FLUSH) {
|
||||||
|
// cerr << "Flush...\n";
|
||||||
|
if(data->vbo_element) {
|
||||||
|
glDeleteBuffersARB(1, &(data->vbo_element));
|
||||||
|
glDeleteBuffersARB(1, &(data->vbo_array));
|
||||||
|
}
|
||||||
|
delete data;
|
||||||
|
delete msg;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(msg->id != QueuePServer::DRAW) {
|
||||||
|
cerr << "Unknown message!\n";
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int cell = msg->result;
|
||||||
PatchInfo &entry = index[cell];
|
PatchInfo &entry = index[cell];
|
||||||
tri_total += entry.nface;
|
tri_total += entry.nface;
|
||||||
//frustum culling
|
//frustum culling
|
||||||
if(frustum.IsOutside(entry.sphere.Center(), entry.sphere.Radius()))
|
if(!frustum.IsOutside(entry.sphere.Center(), entry.sphere.Radius())) {
|
||||||
continue;
|
|
||||||
|
|
||||||
tri_rendered += entry.nface;
|
tri_rendered += entry.nface;
|
||||||
|
Draw(cell, *data);
|
||||||
|
}
|
||||||
|
|
||||||
QueuePServer::Data &data = patches.Lookup(cell,entry.nvert,entry.nface, 0);
|
delete msg;
|
||||||
Patch &patch = *data.patch;
|
count--;
|
||||||
|
}
|
||||||
|
glDisableClientState(GL_VERTEX_ARRAY);
|
||||||
|
glDisableClientState(GL_COLOR_ARRAY);
|
||||||
|
glDisableClientState(GL_NORMAL_ARRAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NexusMt::Draw(unsigned int cell, QueuePServer::Data &data) {
|
||||||
|
|
||||||
|
Patch &patch = *(data.patch);
|
||||||
char *fstart;
|
char *fstart;
|
||||||
char *vstart;
|
char *vstart;
|
||||||
char *cstart;
|
char *cstart;
|
||||||
char *nstart;
|
char *nstart;
|
||||||
|
|
||||||
if(vbo_mode != VBO_OFF) {
|
if(vbo_mode != VBO_OFF) {
|
||||||
// unsigned int vbo_array;
|
if(!data.vbo_element) {
|
||||||
// unsigned int vbo_element;
|
patches.LoadVbo(data);
|
||||||
// patches.GetVbo(cell, vbo_element, vbo_array);
|
}
|
||||||
assert(data.vbo_element);
|
|
||||||
assert(data.vbo_array);
|
|
||||||
|
|
||||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, data.vbo_array);
|
glBindBufferARB(GL_ARRAY_BUFFER_ARB, data.vbo_array);
|
||||||
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, data.vbo_element);
|
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, data.vbo_element);
|
||||||
|
@ -301,10 +336,6 @@ void NexusMt::Draw(vector<unsigned int> &cells) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glDisableClientState(GL_VERTEX_ARRAY);
|
|
||||||
glDisableClientState(GL_COLOR_ARRAY);
|
|
||||||
glDisableClientState(GL_NORMAL_ARRAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NexusMt::SetExtractionSize(unsigned int r_size) {
|
void NexusMt::SetExtractionSize(unsigned int r_size) {
|
||||||
extraction_max = r_size/patches.chunk_size;
|
extraction_max = r_size/patches.chunk_size;
|
||||||
|
@ -471,6 +502,7 @@ void NexusMt::ClearHistory() {
|
||||||
|
|
||||||
void NexusMt::Extract(std::vector<unsigned int> &selected) {
|
void NexusMt::Extract(std::vector<unsigned int> &selected) {
|
||||||
extraction_used = 0;
|
extraction_used = 0;
|
||||||
|
visited.clear();
|
||||||
|
|
||||||
std::vector<Node>::iterator n;
|
std::vector<Node>::iterator n;
|
||||||
for(n = nodes.begin(); n != nodes.end(); n++) {
|
for(n = nodes.begin(); n != nodes.end(); n++) {
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <ptypes/pasync.h>
|
|
||||||
#include <wrap/gui/frustum.h>
|
#include <wrap/gui/frustum.h>
|
||||||
|
|
||||||
#include "nexusbase.h"
|
#include "nexusbase.h"
|
||||||
|
@ -121,9 +120,12 @@ class NexusMt: public NexusBase {
|
||||||
unsigned int tri_total;
|
unsigned int tri_total;
|
||||||
|
|
||||||
std::vector<PServer::Item> visited;
|
std::vector<PServer::Item> visited;
|
||||||
|
|
||||||
QueuePServer patches;
|
QueuePServer patches;
|
||||||
BorderServer borders;
|
BorderServer borders;
|
||||||
|
|
||||||
|
Prefetch prefetch;
|
||||||
|
|
||||||
NexusMt();
|
NexusMt();
|
||||||
~NexusMt();
|
~NexusMt();
|
||||||
|
|
||||||
|
@ -146,6 +148,7 @@ class NexusMt: public NexusBase {
|
||||||
bool SetComponents(unsigned int mask);
|
bool SetComponents(unsigned int mask);
|
||||||
|
|
||||||
void Draw(std::vector<unsigned int> &selected);
|
void Draw(std::vector<unsigned int> &selected);
|
||||||
|
void Draw(unsigned int cell, QueuePServer::Data &data);
|
||||||
void Extract(std::vector<unsigned int> &selected);
|
void Extract(std::vector<unsigned int> &selected);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "prefetch.h"
|
#include "prefetch.h"
|
||||||
|
#include "nexusmt.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
|
@ -6,22 +7,34 @@ using namespace nxs;
|
||||||
|
|
||||||
void Prefetch::init(NexusMt *m, std::vector<unsigned int> &selected,
|
void Prefetch::init(NexusMt *m, std::vector<unsigned int> &selected,
|
||||||
std::vector<PServer::Item> &visited) {
|
std::vector<PServer::Item> &visited) {
|
||||||
|
|
||||||
|
// cerr << "Init\n";
|
||||||
|
|
||||||
safety.lock();
|
safety.lock();
|
||||||
mt = m;
|
mt = m;
|
||||||
missing.clear();
|
missing.clear();
|
||||||
|
|
||||||
|
unsigned int notloaded = 0;
|
||||||
std::map<unsigned int, float> tmp;
|
std::map<unsigned int, float> tmp;
|
||||||
for(unsigned int i = 0; i < selected.size(); i++) {
|
for(unsigned int i = 0; i < selected.size(); i++) {
|
||||||
unsigned int patch = selected[i];
|
unsigned int patch = selected[i];
|
||||||
tmp[patch] = 0.0f;
|
tmp[patch] = 0.0f;
|
||||||
|
if(!mt->patches.IsLoaded(patch))
|
||||||
|
notloaded++;
|
||||||
|
// if(mt->patches.IsLoaded(patch))
|
||||||
|
// mt->todraw.push_back(make_pair(patch, (Patch *)NULL));
|
||||||
|
// else
|
||||||
missing.push_back(PServer::Item(patch, 0.0f));
|
missing.push_back(PServer::Item(patch, 0.0f));
|
||||||
}
|
}
|
||||||
|
if(notloaded)
|
||||||
|
cerr << "Patches to load: " << notloaded << endl;
|
||||||
|
|
||||||
for(unsigned int i = 0; i < visited.size(); i++) {
|
for(unsigned int i = 0; i < visited.size(); i++) {
|
||||||
PServer::Item &item = visited[i];
|
PServer::Item &item = visited[i];
|
||||||
if(tmp.count(item.patch)) continue;
|
if(tmp.count(item.patch)) continue;
|
||||||
if(mt->patches.IsLoaded(item.patch))
|
if(mt->patches.IsLoaded(item.patch))
|
||||||
tmp[item.patch] = item.priority;
|
tmp[item.patch] = item.priority;
|
||||||
else
|
|
||||||
missing.push_back(item);
|
missing.push_back(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +47,7 @@ void Prefetch::init(NexusMt *m, std::vector<unsigned int> &selected,
|
||||||
item.priority = 1e40;
|
item.priority = 1e40;
|
||||||
}
|
}
|
||||||
make_heap(ps.heap.begin(), ps.heap.end());
|
make_heap(ps.heap.begin(), ps.heap.end());
|
||||||
|
|
||||||
sort(missing.begin(), missing.end()); //CRITICAL reverse pero'!
|
sort(missing.begin(), missing.end()); //CRITICAL reverse pero'!
|
||||||
reverse(missing.begin(), missing.end());
|
reverse(missing.begin(), missing.end());
|
||||||
safety.unlock();
|
safety.unlock();
|
||||||
|
@ -44,13 +58,26 @@ void Prefetch::execute() {
|
||||||
if(get_signaled()) return;
|
if(get_signaled()) return;
|
||||||
while(1) {
|
while(1) {
|
||||||
safety.lock();
|
safety.lock();
|
||||||
if(missing.size() == 0) break;
|
if(missing.size() == 0) {
|
||||||
|
safety.unlock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
PServer::Item item = missing.back();
|
PServer::Item item = missing.back();
|
||||||
missing.pop_back();
|
missing.pop_back();
|
||||||
|
|
||||||
|
if(item.priority > 0 &&
|
||||||
|
mt->patches.ram_used > mt->patches.ram_max &&
|
||||||
|
item.priority >= mt->patches.MaxPriority()) {
|
||||||
|
safety.unlock();
|
||||||
|
break;
|
||||||
|
}
|
||||||
PatchInfo &info = mt->index[item.patch];
|
PatchInfo &info = mt->index[item.patch];
|
||||||
|
|
||||||
|
// cerr << "prefetching: " << item.patch << endl;
|
||||||
mt->patches.Lookup(item.patch, info.nvert, info.nface, item.priority);
|
mt->patches.Lookup(item.patch, info.nvert, info.nface, item.priority);
|
||||||
|
|
||||||
safety.unlock();
|
safety.unlock();
|
||||||
}
|
}
|
||||||
relax(50);
|
relax(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
#include <ptypes/pasync.h>
|
#include <ptypes/pasync.h>
|
||||||
|
|
||||||
#include "nexusmt.h"
|
|
||||||
#include "queuepserver.h"
|
#include "queuepserver.h"
|
||||||
|
|
||||||
namespace nxs {
|
namespace nxs {
|
||||||
|
|
|
@ -4,28 +4,74 @@
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
|
using namespace pt;
|
||||||
|
|
||||||
|
|
||||||
QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
||||||
unsigned short nv, unsigned short nf,
|
unsigned short nv, unsigned short nf,
|
||||||
float priority) {
|
float priority) {
|
||||||
if(index.count(patch)) {
|
if(index.count(patch)) {
|
||||||
return index[patch];
|
Data &data = index[patch];
|
||||||
|
if(priority == 0) {
|
||||||
|
// cerr << "Posting draw!\n";
|
||||||
|
message *msg = new message(DRAW, (unsigned int)&data);
|
||||||
|
msg->result = patch;
|
||||||
|
queue.post(msg);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
} else {
|
} else {
|
||||||
while(ram_used > ram_max) {
|
while(ram_used > ram_max) {
|
||||||
pop_heap(heap.begin(), heap.end());
|
pop_heap(heap.begin(), heap.end());
|
||||||
Item item = heap.back();
|
Item item = heap.back();
|
||||||
if(item.priority == 0) break; //no deleting needed patches.
|
if(item.priority == 0) break; //no deleting needed patches.
|
||||||
Data &data = index[patch];
|
// cerr << "Dropping: " << item.patch << endl;
|
||||||
|
Data &data = index[item.patch];
|
||||||
FlushVbo(data);
|
FlushVbo(data);
|
||||||
FlushPatch(patch, data.patch);
|
Data *d = new Data(data);
|
||||||
index.erase(patch);
|
queue.post(FLUSH, (unsigned int)d);
|
||||||
|
|
||||||
|
FlushPatch(item.patch, data.patch);
|
||||||
|
index.erase(item.patch);
|
||||||
}
|
}
|
||||||
Item item(patch, priority);
|
Item item(patch, priority);
|
||||||
heap.push_back(item);
|
heap.push_back(item);
|
||||||
push_heap(heap.begin(), heap.end());
|
push_heap(heap.begin(), heap.end());
|
||||||
Data &data = index[patch];
|
Data &data = index[patch];
|
||||||
|
// cerr << "Loading: " << patch << endl;
|
||||||
data.patch = LoadPatch(patch, nv, nf);
|
data.patch = LoadPatch(patch, nv, nf);
|
||||||
|
|
||||||
|
if(priority == 0) {
|
||||||
|
message *msg = new message(DRAW, (unsigned int)&data);
|
||||||
|
msg->result = patch;
|
||||||
|
queue.post(msg);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
||||||
|
Patch *mem,
|
||||||
|
float priority) {
|
||||||
|
if(index.count(patch)) {
|
||||||
|
Data &data = index[patch];
|
||||||
|
return data;
|
||||||
|
} else {
|
||||||
|
while(ram_used > ram_max) {
|
||||||
|
pop_heap(heap.begin(), heap.end());
|
||||||
|
Item item = heap.back();
|
||||||
|
if(item.priority == 0) break; //no deleting needed patches.
|
||||||
|
// cerr << "Dropping: " << item.patch << endl;
|
||||||
|
Data &data = index[item.patch];
|
||||||
|
FlushVbo(data);
|
||||||
|
FlushPatch(item.patch, data.patch);
|
||||||
|
index.erase(item.patch);
|
||||||
|
}
|
||||||
|
Item item(patch, priority);
|
||||||
|
heap.push_back(item);
|
||||||
|
push_heap(heap.begin(), heap.end());
|
||||||
|
Data &data = index[patch];
|
||||||
|
// cerr << "Loading: " << patch << endl;
|
||||||
|
data.patch = mem;
|
||||||
LoadVbo(data);
|
LoadVbo(data);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
@ -34,6 +80,12 @@ QueuePServer::Data &QueuePServer::Lookup(unsigned int patch,
|
||||||
bool QueuePServer::IsLoaded(unsigned int patch) {
|
bool QueuePServer::IsLoaded(unsigned int patch) {
|
||||||
return index.count(patch);
|
return index.count(patch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float QueuePServer::MaxPriority() {
|
||||||
|
if(!heap.size()) return 0;
|
||||||
|
return heap.front().priority;
|
||||||
|
}
|
||||||
|
|
||||||
void QueuePServer::Flush() {
|
void QueuePServer::Flush() {
|
||||||
std::map<unsigned int, Data>::iterator i;
|
std::map<unsigned int, Data>::iterator i;
|
||||||
for(i = index.begin(); i != index.end(); i++) {
|
for(i = index.begin(); i != index.end(); i++) {
|
||||||
|
@ -70,12 +122,11 @@ void QueuePServer::LoadVbo(Data &data) {
|
||||||
}
|
}
|
||||||
void QueuePServer::FlushVbo(Data &data) {
|
void QueuePServer::FlushVbo(Data &data) {
|
||||||
if(!vbo_max) return;
|
if(!vbo_max) return;
|
||||||
assert(data.vbo_element);
|
if(!data.vbo_element) return;
|
||||||
assert(data.vbo_array);
|
//glDeleteBuffersARB(1, &data.vbo_element);
|
||||||
glDeleteBuffersARB(1, &data.vbo_element);
|
//glDeleteBuffersARB(1, &data.vbo_array);
|
||||||
glDeleteBuffersARB(1, &data.vbo_array);
|
//data.vbo_element = 0;
|
||||||
data.vbo_element = 0;
|
// data.vbo_array = 0;
|
||||||
data.vbo_array = 0;
|
|
||||||
|
|
||||||
Patch &patch = *data.patch;
|
Patch &patch = *data.patch;
|
||||||
vbo_used -= patch.nf * sizeof(unsigned short);
|
vbo_used -= patch.nf * sizeof(unsigned short);
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include <ptypes/pasync.h>
|
||||||
|
|
||||||
#include "pserver.h"
|
#include "pserver.h"
|
||||||
|
|
||||||
namespace nxs {
|
namespace nxs {
|
||||||
|
@ -12,6 +14,7 @@ namespace nxs {
|
||||||
class QueuePServer: public PServer {
|
class QueuePServer: public PServer {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum Action { DRAW = 1, FLUSH = 0 };
|
||||||
struct Data {
|
struct Data {
|
||||||
Patch *patch;
|
Patch *patch;
|
||||||
unsigned int vbo_array;
|
unsigned int vbo_array;
|
||||||
|
@ -19,6 +22,8 @@ class QueuePServer: public PServer {
|
||||||
Data(): patch(NULL), vbo_array(0), vbo_element(0) {}
|
Data(): patch(NULL), vbo_array(0), vbo_element(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pt::jobqueue queue;
|
||||||
|
|
||||||
unsigned int vbo_used;
|
unsigned int vbo_used;
|
||||||
unsigned int vbo_max;
|
unsigned int vbo_max;
|
||||||
|
|
||||||
|
@ -28,10 +33,11 @@ class QueuePServer: public PServer {
|
||||||
Data &Lookup(unsigned int patch, unsigned short nv, unsigned short nf,
|
Data &Lookup(unsigned int patch, unsigned short nv, unsigned short nf,
|
||||||
float priority = 0.0f);
|
float priority = 0.0f);
|
||||||
|
|
||||||
bool IsLoaded(unsigned int patch);
|
Data &Lookup(unsigned int patch, Patch *mem, float priority = 0.0f);
|
||||||
void Flush();
|
|
||||||
|
|
||||||
protected:
|
bool IsLoaded(unsigned int patch);
|
||||||
|
float MaxPriority();
|
||||||
|
void Flush();
|
||||||
|
|
||||||
void LoadVbo(Data &data);
|
void LoadVbo(Data &data);
|
||||||
void FlushVbo(Data &data);
|
void FlushVbo(Data &data);
|
||||||
|
|
Loading…
Reference in New Issue