From e57f58372dbfeb2e3770400debe0c0a4ed4689a9 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Sun, 17 Apr 2011 18:35:03 +1200 Subject: [PATCH 01/56] Using VBOs and shaders to speed up rendering performance (when available). --- data/shaders/shadow.frag | 8 + data/shaders/shadow.vert | 6 + gource.win32.cbp | 3 + src/core | 2 +- src/dirnode.cpp | 46 ++++-- src/dirnode.h | 13 +- src/file.h | 8 +- src/gource.cpp | 340 ++++++++++++++++++++++++++------------- src/gource.h | 26 ++- src/gource_settings.cpp | 11 +- src/gource_settings.h | 8 +- src/main.cpp | 7 +- src/pawn.h | 5 +- src/user.h | 2 +- src/vbo.cpp | 107 ++++++++++++ src/vbo.h | 61 +++++++ 16 files changed, 507 insertions(+), 146 deletions(-) create mode 100644 data/shaders/shadow.frag create mode 100644 data/shaders/shadow.vert create mode 100644 src/vbo.cpp create mode 100644 src/vbo.h diff --git a/data/shaders/shadow.frag b/data/shaders/shadow.frag new file mode 100644 index 00000000..8b58e3ea --- /dev/null +++ b/data/shaders/shadow.frag @@ -0,0 +1,8 @@ +uniform sampler2D tex; + +void main(void) +{ + vec4 colour = texture2D(tex,gl_TexCoord[0].st); + + gl_FragColor = vec4(0.0, 0.0, 0.0, gl_Color.w * colour.w * 0.5); +} diff --git a/data/shaders/shadow.vert b/data/shaders/shadow.vert new file mode 100644 index 00000000..d1866500 --- /dev/null +++ b/data/shaders/shadow.vert @@ -0,0 +1,6 @@ +void main(void) +{ + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_FrontColor = gl_Color; +} diff --git a/gource.win32.cbp b/gource.win32.cbp index 5bdcdb47..e855c47c 100644 --- a/gource.win32.cbp +++ b/gource.win32.cbp @@ -23,6 +23,7 @@ + @@ -76,6 +77,8 @@ + + diff --git a/src/core b/src/core index 5b7f9ba3..3c71b617 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit 5b7f9ba318a39ad361ecf21de2d2f6ac7079689c +Subproject commit 3c71b617c0d26eb2aaeaecbbeb3a7c26d39db82c diff --git a/src/dirnode.cpp b/src/dirnode.cpp index ead4bfad..dd8a0936 100644 --- a/src/dirnode.cpp +++ b/src/dirnode.cpp @@ -62,7 +62,7 @@ RDirNode::RDirNode(RDirNode* parent, const std::string & abspath) { since_node_visible = 0.0; since_last_file_change = 0.0; since_last_node_change = 0.0; - + calcRadius(); calcColour(); } @@ -97,7 +97,7 @@ int RDirNode::getTokenOffset() const{ void RDirNode::fileUpdated(bool userInitiated) { calcRadius(); - if(userInitiated) since_last_file_change = 0.0; + since_last_file_change = 0.0; nodeUpdated(userInitiated); } @@ -149,13 +149,13 @@ RDirNode* RDirNode::getParent() const{ RDirNode* RDirNode::findDir(const std::string& path) const { if(abspath == path) return (RDirNode*) this; - + for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* match = (*it)->findDir(path); - + if(match) return match; } - + return 0; } @@ -905,7 +905,7 @@ void RDirNode::drawDirName(const FXFont& dirfont) const{ glColor4f(1.0, 1.0, 1.0, alpha); vec2f mid = spline.getMidPoint(); - + dirfont.draw(mid.x, mid.y, path_token); } @@ -938,7 +938,7 @@ void RDirNode::drawNames(const FXFont & dirfont, const Frustum & frustum){ if(!gGourceSettings.hide_filenames) { - if(!(gGourceSettings.hide_filenames || gGourceSettings.hide_files) && frustum.boundsInFrustum(quadItemBounds)) { + if(!(gGourceSettings.hide_filenames || gGourceSettings.hide_files) && frustum.intersects(quadItemBounds)) { for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { RFile* f = *it; f->drawName(); @@ -955,7 +955,7 @@ void RDirNode::drawNames(const FXFont & dirfont, const Frustum & frustum){ void RDirNode::drawShadows(const Frustum & frustum, float dt) const{ - if(frustum.boundsInFrustum(quadItemBounds)) { + if(frustum.intersects(quadItemBounds)) { glPushMatrix(); glTranslatef(pos.x, pos.y, 0.0); @@ -977,9 +977,29 @@ void RDirNode::drawShadows(const Frustum & frustum, float dt) const{ } } +void RDirNode::updateFilesVBO(const Frustum & frustum, qbuf2f& buffer, float dt) const{ + + if(frustum.intersects(quadItemBounds)) { + + for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { + RFile* f = *it; + + vec3f col = f->getColour(); + float alpha = f->getAlpha(); + + buffer.add(f->getAbsolutePos(), vec2f(f->size, f->graphic_ratio*f->size), vec4f(col.x, col.y, col.z, alpha)); + } + } + + for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { + RDirNode* node = (*it); + node->updateFilesVBO(frustum,buffer,dt); + } +} + void RDirNode::drawFiles(const Frustum & frustum, float dt) const{ - if(frustum.boundsInFrustum(quadItemBounds)) { + if(frustum.intersects(quadItemBounds)) { vec4f col = getColour(); @@ -1022,7 +1042,7 @@ void RDirNode::calcProjectedPos() { void RDirNode::drawEdgeShadows(float dt) const{ spline.drawShadow(); - + for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* child = (*it); @@ -1036,7 +1056,7 @@ void RDirNode::drawEdgeShadows(float dt) const{ void RDirNode::drawEdges(float dt) const{ spline.draw(); - + for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* child = (*it); @@ -1049,7 +1069,7 @@ void RDirNode::drawEdges(float dt) const{ void RDirNode::drawBloom(const Frustum & frustum, float dt){ - if(isVisible() && frustum.boundsInFrustum(quadItemBounds)) { + if(isVisible() && frustum.intersects(quadItemBounds)) { float bloom_radius = dir_radius * 2.0 * gGourceSettings.bloom_multiplier; @@ -1084,7 +1104,7 @@ void RDirNode::drawSimple(const Frustum & frustum, float dt) const{ glDisable(GL_TEXTURE_2D); - if(frustum.boundsInFrustum(quadItemBounds)) { + if(frustum.intersects(quadItemBounds)) { glPushMatrix(); glTranslatef(pos.x, pos.y, 0.0); for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { diff --git a/src/dirnode.h b/src/dirnode.h index efb42e02..9a10a725 100644 --- a/src/dirnode.h +++ b/src/dirnode.h @@ -27,6 +27,7 @@ #include "spline.h" #include "file.h" +#include "vbo.h" #include #include @@ -44,7 +45,7 @@ class RDirNode : public QuadItem { std::list files; SplineEdge spline; - + vec4f col; vec2f spos; @@ -102,7 +103,7 @@ class RDirNode : public QuadItem { ~RDirNode(); void printFiles(); - + bool empty() const; bool isAnchor(RDirNode* node) const; @@ -129,7 +130,7 @@ class RDirNode : public QuadItem { bool noFiles() const; bool prefixedBy(const std::string & path) const; - + const std::string & getPath() const; const vec2f & getNodeNormal() const; @@ -151,14 +152,14 @@ class RDirNode : public QuadItem { const std::list* getFiles() const { return &files; }; void getFilesRecursive(std::list& files) const; - + vec3f averageFileColour() const; const vec4f & getColour() const; RDirNode* getParent() const; RDirNode* findDir(const std::string& path) const; - + const vec2f & getPos() const; void calcEdges(); @@ -188,6 +189,8 @@ class RDirNode : public QuadItem { void drawBloom(const Frustum & frustum, float dt); + void updateFilesVBO(const Frustum & frustum, qbuf2f& buffer, float dt) const; + void drawShadows(const Frustum & frustum, float dt) const; void drawFiles(const Frustum & frustum, float dt) const; void drawSimple(const Frustum & frustum, float dt) const; diff --git a/src/file.h b/src/file.h index 40202f8d..542583fa 100644 --- a/src/file.h +++ b/src/file.h @@ -57,9 +57,9 @@ class RFile : public Pawn { bool isExpiring() const { return expiring; } bool isRemoving() const { return removing; } - - bool overlaps(const vec2f& pos) const; - + + bool overlaps(const vec2f& pos) const; + const vec3f & getFileColour() const; vec3f getColour() const; void colourize(); @@ -67,7 +67,7 @@ class RFile : public Pawn { float getAlpha() const; void touch(const vec3f & colour); - + void setSelected(bool selected); void setHidden(bool hidden); diff --git a/src/gource.cpp b/src/gource.cpp index 2d9bd906..95d62857 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -50,6 +50,13 @@ Gource::Gource(FrameExporter* exporter) { bloomtex = texturemanager.grab(bloom_tga); beamtex = texturemanager.grab("beam.png"); + usertex = texturemanager.grab("no_photo.png"); + + shadow_shader = 0; + + if(!gGourceSettings.ffp) { + shadow_shader = shadermanager.grab("shadow"); + } logotex = 0; backgroundtex = 0; @@ -75,10 +82,8 @@ Gource::Gource(FrameExporter* exporter) { mousedragged = false; mouseclicked = false; - if(1) { - cursor.setCursorTexture(texturemanager.grab("cursor.png")); - cursor.useSystemCursor(false); - } + cursor.setCursorTexture(texturemanager.grab("cursor.png")); + cursor.useSystemCursor(false); if(gGourceSettings.hide_mouse) { cursor.showCursor(false); @@ -100,13 +105,13 @@ Gource::Gource(FrameExporter* exporter) { hoverUser = 0; date_x_offset = 0; - + textbox = TextBox(fontmanager.grab("FreeSans.ttf", 18)); textbox.setBrightness(0.5f); textbox.show(); - + file_key = FileKey(1.0f); - + camera = ZoomCamera(vec3f(0,0, -300), vec3f(0.0, 0.0, 0.0), 250.0, 5000.0); camera.setPadding(gGourceSettings.padding); @@ -259,14 +264,14 @@ RCommitLog* Gource::determineFormat(const std::string& logfile) { if(clog->checkFormat()) return clog; delete clog; - + //cvs2cl debugLog("trying cvs2cl...\n"); clog = new CVS2CLCommitLog(logfile); if(clog->checkFormat()) return clog; delete clog; - + //custom debugLog("trying custom...\n"); clog = new CustomLog(logfile); @@ -706,7 +711,7 @@ void Gource::keyPress(SDL_KeyboardEvent *e) { } if (e->keysym.sym == SDLK_u) { - + if(gGourceSettings.hide_usernames && !gGourceSettings.highlight_all_users) { gGourceSettings.hide_usernames = false; gGourceSettings.highlight_all_users = true; @@ -718,12 +723,12 @@ void Gource::keyPress(SDL_KeyboardEvent *e) { gGourceSettings.hide_usernames = true; gGourceSettings.highlight_all_users = false; } - + } if (e->keysym.sym == SDLK_d) { if(gGourceSettings.hide_dirnames && !gGourceSettings.highlight_dirs) { - + gGourceSettings.hide_dirnames = false; gGourceSettings.highlight_dirs = true; @@ -739,7 +744,7 @@ void Gource::keyPress(SDL_KeyboardEvent *e) { } if (e->keysym.sym == SDLK_f) { - + if(gGourceSettings.hide_filenames && !gGourceSettings.file_extensions) { gGourceSettings.hide_filenames = false; } else if(!gGourceSettings.hide_filenames && gGourceSettings.file_extensions) { @@ -747,7 +752,7 @@ void Gource::keyPress(SDL_KeyboardEvent *e) { gGourceSettings.hide_filenames = true; } else { gGourceSettings.file_extensions = true; - gGourceSettings.hide_filenames = false; + gGourceSettings.hide_filenames = false; } } @@ -763,6 +768,12 @@ void Gource::keyPress(SDL_KeyboardEvent *e) { toggleCameraMode(); } + if (e->keysym.sym == SDLK_p) { + if(GLEW_VERSION_2_0) { + gGourceSettings.ffp = !gGourceSettings.ffp; + } + } + if (e->keysym.sym == SDLK_z) { gGourceGravity = !gGourceGravity; } @@ -858,7 +869,7 @@ void Gource::reset() { use_selection_bounds = false; selection_bounds.reset(); - + manual_rotate = false; manual_zoom = false; rotation_remaining_angle = 0.0f; @@ -866,7 +877,7 @@ void Gource::reset() { message_timer = 0.0f; cursor_move = vec2f(0.0f, 0.0f); - + selectedUser = 0; hoverUser = 0; @@ -900,7 +911,7 @@ void Gource::reset() { files.clear(); file_key.clear(); - + idle_time=0; currtime=0; lasttime=0; @@ -938,6 +949,50 @@ void Gource::deleteFile(RFile* file) { delete file; } + +RFile* Gource::addFile(const RCommitFile& cf) { + + int tagid = tag_seq++; + + RFile* file = new RFile(cf.filename, cf.colour, vec2f(0.0,0.0), tagid); + + files[cf.filename] = file; + tagfilemap[tagid] = file; + + root->addFile(file); + + file_key.inc(file); + + while(root->getParent() != 0) { + debugLog("parent changed to %s\n", root->getPath().c_str()); + root = root->getParent(); + } + + return file; +} + +RUser* Gource::addUser(const std::string& username) { + + vec2f pos; + + if(dir_bounds.area() > 0) { + pos = dir_bounds.centre(); + } else { + pos = vec2f(0,0); + } + + int tagid = tag_seq++; + + RUser* user = new RUser(username, pos, tagid); + + users[username] = user; + tagusermap[tagid] = user; + + debugLog("added user %s, tagid = %d\n", username.c_str(), tagid); + + return user; +} + void Gource::deleteUser(RUser* user) { if(hoverUser == user) { @@ -1036,7 +1091,7 @@ void Gource::processCommit(RCommit& commit, float t) { for(std::list::iterator it = commit.files.begin(); it != commit.files.end(); it++) { RCommitFile& cf = *it; - RFile* file = 0; + RFile* file = 0; //check filename against filters if(!gGourceSettings.file_filters.empty()) { @@ -1054,35 +1109,35 @@ void Gource::processCommit(RCommit& commit, float t) { if(filtered_filename) continue; } - + //is this a directory (ends in slash) //deleting a directory - find directory: then for each file, remove each file - + if(!cf.filename.empty() && cf.filename[cf.filename.size()-1] == '/') { //ignore unless it is a delete: we cannot 'add' or 'modify' a directory //as its not a physical entity in Gource, only files are. if(cf.action != "D") continue; - + RDirNode* dir = root->findDir(cf.filename); if(!dir) continue; - + //foreach dir files std::list dir_files; dir->getFilesRecursive(dir_files); - + for(std::list::iterator it = dir_files.begin(); it != dir_files.end(); it++) { RFile* file = *it; - + addFileAction(commit.username, cf.action, file, t); } - + return; - } - + } + std::map::iterator seen_file = files.find(cf.filename); if(seen_file != files.end()) file = seen_file->second; @@ -1093,21 +1148,7 @@ void Gource::processCommit(RCommit& commit, float t) { if(gGourceSettings.max_files > 0 && files.size() >= gGourceSettings.max_files) continue; - int tagid = tag_seq++; - - file = new RFile(cf.filename, cf.colour, vec2f(0.0,0.0), tagid); - - files[cf.filename] = file; - tagfilemap[tagid] = file; - - root->addFile(file); - - file_key.inc(file); - - while(root->getParent() != 0) { - debugLog("parent changed to %s\n", root->getPath().c_str()); - root = root->getParent(); - } + file = addFile(cf); } addFileAction(commit.username, cf.action, file, t); @@ -1126,20 +1167,7 @@ void Gource::addFileAction(const std::string& username, const std::string& actio if(seen_user != users.end()) user = seen_user->second; if(user == 0) { - vec2f pos; - - if(dir_bounds.area() > 0) { - pos = dir_bounds.centre(); - } else { - pos = vec2f(0,0); - } - - int tagid = tag_seq++; - - user = new RUser(username, pos, tagid); - - users[username] = user; - tagusermap[tagid] = user; + user = addUser(username); // set the highlighted flag if name matches a highlighted user for(std::vector::iterator hi = gGourceSettings.highlight_users.begin(); hi != gGourceSettings.highlight_users.end(); hi++) { @@ -1150,8 +1178,6 @@ void Gource::addFileAction(const std::string& username, const std::string& actio break; } } - - debugLog("added user %s, tagid = %d\n", username.c_str(), tagid); } //create action @@ -1230,7 +1256,7 @@ void Gource::updateBounds() { if(!user->isIdle()) { active_user_bounds.update(user->quadItemBounds); } - + } dir_bounds.reset(); @@ -1363,22 +1389,22 @@ void Gource::updateCamera(float dt) { bool auto_rotate = !manual_rotate && !gGourceSettings.disable_auto_rotate; - + if(manual_camera) { if(cursor_move.length2() > 0.0f) { float cam_rate = ( -camera.getPos().z ) / ( 5000.0f ); - + vec3f cam_pos = camera.getPos(); - + vec2f cursor_delta = cursor_move * cam_rate * 400.0f * dt; - + cam_pos.x += cursor_delta.x; cam_pos.y += cursor_delta.y; - + camera.setPos(cam_pos, true); - camera.stop(); + camera.stop(); auto_rotate = false; @@ -1438,7 +1464,7 @@ void Gource::updateCamera(float dt) { void Gource::changeColours() { gStringHashSeed = (rand() % 10000) + 1; - + for(std::map::iterator it = users.begin(); it != users.end(); it++) { it->second->colourize(); } @@ -1446,7 +1472,7 @@ void Gource::changeColours() { for(std::map::iterator it = files.begin(); it != files.end(); it++) { it->second->colourize(); } - + file_key.colourize(); } @@ -1513,7 +1539,7 @@ void Gource::logic(float t, float dt) { cursor_move.y = 10.0; manual_camera = true; } - + //apply rotation if(rotate_angle != 0.0f) { @@ -1637,14 +1663,14 @@ void Gource::mousetrace(Frustum& frustum, float dt) { glPopMatrix(); //find user/file under mouse - + RFile* fileSelection = 0; RUser* userSelection = 0; std::set userset; - + userTree->getItemsAt(userset, projected_mouse); - + for(std::set::iterator it = userset.begin(); it != userset.end(); it++) { RUser* user = (RUser*) *it; if(!user->isFading() && user->quadItemBounds.contains(projected_mouse)) { @@ -1654,21 +1680,21 @@ void Gource::mousetrace(Frustum& frustum, float dt) { } if(!userSelection) { - + std::set dirset; dirNodeTree->getItemsAt(dirset, projected_mouse); - + for(std::set::iterator it = dirset.begin(); it != dirset.end(); it++) { RDirNode* dir = (RDirNode*) *it; - - const std::list* files = dir->getFiles(); - + + const std::list* files = dir->getFiles(); + for(std::list::const_iterator fi = files->begin(); fi != files->end(); fi++) { - - RFile* file = *fi; - + + RFile* file = *fi; + if(!file->isHidden() && file->overlaps(projected_mouse)) { fileSelection = file; break; @@ -1729,8 +1755,8 @@ void Gource::mousetrace(Frustum& frustum, float dt) { selectBackground(); } } - - //fprintf(stderr, "end trace\n"); + + //fprintf(stderr, "end trace\n"); } void Gource::loadingScreen() { @@ -1820,34 +1846,22 @@ void Gource::drawTree(Frustum& frustum, float dt) { glMatrixMode(GL_MODELVIEW); glPopMatrix(); + //update file and user vbos + updateVBOs(frustum, dt); + glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //draw shadows - if(!gGourceSettings.hide_users) { - for(std::map::iterator it = users.begin(); it!=users.end(); it++) { - it->second->drawShadow(dt); - } - } + drawUserShadows(frustum, dt); - if(!gGourceSettings.hide_files) { - root->drawShadows(frustum, dt); - } + drawFileShadows(frustum, dt); drawActions(dt); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - if(!trace_debug) { - if(!gGourceSettings.hide_files) { - root->drawFiles(frustum,dt); - } - } else { - root->drawSimple(frustum,dt); - } + drawFiles(frustum, dt); draw_tree_time = SDL_GetTicks() - draw_tree_time; } @@ -1940,6 +1954,118 @@ void Gource::screenshot() { setMessage("Wrote screenshot %s", tganame); } +void Gource::updateVBOs(const Frustum& frustum, float dt) { + if(gGourceSettings.ffp) return; + + user_vbo.reset(); + for(std::map::iterator it = users.begin(); it!=users.end(); it++) { + RUser* user = it->second; + + float alpha = user->getAlpha(); + vec3f col = user->getColour(); + + user_vbo.add(user->getPos(), vec2f(user->size, user->graphic_ratio*user->size), vec4f(col.x, col.y, col.z, alpha)); + } + user_vbo.update(); + + file_vbo.reset(); + root->updateFilesVBO(frustum, file_vbo, dt); + file_vbo.update(); +} + +void Gource::drawFileShadows(const Frustum& frustum, float dt) { + if(gGourceSettings.hide_files) return; + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if(!gGourceSettings.ffp) { + + shadow_shader->use(); + + glBindTexture(GL_TEXTURE_2D, gGourceSettings.file_graphic->textureid); + + glPushMatrix(); + glTranslatef(2.0f, 2.0f, 0.0f); + file_vbo.draw(); + glPopMatrix(); + + glUseProgramObjectARB(0); + } else { + root->drawShadows(frustum, dt); + } +} + +void Gource::drawUserShadows(const Frustum& frustum, float dt) { + if(gGourceSettings.hide_users) return; + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if(!gGourceSettings.ffp) { + + shadow_shader->use(); + + glBindTexture(GL_TEXTURE_2D, usertex->textureid); + + vec2f shadow_offset = vec2f(2.0, 2.0) * gGourceSettings.user_scale; + + glPushMatrix(); + glTranslatef(shadow_offset.x, shadow_offset.y, 0.0f); + user_vbo.draw(); + glPopMatrix(); + + glUseProgramObjectARB(0); + } else { + for(std::map::iterator it = users.begin(); it!=users.end(); it++) { + it->second->drawShadow(dt); + } + } +} + +void Gource::drawFiles(const Frustum& frustum, float dt) { + if(gGourceSettings.hide_files) return; + + if(trace_debug) { + root->drawSimple(frustum,dt); + return; + } + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if(!gGourceSettings.ffp) { + glBindTexture(GL_TEXTURE_2D, gGourceSettings.file_graphic->textureid); + + file_vbo.draw(); + } else { + root->drawFiles(frustum, dt); + } +} + +void Gource::drawUsers(float dt) { + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + if(!gGourceSettings.ffp) { + + glBindTexture(GL_TEXTURE_2D, usertex->textureid); + + user_vbo.draw(); + + } else { + + for(std::map::iterator it = users.begin(); it!=users.end(); it++) { + trace_debug ? it->second->drawSimple(dt) : it->second->draw(dt); + } + } + +} + void Gource::draw(float t, float dt) { display.mode2D(); @@ -1982,10 +2108,7 @@ void Gource::draw(float t, float dt) { //draw tree drawTree(frustum, dt); - glColor4f(1.0, 1.0, 0.0, 1.0); - for(std::map::iterator it = users.begin(); it!=users.end(); it++) { - trace_debug ? it->second->drawSimple(dt) : it->second->draw(dt); - } + drawUsers(dt); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); @@ -2148,12 +2271,12 @@ void Gource::draw(float t, float dt) { slider.draw(dt); } - //text box + //text box if(hoverFile && hoverFile != selectedFile) { - + std::string display_path = hoverFile->path; display_path.erase(0,1); - + textbox.setText(hoverFile->getName()); if(display_path.size()) textbox.addLine(display_path); textbox.setColour(hoverFile->getColour()); @@ -2164,7 +2287,7 @@ void Gource::draw(float t, float dt) { textbox.setText(hoverUser->getName()); textbox.setColour(hoverUser->getColour()); - + textbox.setPos(mousepos, true); textbox.draw(); } @@ -2178,7 +2301,7 @@ void Gource::draw(float t, float dt) { glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); - + font.print(1,20, "FPS: %.2f", fps); font.print(1,40,"Days Per Second: %.2f", gGourceSettings.days_per_second); @@ -2201,6 +2324,7 @@ void Gource::draw(float t, float dt) { dirNodeTree->item_count, dirNodeTree->node_count, dirNodeTree->max_node_depth); font.print(1,360,"Dir Bounds Ratio: %.2f, %.5f", dir_bounds.width() / dir_bounds.height(), rotation_remaining_angle); font.print(1,380,"String Hash Seed: %d", gStringHashSeed); + font.print(1,400,"File VBO %d/%d vertices", file_vbo.size() , file_vbo.capacity()); if(selectedUser != 0) { diff --git a/src/gource.h b/src/gource.h index f7bbd0f4..c4ec04e9 100644 --- a/src/gource.h +++ b/src/gource.h @@ -26,6 +26,7 @@ #include #include "core/display.h" +#include "core/shader.h" #include "core/sdlapp.h" #include "core/fxfont.h" #include "core/bounds.h" @@ -47,6 +48,7 @@ #include "apache.h" #include "svn.h" +#include "vbo.h" #include "slider.h" #include "textbox.h" #include "action.h" @@ -82,14 +84,13 @@ class Gource : public SDLApp { bool mouseclicked; bool mousedragged; - vec2f cursor_move; - + bool recolour; - + bool use_selection_bounds; Bounds2D selection_bounds; - + float rotate_angle; vec2f mousepos; @@ -108,6 +109,9 @@ class Gource : public SDLApp { RUser* hoverUser; RUser* selectedUser; + qbuf2f user_vbo; + qbuf2f file_vbo; + GLuint selectionDepth; RDirNode* root; @@ -119,9 +123,12 @@ class Gource : public SDLApp { TextureResource* beamtex; TextureResource* logotex; TextureResource* backgroundtex; + TextureResource* usertex; + Shader* shadow_shader; + TextBox textbox; - + FXFont font, fontlarge, fontmedium; bool first_read; @@ -172,6 +179,9 @@ class Gource : public SDLApp { void reset(); + RUser* addUser(const std::string& username); + RFile* addFile(const RCommitFile& cf); + void deleteUser(RUser* user); void deleteFile(RFile* file); @@ -215,6 +225,12 @@ class Gource : public SDLApp { void drawActions(float dt); void drawTree(Frustum &frustum, float dt); void drawBloom(Frustum &frustum, float dt); + void drawFileShadows(const Frustum& frustum, float dt); + void drawUserShadows(const Frustum& frustum, float dt); + void drawFiles(const Frustum& frustum, float dt); + void updateVBOs(const Frustum& frustum, float dt); + + void drawUsers(float dt); void screenshot(); diff --git a/src/gource_settings.cpp b/src/gource_settings.cpp index adc93f9a..9df02125 100644 --- a/src/gource_settings.cpp +++ b/src/gource_settings.cpp @@ -122,7 +122,7 @@ if(extended_help) { printf(" --highlight-dirs Highlight the names of all directories\n"); printf(" --highlight-colour Font colour for highlighted text\n\n"); - printf(" --hash-seed SEED Change the seed of hash function.\n\n"); + printf(" --hash-seed SEED Change the seed of hash function\n\n"); printf(" --path PATH\n\n"); } @@ -205,6 +205,7 @@ GourceSettings::GourceSettings() { arg_types["highlight-dirs"] = "bool"; arg_types["file-extensions"] = "bool"; arg_types["key"] = "bool"; + arg_types["ffp"] = "bool"; arg_types["disable-auto-rotate"] = "bool"; arg_types["disable-auto-skip"] = "bool"; @@ -268,6 +269,8 @@ void GourceSettings::setGourceDefaults() { path = "."; + ffp = false; + hide_date = false; hide_users = false; hide_tree = false; @@ -330,7 +333,7 @@ void GourceSettings::setGourceDefaults() { log_format = ""; date_format = "%A, %d %B, %Y %X"; - max_files = 1000; + max_files = 0; max_user_speed = 500.0f; max_file_lag = 5.0f; @@ -897,6 +900,10 @@ void GourceSettings::importGourceSettings(ConfFile& conffile, ConfSection* gourc show_key = true; } + if(gource_settings->getBool("ffp")) { + ffp = true; + } + if(gource_settings->getBool("realtime")) { days_per_second = 1.0 / 86400.0; } diff --git a/src/gource_settings.h b/src/gource_settings.h index 57b08e38..346935b6 100644 --- a/src/gource_settings.h +++ b/src/gource_settings.h @@ -52,7 +52,7 @@ class GourceSettings : public SDLAppSettings { bool disable_auto_rotate; bool show_key; - + std::string load_config; std::string save_config; std::string path; @@ -74,6 +74,8 @@ class GourceSettings : public SDLAppSettings { bool loop; + bool ffp; + bool colour_user_images; std::string default_user_image; std::string user_image_dir; @@ -115,13 +117,13 @@ class GourceSettings : public SDLAppSettings { bool highlight_dirs; bool highlight_all_users; vec3f highlight_colour; - + std::vector highlight_users; std::vector follow_users; std::vector file_filters; std::vector user_filters; bool file_extensions; - + std::string output_custom_filename; TextureResource* file_graphic; diff --git a/src/main.cpp b/src/main.cpp index 35f8150e..58347727 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -91,12 +91,12 @@ int main(int argc, char *argv[]) { conf.save(gGourceSettings.save_config); exit(0); } - + //write custom log file if(gGourceSettings.output_custom_filename.size() > 0 && gGourceSettings.path.size() > 0) { Gource::writeCustomLog(gGourceSettings.path, gGourceSettings.output_custom_filename); - exit(0); + exit(0); } } catch(ConfFileException& exception) { @@ -121,6 +121,9 @@ int main(int argc, char *argv[]) { display.init("Gource", gGourceSettings.display_width, gGourceSettings.display_height, gGourceSettings.fullscreen); + //disable OpenGL 2.0 functions if not supported + if(!GLEW_VERSION_2_0) gGourceSettings.ffp = true; + } catch(SDLInitException& exception) { char errormsg[1024]; diff --git a/src/pawn.h b/src/pawn.h index 622cb340..cde0e23a 100644 --- a/src/pawn.h +++ b/src/pawn.h @@ -36,7 +36,6 @@ class Pawn : public QuadItem { std::string name; float namewidth; - float size; vec2f accel; float speed; @@ -56,7 +55,6 @@ class Pawn : public QuadItem { FXFont font; - float graphic_ratio; TextureResource* graphic; bool mouseover; @@ -68,6 +66,9 @@ class Pawn : public QuadItem { protected: bool selected; public: + float size; + float graphic_ratio; + Pawn(const std::string& name, vec2f pos, int tagid); const vec2f & getPos() const { return pos; } void setPos(vec2f pos); diff --git a/src/user.h b/src/user.h index 1a6362d1..c8891c61 100644 --- a/src/user.h +++ b/src/user.h @@ -62,7 +62,7 @@ class RUser : public Pawn { vec3f getColour() const; void colourize(); - + const std::string& getName() const; void fileRemoved(RFile* f); diff --git a/src/vbo.cpp b/src/vbo.cpp new file mode 100644 index 00000000..0895ec89 --- /dev/null +++ b/src/vbo.cpp @@ -0,0 +1,107 @@ +/* + Copyright (C) 2011 Andrew Caudwell (acaudwell@gmail.com) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "vbo.h" + +qbuf2f_vertex::qbuf2f_vertex() { +} + +//qbuf2f + +qbuf2f::qbuf2f() { + bufferid = 0; + item_count = 0; + fprintf(stderr, "size of qbuf2f_vertex = %d\n", sizeof(qbuf2f_vertex)); +} + +qbuf2f::~qbuf2f() { + if(bufferid !=0) glDeleteBuffers(1, &bufferid); +} + +void qbuf2f::reset() { + data.resize(0); + item_count = 0; +} + +size_t qbuf2f::size() { + return data.size(); +} + +size_t qbuf2f::capacity() { + return data.capacity(); +} + +vec4f qbuf2f_default_texcoord(0.0f, 0.0f, 1.0f, 1.0f); + +void qbuf2f::add(const vec2f& pos, const vec2f& dims, const vec4f& colour) { + add(pos, dims, colour, qbuf2f_default_texcoord); +} + +void qbuf2f::add(const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord) { + //debugLog("%d: %.2f, %.2f, %.2f, %.2f\n", i, pos.x, pos.y, dims.x, dims.y); + + vec2f offset = pos - dims * 0.5; + + qbuf2f_vertex v1(offset, colour, vec2f(texcoord.x, texcoord.y)); + qbuf2f_vertex v2(offset + vec2f(dims.x, 0.0f), colour, vec2f(texcoord.z, texcoord.y)); + qbuf2f_vertex v3(offset + dims, colour, vec2f(texcoord.z, texcoord.w)); + qbuf2f_vertex v4(offset + vec2f(0.0f, dims.y), colour, vec2f(texcoord.x, texcoord.w)); + + int i = data.size(); + + data.resize(data.size()+4); + + data[i] = v1; + data[i+1] = v2; + data[i+2] = v3; + data[i+3] = v4; +} + +#define BUFFER_OFFSET(i) ((char *)NULL + (i)) + +void qbuf2f::update() { + //note possibly better to have a queue and cycle them here + if(bufferid==0) { + glGenBuffers(1, &bufferid); + } + + glBindBuffer(GL_ARRAY_BUFFER, bufferid); + glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(qbuf2f_vertex), &(data[0].pos.x), GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void qbuf2f::draw() { + if(data.empty() || bufferid==0) return; + + glBindBuffer(GL_ARRAY_BUFFER, bufferid); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glVertexPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), BUFFER_OFFSET(0)); // stride over colour (4) + texcoord (2) + glColorPointer(4, GL_FLOAT, sizeof(qbuf2f_vertex), BUFFER_OFFSET(8)); // stride over texcoord (2) + pos (2), offset pos(2) + glTexCoordPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), BUFFER_OFFSET(24)); // stride over pos (2) + colour (4), offset pos(2) + colour(4) + + glDrawArrays(GL_QUADS, 0, data.size()); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glBindBuffer(GL_ARRAY_BUFFER, 0); +} diff --git a/src/vbo.h b/src/vbo.h new file mode 100644 index 00000000..4a382361 --- /dev/null +++ b/src/vbo.h @@ -0,0 +1,61 @@ +/* + Copyright (C) 2011 Andrew Caudwell (acaudwell@gmail.com) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef GOURCE_VBO_H +#define GOURCE_VBO_H + +#include + +#include "core/display.h" +#include "core/vectors.h" +#include "core/logger.h" + +//note this should be 32 bytes (8x4 bytes) +class qbuf2f_vertex { +public: + qbuf2f_vertex(); + qbuf2f_vertex(const vec2f& pos, const vec4f& colour, const vec2f& texcoord) : pos(pos), colour(colour), texcoord(texcoord) {}; + + vec2f pos; + vec4f colour; + vec2f texcoord; +}; + +class qbuf2f { + + std::vector data; + + GLuint bufferid; + + int item_count; +public: + qbuf2f(); + ~qbuf2f(); + + void reset(); + + size_t size(); + size_t capacity(); + + void add(const vec2f& pos, const vec2f& dims, const vec4f& colour); + void add(const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord); + + void update(); + void draw(); +}; + +#endif From 39b7ce29f3cd60b86d35fe64cd4915b2808be27c Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Sun, 17 Apr 2011 18:40:15 +1200 Subject: [PATCH 02/56] Fixed project file. --- gource.win32.cbp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/gource.win32.cbp b/gource.win32.cbp index e855c47c..ec4db92b 100644 --- a/gource.win32.cbp +++ b/gource.win32.cbp @@ -33,6 +33,8 @@ + + @@ -73,12 +75,12 @@ + + - - @@ -124,6 +126,8 @@ + + From 5c0c72fecdd1c56e284ba9e947c81243a8290db7 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Sun, 17 Apr 2011 20:12:27 +1000 Subject: [PATCH 03/56] Commented out debug message. --- src/vbo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vbo.cpp b/src/vbo.cpp index 0895ec89..2fffb5cc 100644 --- a/src/vbo.cpp +++ b/src/vbo.cpp @@ -25,7 +25,7 @@ qbuf2f_vertex::qbuf2f_vertex() { qbuf2f::qbuf2f() { bufferid = 0; item_count = 0; - fprintf(stderr, "size of qbuf2f_vertex = %d\n", sizeof(qbuf2f_vertex)); + //fprintf(stderr, "size of qbuf2f_vertex = %d\n", sizeof(qbuf2f_vertex)); } qbuf2f::~qbuf2f() { From cbaa9bca05e0e6872ecf717d210ff8deeda54865 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Sun, 17 Apr 2011 20:12:42 +1000 Subject: [PATCH 04/56] Added missing files to Makefile.am. --- Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Makefile.am b/Makefile.am index fac203f0..e3772051 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,6 +24,7 @@ gource_SOURCES = \ src/core/sdlapp.cpp src/core/sdlapp.h \ src/core/seeklog.cpp src/core/seeklog.h \ src/core/settings.cpp src/core/settings.h \ + src/core/shader.cpp src/core/shader.h \ src/core/stringhash.cpp src/core/stringhash.h \ src/core/texture.cpp src/core/texture.h \ src/core/utf8/checked.h \ @@ -50,6 +51,7 @@ gource_SOURCES = \ src/svn.cpp src/svn.h \ src/textbox.cpp src/textbox.h \ src/user.cpp src/user.h \ + src/vbo.cpp src/vbo.h \ src/zoomcamera.cpp src/zoomcamera.h CPPFLAGS = -DSDLAPP_RESOURCE_DIR=\"$(pkgdatadir)\" From 2d9be07bd606b87f0815e72a49950591f173e488 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 18 Apr 2011 12:44:08 +1200 Subject: [PATCH 05/56] Removed 'drawSimple' methods. glDisable(GL_TEXTURE_2D) achieves the same thing. --- src/dirnode.cpp | 39 --------------------------------------- src/dirnode.h | 1 - src/pawn.cpp | 35 ----------------------------------- src/pawn.h | 6 ++---- 4 files changed, 2 insertions(+), 79 deletions(-) diff --git a/src/dirnode.cpp b/src/dirnode.cpp index dd8a0936..4c179f33 100644 --- a/src/dirnode.cpp +++ b/src/dirnode.cpp @@ -1018,8 +1018,6 @@ void RDirNode::drawFiles(const Frustum & frustum, float dt) const{ glPopMatrix(); } - glDisable(GL_TEXTURE_2D); - for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* node = (*it); node->drawFiles(frustum,dt); @@ -1100,43 +1098,6 @@ void RDirNode::drawBloom(const Frustum & frustum, float dt){ } } -void RDirNode::drawSimple(const Frustum & frustum, float dt) const{ - - glDisable(GL_TEXTURE_2D); - - if(frustum.intersects(quadItemBounds)) { - glPushMatrix(); - glTranslatef(pos.x, pos.y, 0.0); - for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { - RFile* f = *it; - f->drawSimple(dt); - } - glPopMatrix(); - } - - for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { - RDirNode* node = (*it); - node->drawSimple(frustum,dt); - } - - if(gGourceNodeDebug) { - glColor4f(1.0, 1.0, 1.0, 1.0); - - vec2f vel_offset = pos + vel.normal() * 10.0; - - glBegin(GL_LINES); - glVertex2fv(pos); - glVertex2fv(vel_offset); - glEnd(); - - glColor4f(1.0, 1.0, 0.0, 1.0); - - glLineWidth(1.0); - - quadItemBounds.draw(); - } -} - void RDirNode::updateQuadItemBounds() { float radius = getRadius(); diff --git a/src/dirnode.h b/src/dirnode.h index 9a10a725..445a828f 100644 --- a/src/dirnode.h +++ b/src/dirnode.h @@ -193,7 +193,6 @@ class RDirNode : public QuadItem { void drawShadows(const Frustum & frustum, float dt) const; void drawFiles(const Frustum & frustum, float dt) const; - void drawSimple(const Frustum & frustum, float dt) const; void drawNames(const FXFont & dirfont, const Frustum & frustum); void calcScreenPos(); diff --git a/src/pawn.cpp b/src/pawn.cpp index bce1be7d..3ef68d74 100644 --- a/src/pawn.cpp +++ b/src/pawn.cpp @@ -146,38 +146,6 @@ void Pawn::drawName() const { } } -void Pawn::drawSimple(float dt) { - if(isHidden()) return; - - glLoadName(tagid); - - float halfsize = size * 0.5f; - vec2f offsetpos = pos - vec2f(halfsize, halfsize*graphic_ratio); - - float alpha = getAlpha(); - vec3f col = getColour(); - - glColor4f(col.x, col.y, col.z, alpha); - - glPushMatrix(); - glTranslatef(offsetpos.x, offsetpos.y, 0.0f); - - glBegin(GL_QUADS); - glTexCoord2f(0.0f,0.0f); - glVertex2f(0.0f, 0.0f); - - glTexCoord2f(1.0f,0.0f); - glVertex2f(size, 0.0f); - - glTexCoord2f(1.0f,1.0f); - glVertex2f(size, size*graphic_ratio); - - glTexCoord2f(0.0f,1.0f); - glVertex2f(0.0f, size*graphic_ratio); - glEnd(); - - glPopMatrix(); -} void Pawn::drawShadow(float dt) { if(isHidden() || !shadow) return; @@ -212,9 +180,6 @@ void Pawn::drawShadow(float dt) { void Pawn::draw(float dt) { if(hidden) return; - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D); - float halfsize = size * 0.5f; vec2f offsetpos = pos - vec2f(halfsize, halfsize*graphic_ratio); diff --git a/src/pawn.h b/src/pawn.h index cde0e23a..880fbae1 100644 --- a/src/pawn.h +++ b/src/pawn.h @@ -54,9 +54,7 @@ class Pawn : public QuadItem { int tagid; FXFont font; - - TextureResource* graphic; - + bool mouseover; virtual bool nameVisible() const; @@ -68,6 +66,7 @@ class Pawn : public QuadItem { public: float size; float graphic_ratio; + TextureResource* graphic; Pawn(const std::string& name, vec2f pos, int tagid); const vec2f & getPos() const { return pos; } @@ -99,7 +98,6 @@ class Pawn : public QuadItem { void logic(float dt); void draw(float dt); void drawShadow(float dt); - void drawSimple(float dt); void drawName() const; }; From 1e8bada01764b55bee7e0a4ed0ebdf6602a311ad Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 18 Apr 2011 13:15:46 +1200 Subject: [PATCH 06/56] Don't call update() if data is empty. --- src/vbo.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/vbo.cpp b/src/vbo.cpp index 2fffb5cc..1f8576a2 100644 --- a/src/vbo.cpp +++ b/src/vbo.cpp @@ -71,9 +71,9 @@ void qbuf2f::add(const vec2f& pos, const vec2f& dims, const vec4f& colour, const data[i+3] = v4; } -#define BUFFER_OFFSET(i) ((char *)NULL + (i)) - void qbuf2f::update() { + if(data.empty()) return; + //note possibly better to have a queue and cycle them here if(bufferid==0) { glGenBuffers(1, &bufferid); @@ -93,9 +93,9 @@ void qbuf2f::draw() { glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), BUFFER_OFFSET(0)); // stride over colour (4) + texcoord (2) - glColorPointer(4, GL_FLOAT, sizeof(qbuf2f_vertex), BUFFER_OFFSET(8)); // stride over texcoord (2) + pos (2), offset pos(2) - glTexCoordPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), BUFFER_OFFSET(24)); // stride over pos (2) + colour (4), offset pos(2) + colour(4) + glVertexPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), 0); + glColorPointer(4, GL_FLOAT, sizeof(qbuf2f_vertex), (GLvoid*)8); // offset pos (2x4 bytes) + glTexCoordPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), (GLvoid*)24); // offset pos + colour (2x4 + 4x4 bytes) glDrawArrays(GL_QUADS, 0, data.size()); From 53dac0659f7425d10b2fc40e04b442bbba4368b0 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 18 Apr 2011 13:16:52 +1200 Subject: [PATCH 07/56] One VBO per user graphic to support avatars. Effectively there is one VBO for all users with the default image, and an additional VBO per custom user image. --- src/gource.cpp | 76 +++++++++++++++++++++++++++++++++++--------------- src/gource.h | 3 +- 2 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/gource.cpp b/src/gource.cpp index 95d62857..277674a5 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -855,7 +855,7 @@ void Gource::reset() { tagfilemap.clear(); tagusermap.clear(); gGourceRemovedFiles.clear(); - + if(userTree!=0) delete userTree; if(dirNodeTree!=0) delete dirNodeTree; @@ -901,6 +901,14 @@ void Gource::reset() { users.clear(); + //delete user vbos + for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { + delete it->second; + } + + user_vbos.clear(); + + //delete for(std::map::iterator it = files.begin(); it != files.end(); it++) { delete it->second; @@ -1957,16 +1965,29 @@ void Gource::screenshot() { void Gource::updateVBOs(const Frustum& frustum, float dt) { if(gGourceSettings.ffp) return; - user_vbo.reset(); + for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { + it->second->reset(); + } + + //use a separate vbo for each user texture for(std::map::iterator it = users.begin(); it!=users.end(); it++) { RUser* user = it->second; + qbuf2f* user_vbo = user_vbos[user->graphic->textureid]; + + if(!user_vbo) { + user_vbos[user->graphic->textureid] = user_vbo = new qbuf2f(); + } + float alpha = user->getAlpha(); vec3f col = user->getColour(); - user_vbo.add(user->getPos(), vec2f(user->size, user->graphic_ratio*user->size), vec4f(col.x, col.y, col.z, alpha)); + user_vbo->add(user->getPos(), vec2f(user->size, user->graphic_ratio*user->size), vec4f(col.x, col.y, col.z, alpha)); + } + + for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { + it->second->update(); } - user_vbo.update(); file_vbo.reset(); root->updateFilesVBO(frustum, file_vbo, dt); @@ -1975,8 +1996,7 @@ void Gource::updateVBOs(const Frustum& frustum, float dt) { void Gource::drawFileShadows(const Frustum& frustum, float dt) { if(gGourceSettings.hide_files) return; - - glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -1999,8 +2019,7 @@ void Gource::drawFileShadows(const Frustum& frustum, float dt) { void Gource::drawUserShadows(const Frustum& frustum, float dt) { if(gGourceSettings.hide_users) return; - - glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2008,13 +2027,16 @@ void Gource::drawUserShadows(const Frustum& frustum, float dt) { shadow_shader->use(); - glBindTexture(GL_TEXTURE_2D, usertex->textureid); - vec2f shadow_offset = vec2f(2.0, 2.0) * gGourceSettings.user_scale; - + glPushMatrix(); glTranslatef(shadow_offset.x, shadow_offset.y, 0.0f); - user_vbo.draw(); + + for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { + glBindTexture(GL_TEXTURE_2D, it->first); + it->second->draw(); + } + glPopMatrix(); glUseProgramObjectARB(0); @@ -2028,12 +2050,13 @@ void Gource::drawUserShadows(const Frustum& frustum, float dt) { void Gource::drawFiles(const Frustum& frustum, float dt) { if(gGourceSettings.hide_files) return; + if(trace_debug) { - root->drawSimple(frustum,dt); - return; + glDisable(GL_TEXTURE_2D); + } else { + glEnable(GL_TEXTURE_2D); } - glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2047,20 +2070,28 @@ void Gource::drawFiles(const Frustum& frustum, float dt) { } void Gource::drawUsers(float dt) { + if(gGourceSettings.hide_users) return; - glEnable(GL_TEXTURE_2D); + if(trace_debug) { + glDisable(GL_TEXTURE_2D); + } else { + glEnable(GL_TEXTURE_2D); + } + glEnable(GL_BLEND); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if(!gGourceSettings.ffp) { - - glBindTexture(GL_TEXTURE_2D, usertex->textureid); - - user_vbo.draw(); + + for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { + glBindTexture(GL_TEXTURE_2D, it->first); + it->second->draw(); + } } else { for(std::map::iterator it = users.begin(); it!=users.end(); it++) { - trace_debug ? it->second->drawSimple(dt) : it->second->draw(dt); + it->second->draw(dt); } } @@ -2324,7 +2355,8 @@ void Gource::draw(float t, float dt) { dirNodeTree->item_count, dirNodeTree->node_count, dirNodeTree->max_node_depth); font.print(1,360,"Dir Bounds Ratio: %.2f, %.5f", dir_bounds.width() / dir_bounds.height(), rotation_remaining_angle); font.print(1,380,"String Hash Seed: %d", gStringHashSeed); - font.print(1,400,"File VBO %d/%d vertices", file_vbo.size() , file_vbo.capacity()); + font.print(1,400,"File VBO: %d/%d vertices", file_vbo.size() , file_vbo.capacity()); + font.print(1,420,"User VBOs: %d", user_vbos.size()); if(selectedUser != 0) { diff --git a/src/gource.h b/src/gource.h index c4ec04e9..14d486f1 100644 --- a/src/gource.h +++ b/src/gource.h @@ -109,7 +109,8 @@ class Gource : public SDLApp { RUser* hoverUser; RUser* selectedUser; - qbuf2f user_vbo; + std::map user_vbos; + qbuf2f file_vbo; GLuint selectionDepth; From d9f99a7e000e6aa0363507bd1096eb406d1ceaca Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 5 Apr 2011 13:46:29 +1200 Subject: [PATCH 08/56] Fixed log parsing of Bazaar merges and tagged commits. --output-custom-log now skips unparsed log entries instead of exiting. --- ChangeLog | 4 ++++ src/bzr.cpp | 2 +- src/gource.cpp | 14 ++++++++++++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 550153cf..c2d1314e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +0.33: + * Fixed log parsing of Bazaar merges and tagged commits. + * --output-custom-log now skips unparsed log entries instead of exiting. + 0.32: * Fixed behaviour of user camera tracking. diff --git a/src/bzr.cpp b/src/bzr.cpp index f93d79bc..527cbfae 100644 --- a/src/bzr.cpp +++ b/src/bzr.cpp @@ -17,7 +17,7 @@ #include "bzr.h" -Regex bzr_commit_regex("^ *([\\d.]+) (.+)\t(\\d{4})-(\\d+)-(\\d+)$"); +Regex bzr_commit_regex("^ *([\\d.]+) (.+)\t(\\d{4})-(\\d+)-(\\d+)(?: \\{[^}]+})?(?: \\[merge\\])?$"); Regex bzr_file_regex("^ *([AMDR]) (.*[^/])$"); // parse Bazaar log entries (using the gource.style template) diff --git a/src/gource.cpp b/src/gource.cpp index 277674a5..084fc537 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -148,16 +148,26 @@ void Gource::writeCustomLog(const std::string& logfile, const std::string& outpu if(!fh) return; } - while(commitlog->nextCommit(commit)) { + while(!commitlog->isFinished()) { + + RCommit commit; + + if(!commitlog->nextCommit(commit)) { + if(!commitlog->isSeekable()) { + break; + } + continue; + } + for(std::list::iterator it = commit.files.begin(); it != commit.files.end(); it++) { RCommitFile& cf = *it; fprintf(fh, "%lld|%s|%s|%s\n", (long long int) commit.timestamp, commit.username.c_str(), cf.action.c_str(), cf.filename.c_str()); } + commit.files.clear(); } if(output_file != "-") fclose(fh); - } RCommitLog* Gource::determineFormat(const std::string& logfile) { From 5627a38bfc400a6ff9947661f9ecb7760aaad524 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 5 Apr 2011 13:55:05 +1200 Subject: [PATCH 09/56] Added --hide root option to not draw branches from the root directory. --- ChangeLog | 1 + README | 1 + data/gource.1 | 1 + src/dirnode.cpp | 8 ++++---- src/gource.cpp | 4 ++++ src/gource_settings.cpp | 14 +++++++++----- src/gource_settings.h | 1 + 7 files changed, 21 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2d1314e..393f7608 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ 0.33: + * Added --hide root option to not draw branches from the root directory. * Fixed log parsing of Bazaar merges and tagged commits. * --output-custom-log now skips unparsed log entries instead of exiting. diff --git a/README b/README index 0e1c8d87..57ea5acf 100644 --- a/README +++ b/README @@ -210,6 +210,7 @@ options: filenames - names of files mouse - mouse cursor progress - progress bar widget + root - root directory of tree tree - animated tree structure users - user avatars usernames - names of users diff --git a/data/gource.1 b/data/gource.1 index ae12661d..6c1b2d63 100644 --- a/data/gource.1 +++ b/data/gource.1 @@ -176,6 +176,7 @@ Hide one or more display elements from the list below: filenames \- names of files mouse \- mouse cursor progress \- progress bar widget + root \- root directory of the tree tree \- animated tree structure users \- user avatars usernames \- names of users diff --git a/src/dirnode.cpp b/src/dirnode.cpp index 4c179f33..0bccc953 100644 --- a/src/dirnode.cpp +++ b/src/dirnode.cpp @@ -1039,8 +1039,8 @@ void RDirNode::calcProjectedPos() { void RDirNode::drawEdgeShadows(float dt) const{ - spline.drawShadow(); - + if(parent!=0 && (!gGourceSettings.hide_root || parent->parent !=0)) spline.drawShadow(); + for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* child = (*it); @@ -1053,8 +1053,8 @@ void RDirNode::drawEdgeShadows(float dt) const{ void RDirNode::drawEdges(float dt) const{ - spline.draw(); - + if(parent!=0 && (!gGourceSettings.hide_root || parent->parent !=0)) spline.draw(); + for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* child = (*it); diff --git a/src/gource.cpp b/src/gource.cpp index 084fc537..627b05d0 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -766,6 +766,10 @@ void Gource::keyPress(SDL_KeyboardEvent *e) { } } + if (e->keysym.sym == SDLK_r) { + gGourceSettings.hide_root = !gGourceSettings.hide_root; + } + if (e->keysym.sym == SDLK_k) { gGourceSettings.show_key = !gGourceSettings.show_key; } diff --git a/src/gource_settings.cpp b/src/gource_settings.cpp index 9df02125..61c74658 100644 --- a/src/gource_settings.cpp +++ b/src/gource_settings.cpp @@ -100,7 +100,7 @@ if(extended_help) { printf(" --git-branch Get the git log of a particular branch\n\n"); printf(" --hide DISPLAY_ELEMENT bloom,date,dirnames,files,filenames,mouse,progress,\n"); - printf(" tree,users,usernames\n\n"); + printf(" root,tree,users,usernames\n\n"); printf(" --logo IMAGE Logo to display in the foreground\n"); printf(" --logo-offset XxY Offset position of the logo\n\n"); @@ -201,6 +201,7 @@ GourceSettings::GourceSettings() { arg_types["hide-progress"] = "bool"; arg_types["hide-bloom"] = "bool"; arg_types["hide-mouse"] = "bool"; + arg_types["hide-root"] = "bool"; arg_types["highlight-all-users"] = "bool"; arg_types["highlight-dirs"] = "bool"; arg_types["file-extensions"] = "bool"; @@ -278,9 +279,10 @@ void GourceSettings::setGourceDefaults() { hide_usernames = false; hide_filenames = false; hide_dirnames = false; - hide_progress = false; - hide_bloom = false; - hide_mouse = false; + hide_progress = false; + hide_bloom = false; + hide_mouse = false; + hide_root = false; start_position = 0.0f; stop_position = 0.0f; @@ -484,7 +486,8 @@ void GourceSettings::importGourceSettings(ConfFile& conffile, ConfSection* gourc && hide_field != "dirnames" && hide_field != "bloom" && hide_field != "progress" - && hide_field != "mouse") { + && hide_field != "mouse" + && hide_field != "root") { std::string unknown_hide_option = std::string("unknown option hide ") + hide_field; conffile.entryException(entry, unknown_hide_option); } @@ -516,6 +519,7 @@ void GourceSettings::importGourceSettings(ConfFile& conffile, ConfSection* gourc else if(hidestr == "dirnames") hide_dirnames = true; else if(hidestr == "bloom") hide_bloom = true; else if(hidestr == "progress") hide_progress = true; + else if(hidestr == "root") hide_root = true; else if(hidestr == "mouse") { hide_mouse = true; hide_progress = true; diff --git a/src/gource_settings.h b/src/gource_settings.h index 346935b6..5e03ba03 100644 --- a/src/gource_settings.h +++ b/src/gource_settings.h @@ -48,6 +48,7 @@ class GourceSettings : public SDLAppSettings { bool hide_progress; bool hide_bloom; bool hide_mouse; + bool hide_root; bool disable_auto_rotate; From 470bf95c118cf689f1759823d4e9379b67455acd Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 5 Apr 2011 13:56:46 +1200 Subject: [PATCH 10/56] Bump version. --- configure.ac | 2 +- src/gource_settings.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 0121f286..b89b3177 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ(2.61) -AC_INIT(Gource, 0.32, [acaudwell@gmail.com]) +AC_INIT(Gource, 0.33, [acaudwell@gmail.com]) AC_CONFIG_SRCDIR([src/main.h]) AM_INIT_AUTOMAKE([dist-bzip2 foreign subdir-objects]) diff --git a/src/gource_settings.h b/src/gource_settings.h index 5e03ba03..9d16002d 100644 --- a/src/gource_settings.h +++ b/src/gource_settings.h @@ -18,7 +18,7 @@ #ifndef GOURCE_SETTINGS_H #define GOURCE_SETTINGS_H -#define GOURCE_VERSION "0.32" +#define GOURCE_VERSION "0.33" #include From b17af8062e04edb4be6de24b2b50165509422cec Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 11 Jan 2011 15:18:59 +1300 Subject: [PATCH 11/56] WIP improved font rendering. --- src/core | 2 +- src/dirnode.cpp | 41 +++++++++++++++++++++-------------- src/dirnode.h | 13 ++++++----- src/file.cpp | 48 +++++++++++++++++++++++++++++------------ src/file.h | 6 +++++- src/gource.cpp | 57 ++++++++++++++++++++++++++++++++----------------- src/gource.h | 18 +++++++++------- src/textbox.cpp | 6 +++--- src/user.cpp | 2 +- 9 files changed, 124 insertions(+), 69 deletions(-) diff --git a/src/core b/src/core index 3c71b617..ea4c22b1 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit 3c71b617c0d26eb2aaeaecbbeb3a7c26d39db82c +Subproject commit ea4c22b14d0c479fc7ce409b6a84f5a3b8a1ff9a diff --git a/src/dirnode.cpp b/src/dirnode.cpp index 0bccc953..aee437fe 100644 --- a/src/dirnode.cpp +++ b/src/dirnode.cpp @@ -930,7 +930,7 @@ void RDirNode::calcScreenPos() { } } -void RDirNode::drawNames(const FXFont & dirfont, const Frustum & frustum){ +void RDirNode::drawNames(const FXFont& dirfont) { if(!gGourceSettings.hide_dirnames && isVisible()) { drawDirName(dirfont); @@ -938,7 +938,7 @@ void RDirNode::drawNames(const FXFont & dirfont, const Frustum & frustum){ if(!gGourceSettings.hide_filenames) { - if(!(gGourceSettings.hide_filenames || gGourceSettings.hide_files) && frustum.intersects(quadItemBounds)) { + if(!(gGourceSettings.hide_filenames || gGourceSettings.hide_files) && in_frustum) { for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { RFile* f = *it; f->drawName(); @@ -949,13 +949,23 @@ void RDirNode::drawNames(const FXFont & dirfont, const Frustum & frustum){ for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* node = (*it); - node->drawNames(dirfont,frustum); + node->drawNames(dirfont); } } -void RDirNode::drawShadows(const Frustum & frustum, float dt) const{ +void RDirNode::checkFrustum(const Frustum& frustum) { - if(frustum.intersects(quadItemBounds)) { + in_frustum = frustum.intersects(quadItemBounds); + + for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { + RDirNode* node = (*it); + node->checkFrustum(frustum); + } +} + +void RDirNode::drawShadows(float dt) const{ + + if(in_frustum) { glPushMatrix(); glTranslatef(pos.x, pos.y, 0.0); @@ -973,13 +983,13 @@ void RDirNode::drawShadows(const Frustum & frustum, float dt) const{ for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* node = (*it); - node->drawShadows(frustum, dt); + node->drawShadows(dt); } } -void RDirNode::updateFilesVBO(const Frustum & frustum, qbuf2f& buffer, float dt) const{ +void RDirNode::updateFilesVBO(qbuf2f& buffer, float dt) const{ - if(frustum.intersects(quadItemBounds)) { + if(in_frustum) { for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { RFile* f = *it; @@ -993,13 +1003,13 @@ void RDirNode::updateFilesVBO(const Frustum & frustum, qbuf2f& buffer, float dt) for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* node = (*it); - node->updateFilesVBO(frustum,buffer,dt); + node->updateFilesVBO(buffer,dt); } } -void RDirNode::drawFiles(const Frustum & frustum, float dt) const{ +void RDirNode::drawFiles(float dt) const{ - if(frustum.intersects(quadItemBounds)) { + if(in_frustum) { vec4f col = getColour(); @@ -1020,7 +1030,7 @@ void RDirNode::drawFiles(const Frustum & frustum, float dt) const{ for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* node = (*it); - node->drawFiles(frustum,dt); + node->drawFiles(dt); } } @@ -1065,9 +1075,9 @@ void RDirNode::drawEdges(float dt) const{ } } -void RDirNode::drawBloom(const Frustum & frustum, float dt){ +void RDirNode::drawBloom(float dt){ - if(isVisible() && frustum.intersects(quadItemBounds)) { + if(in_frustum && isVisible()) { float bloom_radius = dir_radius * 2.0 * gGourceSettings.bloom_multiplier; @@ -1089,12 +1099,11 @@ void RDirNode::drawBloom(const Frustum & frustum, float dt){ glVertex2f(-bloom_radius,bloom_radius); glEnd(); glPopMatrix(); - } for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* node = (*it); - node->drawBloom(frustum,dt); + node->drawBloom(dt); } } diff --git a/src/dirnode.h b/src/dirnode.h index 445a828f..c73e4878 100644 --- a/src/dirnode.h +++ b/src/dirnode.h @@ -60,6 +60,7 @@ class RDirNode : public QuadItem { float dir_area; bool visible; + bool in_frustum; bool position_initialized; float since_node_visible; @@ -187,13 +188,15 @@ class RDirNode : public QuadItem { void drawEdges(float dt) const; void drawEdgeShadows(float dt) const; - void drawBloom(const Frustum & frustum, float dt); + void checkFrustum(const Frustum & frustum); - void updateFilesVBO(const Frustum & frustum, qbuf2f& buffer, float dt) const; + void updateFilesVBO(qbuf2f& buffer, float dt) const; - void drawShadows(const Frustum & frustum, float dt) const; - void drawFiles(const Frustum & frustum, float dt) const; - void drawNames(const FXFont & dirfont, const Frustum & frustum); + void drawShadows(float dt) const; + void drawFiles(float dt) const; + void drawBloom(float dt); + + void drawNames(const FXFont& dirfont); void calcScreenPos(); diff --git a/src/file.cpp b/src/file.cpp index 691bdc33..eaebaa35 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -21,6 +21,9 @@ float gGourceFileDiameter = 8.0; std::vector gGourceRemovedFiles; +FXFont file_selected_font; +FXFont file_font; + RFile::RFile(const std::string & name, const vec3f & colour, const vec2f & pos, int tagid) : Pawn(name,pos,tagid) { hidden = true; size = gGourceFileDiameter; @@ -45,9 +48,20 @@ RFile::RFile(const std::string & name, const vec3f & colour, const vec2f & pos, setFilename(name); + if(!file_selected_font.initialized()) { + file_selected_font = fontmanager.grab("FreeSans.ttf", 18); + file_selected_font.dropShadow(false); + file_selected_font.roundCoordinates(true); + } + + if(!file_font.initialized()) { + file_font = fontmanager.grab("FreeSans.ttf", 14); + file_font.dropShadow(false); + file_font.roundCoordinates(true); + } + //namelist = glGenLists(1); - - font = 0; + label = 0; setSelected(false); dir = 0; @@ -112,25 +126,31 @@ int call_count = 0; void RFile::setSelected(bool selected) { - if(font.getFTFont()!=0 && this->selected==selected) return; - - if(selected) { - font = fontmanager.grab("FreeSans.ttf", 18); - } else { - font = fontmanager.grab("FreeSans.ttf", 14); - } - - font.dropShadow(false); - font.roundCoordinates(true); +// if(font.getFTFont()!=0 && this->selected==selected) return; + if(label && this->selected==selected) return; + if(!label) label = new FXLabel(); + Pawn::setSelected(selected); + updateLabel(); + //pre-compile name display list //glNewList(namelist, GL_COMPILE); // font.draw(0.0f, 0.0f, (selected || shortname.size()==0) ? name : shortname); //glEndList(); } +void RFile::updateLabel() { + bool show_file_ext = gGourceSettings.file_extensions; + + if(selected) { + label->setText(file_selected_font, (selected || !show_file_ext) ? name : ext); + } else { + label->setText(file_font, (selected || !show_file_ext) ? name : ext); + } +} + void RFile::colourize() { file_colour = ext.size() ? colourHash(ext) : vec3f(1.0f, 1.0f, 1.0f); } @@ -273,13 +293,13 @@ void RFile::drawNameText(float alpha) const { glTranslatef(1.0, 1.0, 0.0); glColor4f(0.0, 0.0, 0.0, name_alpha * 0.7f); //glCallList(namelist); - font.draw(0.0f, 0.0f, (selected || !show_file_ext) ? name : ext); + label->draw(); glPopMatrix(); //draw name glColor4f(nameCol.x, nameCol.y, nameCol.z, name_alpha); //glCallList(namelist); - font.draw(0.0f, 0.0f, (selected || !show_file_ext) ? name : ext); + label->draw(); glPopMatrix(); } diff --git a/src/file.h b/src/file.h index 542583fa..1d85a3a8 100644 --- a/src/file.h +++ b/src/file.h @@ -41,6 +41,8 @@ class RFile : public Pawn { vec2f dest; float distance; + FXLabel* label; + //GLuint namelist; void setFilename(const std::string& abs_file_path); @@ -69,7 +71,9 @@ class RFile : public Pawn { void touch(const vec3f & colour); void setSelected(bool selected); - + + void updateLabel(); + void setHidden(bool hidden); void setDest(const vec2f & dest){ this->dest = dest; } diff --git a/src/gource.cpp b/src/gource.cpp index 627b05d0..a522b3ef 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -716,6 +716,10 @@ void Gource::keyPress(SDL_KeyboardEvent *e) { gGourceQuadTreeDebug = !gGourceQuadTreeDebug; } + if (e->keysym.sym == SDLK_y) { + gGourceSettings.hide_tree = !gGourceSettings.hide_tree; + } + if (e->keysym.sym == SDLK_g) { gGourceSettings.hide_users = !gGourceSettings.hide_users; } @@ -764,6 +768,8 @@ void Gource::keyPress(SDL_KeyboardEvent *e) { gGourceSettings.file_extensions = true; gGourceSettings.hide_filenames = false; } + + update_file_labels = true; } if (e->keysym.sym == SDLK_r) { @@ -874,6 +880,7 @@ void Gource::reset() { if(dirNodeTree!=0) delete dirNodeTree; recolour = false; + update_file_labels = false; userTree = 0; dirNodeTree = 0; @@ -1586,6 +1593,13 @@ void Gource::logic(float t, float dt) { recolour = false; } + if(update_file_labels) { + for(std::map::iterator it = files.begin(); it != files.end(); it++) { + it->second->updateLabel(); + } + update_file_labels = false; + } + //still want to update camera while paused if(paused) { updateBounds(); @@ -1672,7 +1686,7 @@ void Gource::logic(float t, float dt) { updateTime(commitqueue.size() > 0 ? currtime : lasttime); } -void Gource::mousetrace(Frustum& frustum, float dt) { +void Gource::mousetrace(float dt) { //fprintf(stderr, "start trace\n"); //projected mouse pos glMatrixMode(GL_PROJECTION); @@ -1834,7 +1848,7 @@ void Gource::drawBackground(float dt) { } } -void Gource::drawTree(Frustum& frustum, float dt) { +void Gource::drawTree(float dt) { draw_tree_time = SDL_GetTicks(); root->calcEdges(); @@ -1869,7 +1883,7 @@ void Gource::drawTree(Frustum& frustum, float dt) { glPopMatrix(); //update file and user vbos - updateVBOs(frustum, dt); + updateVBOs(dt); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); @@ -1877,13 +1891,13 @@ void Gource::drawTree(Frustum& frustum, float dt) { //draw shadows - drawUserShadows(frustum, dt); + drawUserShadows(dt); - drawFileShadows(frustum, dt); + drawFileShadows(dt); drawActions(dt); - drawFiles(frustum, dt); + drawFiles(dt); draw_tree_time = SDL_GetTicks() - draw_tree_time; } @@ -1903,7 +1917,7 @@ void Gource::drawActions(float dt) { } } -void Gource::drawBloom(Frustum &frustum, float dt) { +void Gource::drawBloom(float dt) { if(gGourceSettings.hide_bloom) return; glEnable(GL_TEXTURE_2D); @@ -1913,7 +1927,7 @@ void Gource::drawBloom(Frustum &frustum, float dt) { glBindTexture(GL_TEXTURE_2D, bloomtex->textureid); glBlendFunc (GL_ONE, GL_ONE); - root->drawBloom(frustum, dt); + root->drawBloom(dt); } void Gource::setMessage(const char* str, ...) { @@ -1976,7 +1990,7 @@ void Gource::screenshot() { setMessage("Wrote screenshot %s", tganame); } -void Gource::updateVBOs(const Frustum& frustum, float dt) { +void Gource::updateVBOs(float dt) { if(gGourceSettings.ffp) return; for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { @@ -2004,11 +2018,11 @@ void Gource::updateVBOs(const Frustum& frustum, float dt) { } file_vbo.reset(); - root->updateFilesVBO(frustum, file_vbo, dt); + root->updateFilesVBO(file_vbo, dt); file_vbo.update(); } -void Gource::drawFileShadows(const Frustum& frustum, float dt) { +void Gource::drawFileShadows(float dt) { if(gGourceSettings.hide_files) return; glEnable(GL_BLEND); @@ -2027,11 +2041,11 @@ void Gource::drawFileShadows(const Frustum& frustum, float dt) { glUseProgramObjectARB(0); } else { - root->drawShadows(frustum, dt); + root->drawShadows(dt); } } -void Gource::drawUserShadows(const Frustum& frustum, float dt) { +void Gource::drawUserShadows(float dt) { if(gGourceSettings.hide_users) return; glEnable(GL_BLEND); @@ -2061,7 +2075,7 @@ void Gource::drawUserShadows(const Frustum& frustum, float dt) { } } -void Gource::drawFiles(const Frustum& frustum, float dt) { +void Gource::drawFiles(float dt) { if(gGourceSettings.hide_files) return; @@ -2079,7 +2093,7 @@ void Gource::drawFiles(const Frustum& frustum, float dt) { file_vbo.draw(); } else { - root->drawFiles(frustum, dt); + root->drawFiles(dt); } } @@ -2128,7 +2142,7 @@ void Gource::draw(float t, float dt) { trace_time = SDL_GetTicks(); if(!gGourceSettings.hide_mouse && cursor.isVisible()) { - mousetrace(frustum,dt); + mousetrace(dt); } else { if(hoverUser) { hoverUser->setMouseOver(false); @@ -2150,8 +2164,11 @@ void Gource::draw(float t, float dt) { glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + //check visibility + root->checkFrustum(frustum); + //draw tree - drawTree(frustum, dt); + drawTree(dt); drawUsers(dt); @@ -2159,7 +2176,7 @@ void Gource::draw(float t, float dt) { glEnable(GL_BLEND); //draw bloom - drawBloom(frustum, dt); + drawBloom(dt); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2173,8 +2190,8 @@ void Gource::draw(float t, float dt) { //switch to 2D, preserve current state display.push2D(); - - root->drawNames(font,frustum); + + root->drawNames(font); //switch back display.pop2D(); diff --git a/src/gource.h b/src/gource.h index 14d486f1..a34bb3f8 100644 --- a/src/gource.h +++ b/src/gource.h @@ -88,6 +88,8 @@ class Gource : public SDLApp { bool recolour; + bool update_file_labels; + bool use_selection_bounds; Bounds2D selection_bounds; @@ -172,7 +174,7 @@ class Gource : public SDLApp { QuadTree* dirNodeTree; QuadTree* userTree; - + std::string message; float message_timer; @@ -214,7 +216,7 @@ class Gource : public SDLApp { void updateTime(time_t display_time); - void mousetrace(Frustum& frustum, float dt); + void mousetrace(float dt); bool canSeek(); void seekTo(float percent); @@ -224,14 +226,14 @@ class Gource : public SDLApp { void loadingScreen(); void drawBackground(float dt); void drawActions(float dt); - void drawTree(Frustum &frustum, float dt); - void drawBloom(Frustum &frustum, float dt); - void drawFileShadows(const Frustum& frustum, float dt); - void drawUserShadows(const Frustum& frustum, float dt); - void drawFiles(const Frustum& frustum, float dt); - void updateVBOs(const Frustum& frustum, float dt); + void drawTree(float dt); + void drawBloom(float dt); + void drawFileShadows(float dt); + void drawUserShadows(float dt); + void drawFiles(float dt); void drawUsers(float dt); + void updateVBOs(float dt); void screenshot(); diff --git a/src/textbox.cpp b/src/textbox.cpp index 45934576..84bf737f 100644 --- a/src/textbox.cpp +++ b/src/textbox.cpp @@ -71,7 +71,7 @@ void TextBox::addLine(std::string str) { if(width > rect_width) rect_width = width; - rect_height += (font.getHeight()+4); + rect_height += (font.getFontSize()+4); content.push_back(str); } @@ -98,7 +98,7 @@ void TextBox::setPos(const vec2f& pos, bool adjust) { if(!adjust) return; - int fontheight = font.getHeight() + 4; + int fontheight = font.getFontSize() + 4; corner.y -= rect_height; @@ -153,6 +153,6 @@ void TextBox::draw() const { std::vector::const_iterator it; for(it = content.begin(); it != content.end(); it++) { font.draw((int)corner.x+2, (int)corner.y+yinc, (*it).c_str()); - yinc += font.getHeight() + 4; + yinc += font.getFontSize() + 4; } } diff --git a/src/user.cpp b/src/user.cpp index 5dde9ce5..8135828e 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -389,7 +389,7 @@ void RUser::drawNameText(float alpha) const { vec3f screenpos = display.project(drawpos - vec3f(0.0, 0.5 * size * graphic_ratio, 0.0f )); screenpos.x -= namewidth * 0.5; - screenpos.y -= font.getHeight(); + screenpos.y -= font.getMaxHeight(); glColor4f(nameCol.x, nameCol.y, nameCol.z, (selected||highlighted||gGourceSettings.highlight_all_users) ? user_alpha : alpha); From 2daa509443c240f09f14a2c79b4a55cc67e0f612 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 11:47:47 +1200 Subject: [PATCH 12/56] More accurate timing debugging. Users use the same VBO with texture changes. --- src/gource.cpp | 158 ++++++++++++++++++++++++++++--------------------- src/gource.h | 22 ++++--- 2 files changed, 104 insertions(+), 76 deletions(-) diff --git a/src/gource.cpp b/src/gource.cpp index a522b3ef..38bde8a8 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -335,8 +335,6 @@ void Gource::update(float t, float dt) { logic_time = SDL_GetTicks() - logic_time; - draw_time = SDL_GetTicks(); - draw(runtime, scaled_dt); //extract frames based on frameskip setting if frameExporter defined @@ -920,15 +918,7 @@ void Gource::reset() { delete it->second; } - users.clear(); - - //delete user vbos - for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { - delete it->second; - } - - user_vbos.clear(); - + users.clear(); //delete for(std::map::iterator it = files.begin(); it != files.end(); it++) { @@ -1848,8 +1838,10 @@ void Gource::drawBackground(float dt) { } } -void Gource::drawTree(float dt) { - draw_tree_time = SDL_GetTicks(); +void Gource::drawScene(float dt) { + + //draw edges + draw_edges_time = SDL_GetTicks(); root->calcEdges(); @@ -1882,24 +1874,50 @@ void Gource::drawTree(float dt) { glMatrixMode(GL_MODELVIEW); glPopMatrix(); - //update file and user vbos - updateVBOs(dt); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + draw_edges_time = SDL_GetTicks() - draw_edges_time; //draw shadows + + draw_shadows_time = SDL_GetTicks(); drawUserShadows(dt); drawFileShadows(dt); + draw_shadows_time = SDL_GetTicks() - draw_shadows_time; + + //draw actions + + draw_actions_time = SDL_GetTicks(); + drawActions(dt); + draw_actions_time = SDL_GetTicks() - draw_actions_time; + + //draw files + + draw_files_time = SDL_GetTicks(); + drawFiles(dt); - draw_tree_time = SDL_GetTicks() - draw_tree_time; + draw_files_time = SDL_GetTicks() - draw_files_time; + + //draw users + + draw_users_time = SDL_GetTicks(); + + drawUsers(dt); + + draw_users_time = SDL_GetTicks() - draw_users_time; + + //draw bloom + + draw_bloom_time = SDL_GetTicks(); + + drawBloom(dt); + + draw_bloom_time = SDL_GetTicks() - draw_bloom_time; + } void Gource::drawActions(float dt) { @@ -1922,10 +1940,10 @@ void Gource::drawBloom(float dt) { glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); //draw 'gourceian blur' around dirnodes glBindTexture(GL_TEXTURE_2D, bloomtex->textureid); - glBlendFunc (GL_ONE, GL_ONE); root->drawBloom(dt); } @@ -1993,29 +2011,18 @@ void Gource::screenshot() { void Gource::updateVBOs(float dt) { if(gGourceSettings.ffp) return; - for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { - it->second->reset(); - } + user_vbo.reset(); //use a separate vbo for each user texture for(std::map::iterator it = users.begin(); it!=users.end(); it++) { RUser* user = it->second; - qbuf2f* user_vbo = user_vbos[user->graphic->textureid]; - - if(!user_vbo) { - user_vbos[user->graphic->textureid] = user_vbo = new qbuf2f(); - } - float alpha = user->getAlpha(); vec3f col = user->getColour(); - user_vbo->add(user->getPos(), vec2f(user->size, user->graphic_ratio*user->size), vec4f(col.x, col.y, col.z, alpha)); - } - - for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { - it->second->update(); + user_vbo.add(user->graphic->textureid, user->getPos(), vec2f(user->size, user->graphic_ratio*user->size), vec4f(col.x, col.y, col.z, alpha)); } + user_vbo.update(); file_vbo.reset(); root->updateFilesVBO(file_vbo, dt); @@ -2024,7 +2031,8 @@ void Gource::updateVBOs(float dt) { void Gource::drawFileShadows(float dt) { if(gGourceSettings.hide_files) return; - + + glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2048,6 +2056,7 @@ void Gource::drawFileShadows(float dt) { void Gource::drawUserShadows(float dt) { if(gGourceSettings.hide_users) return; + glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2060,10 +2069,7 @@ void Gource::drawUserShadows(float dt) { glPushMatrix(); glTranslatef(shadow_offset.x, shadow_offset.y, 0.0f); - for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { - glBindTexture(GL_TEXTURE_2D, it->first); - it->second->draw(); - } + user_vbo.draw(); glPopMatrix(); @@ -2111,10 +2117,7 @@ void Gource::drawUsers(float dt) { if(!gGourceSettings.ffp) { - for(std::map::iterator it = user_vbos.begin(); it!= user_vbos.end(); it++) { - glBindTexture(GL_TEXTURE_2D, it->first); - it->second->draw(); - } + user_vbo.draw(); } else { @@ -2167,23 +2170,30 @@ void Gource::draw(float t, float dt) { //check visibility root->checkFrustum(frustum); - //draw tree - drawTree(dt); + //update file and user vbos - drawUsers(dt); + update_vbos_time = SDL_GetTicks(); + + updateVBOs(dt); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); + update_vbos_time = SDL_GetTicks() - update_vbos_time; + + //draw scene - //draw bloom - drawBloom(dt); + draw_scene_time = SDL_GetTicks(); + + drawScene(dt); + + draw_scene_time = SDL_GetTicks() - draw_scene_time; glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); name_calc_time = SDL_GetTicks(); - root->calcScreenPos(); - + if(!gGourceSettings.hide_filenames) { + root->calcScreenPos(); + } + name_calc_time = SDL_GetTicks() - name_calc_time; name_draw_time = SDL_GetTicks(); @@ -2196,8 +2206,6 @@ void Gource::draw(float t, float dt) { //switch back display.pop2D(); - name_draw_time = SDL_GetTicks() - name_draw_time; - if(!(gGourceSettings.hide_usernames || gGourceSettings.hide_users)) { for(std::map::iterator it = users.begin(); it!=users.end(); it++) { it->second->drawName(); @@ -2213,6 +2221,8 @@ void Gource::draw(float t, float dt) { display.pop2D(); } + name_draw_time = SDL_GetTicks() - name_draw_time; + if(debug) { glDisable(GL_TEXTURE_2D); glLineWidth(2.0); @@ -2376,25 +2386,37 @@ void Gource::draw(float t, float dt) { font.print(1,160,"Camera: (%.2f, %.2f, %.2f)", campos.x, campos.y, campos.z); font.print(1,180,"Gravity: %.2f", gGourceForceGravity); font.print(1,200,"Update Tree: %u ms", update_dir_tree_time); - font.print(1,220,"Draw Tree: %u ms", draw_tree_time); - font.print(1,240,"Mouse Trace: %u ms", trace_time); - font.print(1,260,"Logic Time: %u ms", logic_time); - font.print(1,280,"Draw Time: %u ms (Names: Calc Time = %u ms, Draw Time = %u ms)", SDL_GetTicks() - draw_time, name_calc_time, name_draw_time); - font.print(1,300,"File Inner Loops: %d", gGourceFileInnerLoops); - font.print(1,320,"User Inner Loops: %d", gGourceUserInnerLoops); - font.print(1,340,"Dir Inner Loops: %d (QTree items = %d, nodes = %d, max node depth = %d)", gGourceDirNodeInnerLoops, + font.print(1,220,"Update VBOs: %u ms", update_vbos_time); + font.print(1,240,"Draw Scene: %u ms", draw_scene_time); + font.print(1,260," - Edges: %u ms", draw_edges_time); + font.print(1,280," - Shadows: %u ms", draw_shadows_time); + font.print(1,300," - Actions: %u ms", draw_actions_time); + font.print(1,320," - Files: %u ms", draw_files_time); + font.print(1,340," - Users: %u ms", draw_users_time); + font.print(1,360," - Bloom: %u ms", draw_bloom_time); + font.print(1,380,"Text: %u ms", name_calc_time + name_draw_time); + font.print(1,400," - Calc Time: %u ms", name_calc_time); + font.print(1,420," - Draw Time: %u ms", name_draw_time); + font.print(1,440,"Mouse Trace: %u ms", trace_time); + font.print(1,460,"Logic Time: %u ms", logic_time); + font.print(1,480,"File Inner Loops: %d", gGourceFileInnerLoops); + font.print(1,500,"User Inner Loops: %d", gGourceUserInnerLoops); + font.print(1,520,"Dir Inner Loops: %d (QTree items = %d, nodes = %d, max node depth = %d)", gGourceDirNodeInnerLoops, dirNodeTree->item_count, dirNodeTree->node_count, dirNodeTree->max_node_depth); - font.print(1,360,"Dir Bounds Ratio: %.2f, %.5f", dir_bounds.width() / dir_bounds.height(), rotation_remaining_angle); - font.print(1,380,"String Hash Seed: %d", gStringHashSeed); - font.print(1,400,"File VBO: %d/%d vertices", file_vbo.size() , file_vbo.capacity()); - font.print(1,420,"User VBOs: %d", user_vbos.size()); - + font.print(1,540,"Dir Bounds Ratio: %.2f, %.5f", dir_bounds.width() / dir_bounds.height(), rotation_remaining_angle); + font.print(1,560,"String Hash Seed: %d", gStringHashSeed); + + if(!gGourceSettings.ffp) { + font.print(1,580,"File VBO: %d/%d vertices, %d texture changes", file_vbo.vertices(), file_vbo.capacity(), file_vbo.texture_changes()); + font.print(1,600,"User VBO: %d/%d vertices, %d texture changes", user_vbo.vertices(), user_vbo.capacity(), user_vbo.texture_changes()); + } + if(selectedUser != 0) { } if(selectedFile != 0) { - font.print(1,400,"%s: %d files (%d visible)", selectedFile->getDir()->getPath().c_str(), + font.print(1,620,"%s: %d files (%d visible)", selectedFile->getDir()->getPath().c_str(), selectedFile->getDir()->fileCount(), selectedFile->getDir()->visibleFileCount()); } } diff --git a/src/gource.h b/src/gource.h index a34bb3f8..6d0e0937 100644 --- a/src/gource.h +++ b/src/gource.h @@ -111,8 +111,7 @@ class Gource : public SDLApp { RUser* hoverUser; RUser* selectedUser; - std::map user_vbos; - + qbuf2f user_vbo; qbuf2f file_vbo; GLuint selectionDepth; @@ -151,10 +150,16 @@ class Gource : public SDLApp { float idle_time; - Uint32 draw_tree_time; + Uint32 draw_edges_time; + Uint32 draw_shadows_time; + Uint32 draw_actions_time; + Uint32 draw_files_time; + Uint32 draw_users_time; + Uint32 draw_bloom_time; + Uint32 update_vbos_time; Uint32 update_dir_tree_time; Uint32 update_user_tree_time; - Uint32 draw_time; + Uint32 draw_scene_time; Uint32 logic_time; Uint32 trace_time; Uint32 name_calc_time; @@ -225,15 +230,16 @@ class Gource : public SDLApp { void loadingScreen(); void drawBackground(float dt); - void drawActions(float dt); - void drawTree(float dt); - void drawBloom(float dt); + void drawScene(float dt); + + void updateVBOs(float dt); void drawFileShadows(float dt); void drawUserShadows(float dt); + void drawActions(float dt); void drawFiles(float dt); void drawUsers(float dt); - void updateVBOs(float dt); + void drawBloom(float dt); void screenshot(); From 50f99821268ecc613b013b423dce269502b7d52d Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 11:48:42 +1200 Subject: [PATCH 13/56] Support multiple textures in the same VBO. Use glBufferSubData() for data changes. --- src/vbo.cpp | 103 +++++++++++++++++++++++++++++++++++++++++----------- src/vbo.h | 32 ++++++++++++---- 2 files changed, 105 insertions(+), 30 deletions(-) diff --git a/src/vbo.cpp b/src/vbo.cpp index 1f8576a2..0bb3b963 100644 --- a/src/vbo.cpp +++ b/src/vbo.cpp @@ -17,14 +17,15 @@ #include "vbo.h" -qbuf2f_vertex::qbuf2f_vertex() { -} - //qbuf2f -qbuf2f::qbuf2f() { - bufferid = 0; - item_count = 0; +qbuf2f::qbuf2f(int data_size) : data_size(data_size) { + bufferid = 0; + buffer_size = 0; + vertex_count = 0; + + data = new qbuf2f_vertex[data_size]; + //fprintf(stderr, "size of qbuf2f_vertex = %d\n", sizeof(qbuf2f_vertex)); } @@ -32,26 +33,45 @@ qbuf2f::~qbuf2f() { if(bufferid !=0) glDeleteBuffers(1, &bufferid); } +void qbuf2f::resize(int new_size) { + + qbuf2f_vertex* _data = data; + + data = new qbuf2f_vertex[new_size]; + + for(int i=0;i data_size) { + resize(vertex_count*2); + } + data[i] = v1; data[i+1] = v2; data[i+2] = v3; data[i+3] = v4; + + if(textures.empty() || textures.back().textureid != textureid) { + textures.push_back(qbuf2f_tex(i, textureid)); + } } void qbuf2f::update() { - if(data.empty()) return; + if(vertex_count==0) return; //note possibly better to have a queue and cycle them here if(bufferid==0) { glGenBuffers(1, &bufferid); } + //TODO: use glBufferSubData + glBindBuffer(GL_ARRAY_BUFFER, bufferid); - glBufferData(GL_ARRAY_BUFFER, data.size()*sizeof(qbuf2f_vertex), &(data[0].pos.x), GL_DYNAMIC_DRAW); + + //recreate buffer if less than the vertex_count + if(buffer_size < vertex_count) { + buffer_size = data_size; + glBufferData(GL_ARRAY_BUFFER, buffer_size*sizeof(qbuf2f_vertex), &(data[0].pos.x), GL_DYNAMIC_DRAW); + } else { + glBufferSubData(GL_ARRAY_BUFFER, 0, vertex_count*sizeof(qbuf2f_vertex), &(data[0].pos.x)); + } + glBindBuffer(GL_ARRAY_BUFFER, 0); } void qbuf2f::draw() { - if(data.empty() || bufferid==0) return; + if(vertex_count==0 || bufferid==0) return; glBindBuffer(GL_ARRAY_BUFFER, bufferid); @@ -96,8 +134,29 @@ void qbuf2f::draw() { glVertexPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), 0); glColorPointer(4, GL_FLOAT, sizeof(qbuf2f_vertex), (GLvoid*)8); // offset pos (2x4 bytes) glTexCoordPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), (GLvoid*)24); // offset pos + colour (2x4 + 4x4 bytes) - - glDrawArrays(GL_QUADS, 0, data.size()); + + int last_index = vertex_count-1; + + for(std::vector::iterator it = textures.begin(); it != textures.end();) { + qbuf2f_tex* tex = &(*it); + + int end_index; + + it++; + + if(it == textures.end()) { + end_index = last_index; + } else { + end_index = (*it).start_index; + } + + glBindTexture(GL_TEXTURE_2D, tex->textureid); + glDrawArrays(GL_QUADS, tex->start_index, end_index - tex->start_index + 1); + + if(end_index==last_index) break; + } + + glDrawArrays(GL_QUADS, 0, vertex_count); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); diff --git a/src/vbo.h b/src/vbo.h index 4a382361..4d15cdc0 100644 --- a/src/vbo.h +++ b/src/vbo.h @@ -27,7 +27,7 @@ //note this should be 32 bytes (8x4 bytes) class qbuf2f_vertex { public: - qbuf2f_vertex(); + qbuf2f_vertex() {}; qbuf2f_vertex(const vec2f& pos, const vec4f& colour, const vec2f& texcoord) : pos(pos), colour(colour), texcoord(texcoord) {}; vec2f pos; @@ -35,24 +35,40 @@ class qbuf2f_vertex { vec2f texcoord; }; +//maintain ranges corresponding to each texture +class qbuf2f_tex { +public: + qbuf2f_tex() {}; + qbuf2f_tex(int start_index, GLuint textureid) : start_index(start_index), textureid(textureid) {}; + int start_index; + GLuint textureid; +}; + class qbuf2f { - std::vector data; + qbuf2f_vertex* data; + int data_size; + std::vector textures; + GLuint bufferid; + int buffer_size; - int item_count; + int vertex_count; + + void resize(int new_size); public: - qbuf2f(); + qbuf2f(int data_size = 1); ~qbuf2f(); void reset(); - size_t size(); + size_t vertices(); size_t capacity(); - - void add(const vec2f& pos, const vec2f& dims, const vec4f& colour); - void add(const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord); + size_t texture_changes(); + + void add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour); + void add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord); void update(); void draw(); From 5f20ec3e0549cbe8a2611023bef72ab7e02d57fb Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 12:07:39 +1200 Subject: [PATCH 14/56] Added --no-vsync option. --- README | 5 ++++- data/gource.1 | 3 +++ src/core | 2 +- src/gource_settings.cpp | 3 ++- src/main.cpp | 2 +- 5 files changed, 11 insertions(+), 4 deletions(-) diff --git a/README b/README index 57ea5acf..075f2f08 100644 --- a/README +++ b/README @@ -169,7 +169,10 @@ options: --multi-sampling Enable multi-sampling. - --bloom-multiplier FLOAT + --no-vsync + Disable vsync. + + --bloom-multiplier FLOAT Adjust the amount of bloom. --bloom-intensity FLOAT diff --git a/data/gource.1 b/data/gource.1 index 6c1b2d63..20e36f82 100644 --- a/data/gource.1 +++ b/data/gource.1 @@ -139,6 +139,9 @@ Camera view padding. \fB\-\-multi\-sampling\fR Enable multi-sampling. .TP +\fB\-\-no\-vsync\fR +Disable vsync. +.TP \fB\-\-bloom\-multiplier FLOAT\fR Adjust the amount of bloom. .TP diff --git a/src/core b/src/core index ea4c22b1..65f3f935 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit ea4c22b14d0c479fc7ce409b6a84f5a3b8a1ff9a +Subproject commit 65f3f93590581bfcc06eac1b4481aa26dbca16b2 diff --git a/src/gource_settings.cpp b/src/gource_settings.cpp index 61c74658..2632419a 100644 --- a/src/gource_settings.cpp +++ b/src/gource_settings.cpp @@ -36,7 +36,8 @@ void GourceSettings::help(bool extended_help) { printf(" -h, --help Help\n\n"); printf(" -WIDTHxHEIGHT, --viewport Set viewport size\n"); printf(" -f, --fullscreen Fullscreen\n"); - printf(" --multi-sampling Enable multi-sampling\n\n"); + printf(" --multi-sampling Enable multi-sampling\n"); + printf(" --no-vsync Disable vsync\n\n"); printf(" -p, --start-position POSITION Begin at some position (0.0-1.0 or 'random')\n"); printf(" --stop-position POSITION Stop at some position\n"); diff --git a/src/main.cpp b/src/main.cpp index 58347727..4f571af8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -115,7 +115,7 @@ int main(int argc, char *argv[]) { } //enable vsync - display.enableVsync(true); + display.enableVsync(gGourceSettings.vsync); try { From 927b0dcee59b24ad65cf1bbb363a150ba327d75f Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 12:16:48 +1200 Subject: [PATCH 15/56] Changed dependencies (no longer needs FTGL). No longer links or checks for libpng or libjpeg, assumes people who package SDL_image build it with these. Bumped version number (this is not a release!). --- ChangeLog | 5 +++++ INSTALL | 6 +++--- configure.ac | 23 ++++++++--------------- src/gource_settings.h | 2 +- 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/ChangeLog b/ChangeLog index 393f7608..8ea63600 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +0.34: + * Now using VBOs and shaders for faster rendering when OpenGL 2.0 is available. + * New font rendering library derived from FTGL (FTGL no longer required). + * Added --no-vsync option. + 0.33: * Added --hide root option to not draw branches from the root directory. * Fixed log parsing of Bazaar merges and tagged commits. diff --git a/INSTALL b/INSTALL index c558c4c1..a222932f 100644 --- a/INSTALL +++ b/INSTALL @@ -15,15 +15,15 @@ Gource requires the following libraries to compile: SDL 1.2 (libsdl1.2-dev) SDL Image 1.2 (libsdl-image1.2-dev) PCRE3 (libpcre3-dev) - FTGL 2.1.3~rc5-2 (libftgl-dev) - PNG library (libpng12-dev) - JPEG library (libjpeg62-dev) + Freetype 2 (libfreetype6-dev) GLEW (libglew1.5-dev) Optional: TinyXML (libtinyxml-dev) +Note: SDL Image needs to have been built with support PNG and JPEG images. + 2. Building =========== diff --git a/configure.ac b/configure.ac index b89b3177..9046e60d 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ(2.61) -AC_INIT(Gource, 0.33, [acaudwell@gmail.com]) +AC_INIT(Gource, 0.34, [acaudwell@gmail.com]) AC_CONFIG_SRCDIR([src/main.h]) AM_INIT_AUTOMAKE([dist-bzip2 foreign subdir-objects]) @@ -41,24 +41,18 @@ CPPFLAGS="$CPPFLAGS $SDL_CFLAGS" LIBS="$LIBS $SDL_LIBS" #Freetype2 -AC_CHECK_FT2([9.0.3],[],[AC_MSG_ERROR([FreeType2 is required by FTGL. Please see INSTALL])]) +AC_CHECK_FT2([9.0.3],[],[AC_MSG_ERROR([FreeType2 is required. Please see INSTALL])]) CXXFLAGS="$CXXFLAGS $FT2_CFLAGS" CPPFLAGS="$CPPFLAGS $FT2_CFLAGS" +LIBS="$LIBS $FT2_LIBS" -#FTGL -PKG_CHECK_MODULES(FTGL, ftgl >= 2.1.3, [], AC_MSG_ERROR(FTGL 2.1.3 or greater is required. Please see INSTALL)) -CXXFLAGS="$CXXFLAGS $FTGL_CFLAGS" -CPPFLAGS="$CPPFLAGS $FTGL_CFLAGS" -LIBS="$LIBS $FTGL_LIBS" - -#PNG library -AC_CHECK_LIB(png, png_read_info, , AC_MSG_ERROR([PNG library required. Please see INSTALL])) +#SDL_image library with PNG support +AC_CHECK_LIB(SDL_image, IMG_LoadPNG_RW, LIBS="$LIBS", AC_MSG_ERROR([SDL_image with PNG support required. Please see INSTALL])) -#JPEG library -AC_CHECK_LIB(jpeg, jpeg_read_header, , AC_MSG_ERROR([JPEG library required. Please see INSTALL])) +#SDL_image library with JPG support +AC_CHECK_LIB(SDL_image, IMG_LoadJPG_RW, LIBS="$LIBS", AC_MSG_ERROR([SDL_image with JPG support required. Please see INSTALL])) -#SDL_image library with PNG support -AC_CHECK_LIB(SDL_image, IMG_LoadPNG_RW, LIBS="$LIBS -lSDL_image", AC_MSG_ERROR([SDL_image required. Please see INSTALL])) +LIBS="$LIBS -lSDL_image" #PCRE AC_CHECK_LIB([pcre], [pcre_compile],, AC_MSG_ERROR(PCRE is required. Please see INSTALL)) @@ -69,7 +63,6 @@ AC_CHECK_LIB(GLEW, glewInit, LIBS="$LIBS -lGLEW", AC_MSG_ERROR([GLEW required. P #Check for required headers AC_CHECK_HEADER([SDL.h],, AC_MSG_ERROR(SDL.h is required. Please see INSTALL)) AC_CHECK_HEADER([SDL_image.h],, AC_MSG_ERROR(SDL_image.h is required. Please see INSTALL)) -AC_CHECK_HEADER([ftgl.h],, AC_MSG_ERROR(ftgl.h is required. Please see INSTALL)) AC_CHECK_HEADER([pcre.h],, AC_MSG_ERROR(pcre.h is required. Please see INSTALL)) AC_CHECK_HEADER([GL/glew.h],, AC_MSG_ERROR(glew.h is required. Please see INSTALL)) diff --git a/src/gource_settings.h b/src/gource_settings.h index 9d16002d..4d8772fd 100644 --- a/src/gource_settings.h +++ b/src/gource_settings.h @@ -18,7 +18,7 @@ #ifndef GOURCE_SETTINGS_H #define GOURCE_SETTINGS_H -#define GOURCE_VERSION "0.33" +#define GOURCE_VERSION "0.34" #include From 8241b2b219f8606a45ff1540d13e9593b77face5 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 12:17:53 +1200 Subject: [PATCH 16/56] Support multiple textures in the same VBO. --- src/dirnode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dirnode.cpp b/src/dirnode.cpp index aee437fe..85c4c116 100644 --- a/src/dirnode.cpp +++ b/src/dirnode.cpp @@ -997,7 +997,7 @@ void RDirNode::updateFilesVBO(qbuf2f& buffer, float dt) const{ vec3f col = f->getColour(); float alpha = f->getAlpha(); - buffer.add(f->getAbsolutePos(), vec2f(f->size, f->graphic_ratio*f->size), vec4f(col.x, col.y, col.z, alpha)); + buffer.add(f->graphic->textureid, f->getAbsolutePos(), vec2f(f->size, f->graphic_ratio*f->size), vec4f(col.x, col.y, col.z, alpha)); } } From 8b75b57c5e15725a24323d265fb88bcb7c40b33d Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 13:04:07 +1200 Subject: [PATCH 17/56] Stop drawing VBOs twice. --- src/vbo.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vbo.cpp b/src/vbo.cpp index 0bb3b963..23809661 100644 --- a/src/vbo.cpp +++ b/src/vbo.cpp @@ -156,8 +156,6 @@ void qbuf2f::draw() { if(end_index==last_index) break; } - glDrawArrays(GL_QUADS, 0, vertex_count); - glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); From 9219a50b300c919db0216491784347a5ca47db64 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 13:16:37 +1200 Subject: [PATCH 18/56] Include shaders in install. --- Makefile.am | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile.am b/Makefile.am index e3772051..c53d8fed 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,6 +58,9 @@ CPPFLAGS = -DSDLAPP_RESOURCE_DIR=\"$(pkgdatadir)\" dist_pkgdata_DATA = data/beam.png data/bloom.tga data/bloom_alpha.tga data/cursor.png data/file.png data/no_photo.png data/gource.style +shadersdir = $(pkgdatadir)/shaders +dist_shaders_DATA = data/shaders/shadow.vert data/shaders/shadow.frag + install-data-hook: mkdir -p -m 755 ${DESTDIR}/$(mandir)/man1 gzip -cf9 data/gource.1 > $(DESTDIR)$(mandir)/man1/gource.1.gz From 372f7985dc3f26fd3ee1bd9aabef17abaa9265af Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 16:49:45 +1200 Subject: [PATCH 19/56] Removed comment. --- src/vbo.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vbo.cpp b/src/vbo.cpp index 23809661..d72c3e4e 100644 --- a/src/vbo.cpp +++ b/src/vbo.cpp @@ -106,9 +106,7 @@ void qbuf2f::update() { if(bufferid==0) { glGenBuffers(1, &bufferid); } - - //TODO: use glBufferSubData - + glBindBuffer(GL_ARRAY_BUFFER, bufferid); //recreate buffer if less than the vertex_count From db67ac7d01182309a04fcd3e2783eced206038cc Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 16:50:13 +1200 Subject: [PATCH 20/56] Reduced cost of screen position calculations. Added more timing debugging. --- src/dirnode.cpp | 52 ++++++++++++++++++++++++++--------------- src/dirnode.h | 4 +--- src/file.cpp | 9 +------- src/gource.cpp | 61 ++++++++++++++++++++++++++----------------------- src/gource.h | 2 +- src/pawn.h | 3 +-- 6 files changed, 71 insertions(+), 60 deletions(-) diff --git a/src/dirnode.cpp b/src/dirnode.cpp index 85c4c116..1a020de7 100644 --- a/src/dirnode.cpp +++ b/src/dirnode.cpp @@ -846,8 +846,6 @@ void RDirNode::updateFilePositions() { void RDirNode::calcEdges() { - calcProjectedPos(); - if(parent != 0) { spline.update(parent->getProjectedPos(), parent->getColour(), projected_pos, col, projected_spos); } @@ -909,24 +907,47 @@ void RDirNode::drawDirName(const FXFont& dirfont) const{ dirfont.draw(mid.x, mid.y, path_token); } +void RDirNode::calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* projection) { -// project positions of files and directories on the display in 2d -void RDirNode::calcScreenPos() { + static GLdouble screen_x, screen_y, screen_z; + + gluProject( pos.x, pos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z); + screen_y = (float)viewport[3] - screen_y; + projected_pos.x = screen_x; + projected_pos.y = screen_y; - //first pass - calculate positions of names - for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { - RFile* f = *it; + gluProject( spos.x, spos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z); + screen_y = (float)viewport[3] - screen_y; + projected_spos.x = screen_x; + projected_spos.y = screen_y; - // TODO: different offsets for selected/not selected - if(f->isSelected()) - f->calcScreenPos(pos + vec2f(5.5f, -2.0f)); - else - f->calcScreenPos(pos + vec2f(5.5f, -1.0f)); + static vec2f selected_offset(5.5f, -2.0f); + static vec2f unselected_offset(5.5f, -1.0f); + + if(!gGourceSettings.hide_filenames) { + + //first pass - calculate positions of names + for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { + RFile* f = *it; + + vec2f text_pos = f->getAbsolutePos(); + text_pos.x += 5.5f; + + if(f->isSelected()) + text_pos.y -= 2.0f; + else + text_pos.y -= 1.0f; + + gluProject( text_pos.x, text_pos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z); + screen_y = (float)viewport[3] - screen_y; + f->screenpos.x = screen_x; + f->screenpos.y = screen_y; + } } for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* node = (*it); - node->calcScreenPos(); + node->calcScreenPos(viewport, modelview, projection); } } @@ -1042,11 +1063,6 @@ const vec2f & RDirNode::getProjectedPos() const{ return projected_pos; } -void RDirNode::calcProjectedPos() { - projected_pos = display.project(vec3f(pos.x, pos.y, 0.0)).truncate(); - projected_spos = display.project(vec3f(spos.x, spos.y, 0.0)).truncate(); -} - void RDirNode::drawEdgeShadows(float dt) const{ if(parent!=0 && (!gGourceSettings.hide_root || parent->parent !=0)) spline.drawShadow(); diff --git a/src/dirnode.h b/src/dirnode.h index c73e4878..3020487e 100644 --- a/src/dirnode.h +++ b/src/dirnode.h @@ -86,8 +86,6 @@ class RDirNode : public QuadItem { void changePath(const std::string & abspath); - void calcProjectedPos(); - void setInitialPosition(); void drawEdge(RDirNode* child) const; @@ -198,7 +196,7 @@ class RDirNode : public QuadItem { void drawNames(const FXFont& dirfont); - void calcScreenPos(); + void calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* projection); void nodeCount() const; }; diff --git a/src/file.cpp b/src/file.cpp index eaebaa35..3b261b2f 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -276,17 +276,10 @@ void RFile::drawNameText(float alpha) const { vec3f nameCol = getNameColour(); float name_alpha = selected ? 1.0 : alpha; - - vec3f drawpos = screenpos; - - //drawpos.x += 10.0; - //drawpos.y -= 10.0; - - bool show_file_ext = gGourceSettings.file_extensions; glPushMatrix(); - glTranslatef(drawpos.x, drawpos.y, 0.0); + glTranslatef(screenpos.x, screenpos.y, 0.0); //hard coded drop shadow glPushMatrix(); diff --git a/src/gource.cpp b/src/gource.cpp index 38bde8a8..4c4c8896 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -2170,6 +2170,20 @@ void Gource::draw(float t, float dt) { //check visibility root->checkFrustum(frustum); + screen_project_time = SDL_GetTicks(); + + GLint viewport[4]; + GLdouble modelview[16]; + GLdouble projection[16]; + + glGetIntegerv( GL_VIEWPORT, viewport ); + glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); + glGetDoublev( GL_PROJECTION_MATRIX, projection ); + + root->calcScreenPos(viewport, modelview, projection); + + screen_project_time = SDL_GetTicks() - screen_project_time; + //update file and user vbos update_vbos_time = SDL_GetTicks(); @@ -2188,14 +2202,6 @@ void Gource::draw(float t, float dt) { glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - name_calc_time = SDL_GetTicks(); - - if(!gGourceSettings.hide_filenames) { - root->calcScreenPos(); - } - - name_calc_time = SDL_GetTicks() - name_calc_time; - name_draw_time = SDL_GetTicks(); //switch to 2D, preserve current state @@ -2387,28 +2393,27 @@ void Gource::draw(float t, float dt) { font.print(1,180,"Gravity: %.2f", gGourceForceGravity); font.print(1,200,"Update Tree: %u ms", update_dir_tree_time); font.print(1,220,"Update VBOs: %u ms", update_vbos_time); - font.print(1,240,"Draw Scene: %u ms", draw_scene_time); - font.print(1,260," - Edges: %u ms", draw_edges_time); - font.print(1,280," - Shadows: %u ms", draw_shadows_time); - font.print(1,300," - Actions: %u ms", draw_actions_time); - font.print(1,320," - Files: %u ms", draw_files_time); - font.print(1,340," - Users: %u ms", draw_users_time); - font.print(1,360," - Bloom: %u ms", draw_bloom_time); - font.print(1,380,"Text: %u ms", name_calc_time + name_draw_time); - font.print(1,400," - Calc Time: %u ms", name_calc_time); - font.print(1,420," - Draw Time: %u ms", name_draw_time); - font.print(1,440,"Mouse Trace: %u ms", trace_time); - font.print(1,460,"Logic Time: %u ms", logic_time); - font.print(1,480,"File Inner Loops: %d", gGourceFileInnerLoops); - font.print(1,500,"User Inner Loops: %d", gGourceUserInnerLoops); - font.print(1,520,"Dir Inner Loops: %d (QTree items = %d, nodes = %d, max node depth = %d)", gGourceDirNodeInnerLoops, + font.print(1,240,"Projection: %u ms", screen_project_time); + font.print(1,260,"Draw Scene: %u ms", draw_scene_time); + font.print(1,280," - Edges: %u ms", draw_edges_time); + font.print(1,300," - Shadows: %u ms", draw_shadows_time); + font.print(1,320," - Actions: %u ms", draw_actions_time); + font.print(1,340," - Files: %u ms", draw_files_time); + font.print(1,360," - Users: %u ms", draw_users_time); + font.print(1,380," - Bloom: %u ms", draw_bloom_time); + font.print(1,400,"Text: %u ms", name_draw_time); + font.print(1,420,"Mouse Trace: %u ms", trace_time); + font.print(1,440,"Logic Time: %u ms", logic_time); + font.print(1,460,"File Inner Loops: %d", gGourceFileInnerLoops); + font.print(1,480,"User Inner Loops: %d", gGourceUserInnerLoops); + font.print(1,500,"Dir Inner Loops: %d (QTree items = %d, nodes = %d, max node depth = %d)", gGourceDirNodeInnerLoops, dirNodeTree->item_count, dirNodeTree->node_count, dirNodeTree->max_node_depth); - font.print(1,540,"Dir Bounds Ratio: %.2f, %.5f", dir_bounds.width() / dir_bounds.height(), rotation_remaining_angle); - font.print(1,560,"String Hash Seed: %d", gStringHashSeed); + font.print(1,520,"Dir Bounds Ratio: %.2f, %.5f", dir_bounds.width() / dir_bounds.height(), rotation_remaining_angle); + font.print(1,540,"String Hash Seed: %d", gStringHashSeed); if(!gGourceSettings.ffp) { - font.print(1,580,"File VBO: %d/%d vertices, %d texture changes", file_vbo.vertices(), file_vbo.capacity(), file_vbo.texture_changes()); - font.print(1,600,"User VBO: %d/%d vertices, %d texture changes", user_vbo.vertices(), user_vbo.capacity(), user_vbo.texture_changes()); + font.print(1,560,"File VBO: %d/%d vertices, %d texture changes", file_vbo.vertices(), file_vbo.capacity(), file_vbo.texture_changes()); + font.print(1,580,"User VBO: %d/%d vertices, %d texture changes", user_vbo.vertices(), user_vbo.capacity(), user_vbo.texture_changes()); } if(selectedUser != 0) { @@ -2416,7 +2421,7 @@ void Gource::draw(float t, float dt) { } if(selectedFile != 0) { - font.print(1,620,"%s: %d files (%d visible)", selectedFile->getDir()->getPath().c_str(), + font.print(1,600,"%s: %d files (%d visible)", selectedFile->getDir()->getPath().c_str(), selectedFile->getDir()->fileCount(), selectedFile->getDir()->visibleFileCount()); } } diff --git a/src/gource.h b/src/gource.h index 6d0e0937..a6654845 100644 --- a/src/gource.h +++ b/src/gource.h @@ -150,6 +150,7 @@ class Gource : public SDLApp { float idle_time; + Uint32 screen_project_time; Uint32 draw_edges_time; Uint32 draw_shadows_time; Uint32 draw_actions_time; @@ -162,7 +163,6 @@ class Gource : public SDLApp { Uint32 draw_scene_time; Uint32 logic_time; Uint32 trace_time; - Uint32 name_calc_time; Uint32 name_draw_time; bool track_users; diff --git a/src/pawn.h b/src/pawn.h index 880fbae1..38da0e2d 100644 --- a/src/pawn.h +++ b/src/pawn.h @@ -32,8 +32,6 @@ class Pawn : public QuadItem { vec2f pos; vec2f shadowOffset; - vec3f screenpos; - std::string name; float namewidth; vec2f accel; @@ -67,6 +65,7 @@ class Pawn : public QuadItem { float size; float graphic_ratio; TextureResource* graphic; + vec3f screenpos; Pawn(const std::string& name, vec2f pos, int tagid); const vec2f & getPos() const { return pos; } From d258333610fd8bf8196bf7eb10e9f862f53af237 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 20:52:16 +1200 Subject: [PATCH 21/56] Delete data in destructor. --- src/vbo.cpp | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/src/vbo.cpp b/src/vbo.cpp index d72c3e4e..0fcc43d3 100644 --- a/src/vbo.cpp +++ b/src/vbo.cpp @@ -23,28 +23,29 @@ qbuf2f::qbuf2f(int data_size) : data_size(data_size) { bufferid = 0; buffer_size = 0; vertex_count = 0; - + data = new qbuf2f_vertex[data_size]; - + //fprintf(stderr, "size of qbuf2f_vertex = %d\n", sizeof(qbuf2f_vertex)); } qbuf2f::~qbuf2f() { if(bufferid !=0) glDeleteBuffers(1, &bufferid); + delete[] data; } void qbuf2f::resize(int new_size) { - + qbuf2f_vertex* _data = data; - + data = new qbuf2f_vertex[new_size]; - + for(int i=0;i data_size) { resize(vertex_count*2); } - + data[i] = v1; data[i+1] = v2; data[i+2] = v3; data[i+3] = v4; - + if(textures.empty() || textures.back().textureid != textureid) { - textures.push_back(qbuf2f_tex(i, textureid)); - } + textures.push_back(qbuf2f_tex(i, textureid)); + } } void qbuf2f::update() { @@ -106,7 +107,7 @@ void qbuf2f::update() { if(bufferid==0) { glGenBuffers(1, &bufferid); } - + glBindBuffer(GL_ARRAY_BUFFER, bufferid); //recreate buffer if less than the vertex_count @@ -116,7 +117,7 @@ void qbuf2f::update() { } else { glBufferSubData(GL_ARRAY_BUFFER, 0, vertex_count*sizeof(qbuf2f_vertex), &(data[0].pos.x)); } - + glBindBuffer(GL_ARRAY_BUFFER, 0); } @@ -129,12 +130,12 @@ void qbuf2f::draw() { glEnableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), 0); + glVertexPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), 0); glColorPointer(4, GL_FLOAT, sizeof(qbuf2f_vertex), (GLvoid*)8); // offset pos (2x4 bytes) glTexCoordPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), (GLvoid*)24); // offset pos + colour (2x4 + 4x4 bytes) - + int last_index = vertex_count-1; - + for(std::vector::iterator it = textures.begin(); it != textures.end();) { qbuf2f_tex* tex = &(*it); @@ -147,13 +148,13 @@ void qbuf2f::draw() { } else { end_index = (*it).start_index; } - + glBindTexture(GL_TEXTURE_2D, tex->textureid); glDrawArrays(GL_QUADS, tex->start_index, end_index - tex->start_index + 1); if(end_index==last_index) break; } - + glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); From af2e8d9f1c499fe33cb9198cf100d553c9175c20 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 20:53:20 +1200 Subject: [PATCH 22/56] Updated codeblocks project to use freetype2. --- gource.win32.cbp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gource.win32.cbp b/gource.win32.cbp index ec4db92b..53c628a9 100644 --- a/gource.win32.cbp +++ b/gource.win32.cbp @@ -22,7 +22,6 @@ - @@ -32,6 +31,7 @@ + From 4395ffc92dd2def4758ca777676e3c1b9478fd0e Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 23:40:08 +1200 Subject: [PATCH 23/56] Added bloom shader. --- Makefile.am | 2 +- data/shaders/bloom.frag | 10 ++++ data/shaders/bloom.vert | 10 ++++ src/bloom.cpp | 128 ++++++++++++++++++++++++++++++++++++++++ src/bloom.h | 65 ++++++++++++++++++++ src/dirnode.cpp | 49 ++++++++++----- src/dirnode.h | 2 + src/gource.cpp | 92 ++++++++++++++++++----------- src/gource.h | 12 ++-- 9 files changed, 313 insertions(+), 57 deletions(-) create mode 100644 data/shaders/bloom.frag create mode 100644 data/shaders/bloom.vert create mode 100644 src/bloom.cpp create mode 100644 src/bloom.h diff --git a/Makefile.am b/Makefile.am index c53d8fed..cc7917cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,7 +59,7 @@ CPPFLAGS = -DSDLAPP_RESOURCE_DIR=\"$(pkgdatadir)\" dist_pkgdata_DATA = data/beam.png data/bloom.tga data/bloom_alpha.tga data/cursor.png data/file.png data/no_photo.png data/gource.style shadersdir = $(pkgdatadir)/shaders -dist_shaders_DATA = data/shaders/shadow.vert data/shaders/shadow.frag +dist_shaders_DATA = data/shaders/shadow.vert data/shaders/shadow.frag data/shaders/bloom.vert data/shaders/bloom.frag install-data-hook: mkdir -p -m 755 ${DESTDIR}/$(mandir)/man1 diff --git a/data/shaders/bloom.frag b/data/shaders/bloom.frag new file mode 100644 index 00000000..d7c39b60 --- /dev/null +++ b/data/shaders/bloom.frag @@ -0,0 +1,10 @@ + +varying vec3 pos; + +void main() +{ + float intensity = min(1.0, cos(length(pos*2.0)/gl_TexCoord[0].x)); + float gradient = intensity * smoothstep(0.0, 2.0, intensity); + + gl_FragColor = gl_Color * gradient; +} diff --git a/data/shaders/bloom.vert b/data/shaders/bloom.vert new file mode 100644 index 00000000..7274540e --- /dev/null +++ b/data/shaders/bloom.vert @@ -0,0 +1,10 @@ + +varying vec3 pos; + +void main() +{ + pos = gl_Vertex.xyz - gl_MultiTexCoord0.yzw; + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_FrontColor = gl_Color; + gl_Position = ftransform(); +} diff --git a/src/bloom.cpp b/src/bloom.cpp new file mode 100644 index 00000000..71dd5338 --- /dev/null +++ b/src/bloom.cpp @@ -0,0 +1,128 @@ +/* + Copyright (C) 2011 Andrew Caudwell (acaudwell@gmail.com) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "bloom.h" + +//bloom_buf + +bloom_buf::bloom_buf(int data_size) : data_size(data_size) { + bufferid = 0; + buffer_size = 0; + vertex_count = 0; + + data = new bloom_vertex[data_size]; + + //fprintf(stderr, "size of bloom_vertex = %d\n", sizeof(bloom_vertex)); +} + +bloom_buf::~bloom_buf() { + if(bufferid !=0) glDeleteBuffers(1, &bufferid); + delete[] data; +} + +void bloom_buf::resize(int new_size) { + + bloom_vertex* _data = data; + + data = new bloom_vertex[new_size]; + + for(int i=0;i data_size) { + resize(vertex_count*2); + } + + data[i] = v1; + data[i+1] = v2; + data[i+2] = v3; + data[i+3] = v4; +} + +void bloom_buf::update() { + if(vertex_count==0) return; + + //note possibly better to have a queue and cycle them here + if(bufferid==0) { + glGenBuffers(1, &bufferid); + } + + glBindBuffer(GL_ARRAY_BUFFER, bufferid); + + //recreate buffer if less than the vertex_count + if(buffer_size < vertex_count) { + buffer_size = data_size; + glBufferData(GL_ARRAY_BUFFER, buffer_size*sizeof(bloom_vertex), &(data[0].pos.x), GL_DYNAMIC_DRAW); + } else { + glBufferSubData(GL_ARRAY_BUFFER, 0, vertex_count*sizeof(bloom_vertex), &(data[0].pos.x)); + } + + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +void bloom_buf::draw() { + if(vertex_count==0 || bufferid==0) return; + + glBindBuffer(GL_ARRAY_BUFFER, bufferid); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + glVertexPointer(2, GL_FLOAT, sizeof(bloom_vertex), 0); + glColorPointer(4, GL_FLOAT, sizeof(bloom_vertex), (GLvoid*)8); // offset pos (2x4 bytes) + glTexCoordPointer(4, GL_FLOAT, sizeof(bloom_vertex), (GLvoid*)24); // offset pos + colour (2x4 + 4x4 bytes) + + glDrawArrays(GL_QUADS, 0, vertex_count); + + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + + glBindBuffer(GL_ARRAY_BUFFER, 0); +} diff --git a/src/bloom.h b/src/bloom.h new file mode 100644 index 00000000..fd3395c6 --- /dev/null +++ b/src/bloom.h @@ -0,0 +1,65 @@ +/* + Copyright (C) 2011 Andrew Caudwell (acaudwell@gmail.com) + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version + 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef GOURCE_BLOOM_VBO_H +#define GOURCE_BLOOM_VBO_H + +#include + +#include "core/display.h" +#include "core/vectors.h" +#include "core/logger.h" + +//note this should be 64 bytes +class bloom_vertex { +public: + bloom_vertex() {}; + bloom_vertex(const vec2f& pos, const vec4f& colour, const vec4f& texcoord) : pos(pos), colour(colour), texcoord(texcoord) {}; + + vec2f pos; + vec4f colour; + vec4f texcoord; + char padding[22]; +}; + +class bloom_buf { + + bloom_vertex* data; + int data_size; + + GLuint bufferid; + int buffer_size; + + int vertex_count; + + void resize(int new_size); +public: + bloom_buf(int data_size = 1); + ~bloom_buf(); + + void reset(); + + size_t vertices(); + size_t capacity(); + + void add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord); + + void update(); + void draw(); +}; + +#endif diff --git a/src/dirnode.cpp b/src/dirnode.cpp index 1a020de7..3f6c9904 100644 --- a/src/dirnode.cpp +++ b/src/dirnode.cpp @@ -910,36 +910,36 @@ void RDirNode::drawDirName(const FXFont& dirfont) const{ void RDirNode::calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* projection) { static GLdouble screen_x, screen_y, screen_z; - + gluProject( pos.x, pos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z); - screen_y = (float)viewport[3] - screen_y; + screen_y = (float)viewport[3] - screen_y; projected_pos.x = screen_x; projected_pos.y = screen_y; gluProject( spos.x, spos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z); - screen_y = (float)viewport[3] - screen_y; + screen_y = (float)viewport[3] - screen_y; projected_spos.x = screen_x; projected_spos.y = screen_y; static vec2f selected_offset(5.5f, -2.0f); static vec2f unselected_offset(5.5f, -1.0f); - + if(!gGourceSettings.hide_filenames) { - + //first pass - calculate positions of names for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { RFile* f = *it; - + vec2f text_pos = f->getAbsolutePos(); text_pos.x += 5.5f; - + if(f->isSelected()) text_pos.y -= 2.0f; else text_pos.y -= 1.0f; - + gluProject( text_pos.x, text_pos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z); - screen_y = (float)viewport[3] - screen_y; + screen_y = (float)viewport[3] - screen_y; f->screenpos.x = screen_x; f->screenpos.y = screen_y; } @@ -1028,6 +1028,25 @@ void RDirNode::updateFilesVBO(qbuf2f& buffer, float dt) const{ } } +void RDirNode::updateBloomVBO(bloom_buf& buffer, float dt) { + + if(in_frustum && isVisible()) { + + float bloom_radius = dir_radius * 2.0 * gGourceSettings.bloom_multiplier; + float bloom_diameter = bloom_radius * 2.0; + vec4f bloom_col = col * gGourceSettings.bloom_intensity; + + vec4f bloom_texcoords(bloom_radius, pos.x, pos.y, 0.0f); + + buffer.add(0, pos, vec2f(bloom_diameter, bloom_diameter), vec4f(bloom_col.x, bloom_col.y, bloom_col.z, 1.0f), bloom_texcoords); + } + + for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { + RDirNode* node = (*it); + node->updateBloomVBO(buffer,dt); + } +} + void RDirNode::drawFiles(float dt) const{ if(in_frustum) { @@ -1066,7 +1085,7 @@ const vec2f & RDirNode::getProjectedPos() const{ void RDirNode::drawEdgeShadows(float dt) const{ if(parent!=0 && (!gGourceSettings.hide_root || parent->parent !=0)) spline.drawShadow(); - + for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* child = (*it); @@ -1080,7 +1099,7 @@ void RDirNode::drawEdgeShadows(float dt) const{ void RDirNode::drawEdges(float dt) const{ if(parent!=0 && (!gGourceSettings.hide_root || parent->parent !=0)) spline.draw(); - + for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { RDirNode* child = (*it); @@ -1105,13 +1124,13 @@ void RDirNode::drawBloom(float dt){ glTranslatef(pos.x, pos.y, 0.0); glBegin(GL_QUADS); - glTexCoord2f(1.0, 1.0); + glTexCoord2f(1.0f, 1.0f); glVertex2f(bloom_radius,bloom_radius); - glTexCoord2f(1.0, 0.0); + glTexCoord2f(1.0f, 0.0f); glVertex2f(bloom_radius,-bloom_radius); - glTexCoord2f(0.0, 0.0); + glTexCoord2f(0.0f, 0.0f); glVertex2f(-bloom_radius,-bloom_radius); - glTexCoord2f(0.0, 1.0); + glTexCoord2f(0.0f, 1.0f); glVertex2f(-bloom_radius,bloom_radius); glEnd(); glPopMatrix(); diff --git a/src/dirnode.h b/src/dirnode.h index 3020487e..b9cf702b 100644 --- a/src/dirnode.h +++ b/src/dirnode.h @@ -28,6 +28,7 @@ #include "spline.h" #include "file.h" #include "vbo.h" +#include "bloom.h" #include #include @@ -189,6 +190,7 @@ class RDirNode : public QuadItem { void checkFrustum(const Frustum & frustum); void updateFilesVBO(qbuf2f& buffer, float dt) const; + void updateBloomVBO(bloom_buf& buffer, float dt); void drawShadows(float dt) const; void drawFiles(float dt) const; diff --git a/src/gource.cpp b/src/gource.cpp index 4c4c8896..dc6ab2c4 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -52,10 +52,11 @@ Gource::Gource(FrameExporter* exporter) { beamtex = texturemanager.grab("beam.png"); usertex = texturemanager.grab("no_photo.png"); - shadow_shader = 0; + shadow_shader = bloom_shader = 0; if(!gGourceSettings.ffp) { shadow_shader = shadermanager.grab("shadow"); + bloom_shader = shadermanager.grab("bloom"); } logotex = 0; @@ -152,7 +153,7 @@ void Gource::writeCustomLog(const std::string& logfile, const std::string& outpu RCommit commit; - if(!commitlog->nextCommit(commit)) { + if(!commitlog->nextCommit(commit)) { if(!commitlog->isSeekable()) { break; } @@ -873,7 +874,7 @@ void Gource::reset() { tagfilemap.clear(); tagusermap.clear(); gGourceRemovedFiles.clear(); - + if(userTree!=0) delete userTree; if(dirNodeTree!=0) delete dirNodeTree; @@ -918,8 +919,8 @@ void Gource::reset() { delete it->second; } - users.clear(); - + users.clear(); + //delete for(std::map::iterator it = files.begin(); it != files.end(); it++) { delete it->second; @@ -1877,7 +1878,7 @@ void Gource::drawScene(float dt) { draw_edges_time = SDL_GetTicks() - draw_edges_time; //draw shadows - + draw_shadows_time = SDL_GetTicks(); drawUserShadows(dt); @@ -1885,23 +1886,23 @@ void Gource::drawScene(float dt) { drawFileShadows(dt); draw_shadows_time = SDL_GetTicks() - draw_shadows_time; - + //draw actions - + draw_actions_time = SDL_GetTicks(); - + drawActions(dt); draw_actions_time = SDL_GetTicks() - draw_actions_time; //draw files - + draw_files_time = SDL_GetTicks(); - + drawFiles(dt); draw_files_time = SDL_GetTicks() - draw_files_time; - + //draw users draw_users_time = SDL_GetTicks(); @@ -1909,9 +1910,9 @@ void Gource::drawScene(float dt) { drawUsers(dt); draw_users_time = SDL_GetTicks() - draw_users_time; - + //draw bloom - + draw_bloom_time = SDL_GetTicks(); drawBloom(dt); @@ -1942,10 +1943,21 @@ void Gource::drawBloom(float dt) { glEnable(GL_BLEND); glBlendFunc (GL_ONE, GL_ONE); - //draw 'gourceian blur' around dirnodes - glBindTexture(GL_TEXTURE_2D, bloomtex->textureid); + if(!gGourceSettings.ffp) { + + bloom_shader->use(); + + bloom_vbo.draw(); + + glUseProgramObjectARB(0); + + } else { + + //draw 'gourceian blur' around dirnodes + glBindTexture(GL_TEXTURE_2D, bloomtex->textureid); - root->drawBloom(dt); + root->drawBloom(dt); + } } void Gource::setMessage(const char* str, ...) { @@ -2024,6 +2036,10 @@ void Gource::updateVBOs(float dt) { } user_vbo.update(); + bloom_vbo.reset(); + root->updateBloomVBO(bloom_vbo, dt); + bloom_vbo.update(); + file_vbo.reset(); root->updateFilesVBO(file_vbo, dt); file_vbo.update(); @@ -2055,7 +2071,7 @@ void Gource::drawFileShadows(float dt) { void Gource::drawUserShadows(float dt) { if(gGourceSettings.hide_users) return; - + glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2065,7 +2081,7 @@ void Gource::drawUserShadows(float dt) { shadow_shader->use(); vec2f shadow_offset = vec2f(2.0, 2.0) * gGourceSettings.user_scale; - + glPushMatrix(); glTranslatef(shadow_offset.x, shadow_offset.y, 0.0f); @@ -2111,12 +2127,12 @@ void Gource::drawUsers(float dt) { } else { glEnable(GL_TEXTURE_2D); } - + glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if(!gGourceSettings.ffp) { - + user_vbo.draw(); } else { @@ -2171,7 +2187,7 @@ void Gource::draw(float t, float dt) { root->checkFrustum(frustum); screen_project_time = SDL_GetTicks(); - + GLint viewport[4]; GLdouble modelview[16]; GLdouble projection[16]; @@ -2179,25 +2195,29 @@ void Gource::draw(float t, float dt) { glGetIntegerv( GL_VIEWPORT, viewport ); glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); glGetDoublev( GL_PROJECTION_MATRIX, projection ); - + root->calcScreenPos(viewport, modelview, projection); - - screen_project_time = SDL_GetTicks() - screen_project_time; - + + screen_project_time = SDL_GetTicks() - screen_project_time; + //update file and user vbos update_vbos_time = SDL_GetTicks(); - + updateVBOs(dt); - update_vbos_time = SDL_GetTicks() - update_vbos_time; - + update_vbos_time = SDL_GetTicks() - update_vbos_time; + //draw scene - draw_scene_time = SDL_GetTicks(); - + draw_scene_time = SDL_GetTicks(); + drawScene(dt); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + draw_scene_time = SDL_GetTicks() - draw_scene_time; glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -2206,7 +2226,7 @@ void Gource::draw(float t, float dt) { //switch to 2D, preserve current state display.push2D(); - + root->drawNames(font); //switch back @@ -2398,8 +2418,8 @@ void Gource::draw(float t, float dt) { font.print(1,280," - Edges: %u ms", draw_edges_time); font.print(1,300," - Shadows: %u ms", draw_shadows_time); font.print(1,320," - Actions: %u ms", draw_actions_time); - font.print(1,340," - Files: %u ms", draw_files_time); - font.print(1,360," - Users: %u ms", draw_users_time); + font.print(1,340," - Files: %u ms", draw_files_time); + font.print(1,360," - Users: %u ms", draw_users_time); font.print(1,380," - Bloom: %u ms", draw_bloom_time); font.print(1,400,"Text: %u ms", name_draw_time); font.print(1,420,"Mouse Trace: %u ms", trace_time); @@ -2410,12 +2430,12 @@ void Gource::draw(float t, float dt) { dirNodeTree->item_count, dirNodeTree->node_count, dirNodeTree->max_node_depth); font.print(1,520,"Dir Bounds Ratio: %.2f, %.5f", dir_bounds.width() / dir_bounds.height(), rotation_remaining_angle); font.print(1,540,"String Hash Seed: %d", gStringHashSeed); - + if(!gGourceSettings.ffp) { font.print(1,560,"File VBO: %d/%d vertices, %d texture changes", file_vbo.vertices(), file_vbo.capacity(), file_vbo.texture_changes()); font.print(1,580,"User VBO: %d/%d vertices, %d texture changes", user_vbo.vertices(), user_vbo.capacity(), user_vbo.texture_changes()); } - + if(selectedUser != 0) { } diff --git a/src/gource.h b/src/gource.h index a6654845..8e2b82cc 100644 --- a/src/gource.h +++ b/src/gource.h @@ -49,6 +49,7 @@ #include "svn.h" #include "vbo.h" +#include "bloom.h" #include "slider.h" #include "textbox.h" #include "action.h" @@ -89,7 +90,7 @@ class Gource : public SDLApp { bool recolour; bool update_file_labels; - + bool use_selection_bounds; Bounds2D selection_bounds; @@ -111,8 +112,9 @@ class Gource : public SDLApp { RUser* hoverUser; RUser* selectedUser; - qbuf2f user_vbo; - qbuf2f file_vbo; + qbuf2f user_vbo; + qbuf2f file_vbo; + bloom_buf bloom_vbo; GLuint selectionDepth; @@ -127,7 +129,7 @@ class Gource : public SDLApp { TextureResource* backgroundtex; TextureResource* usertex; Shader* shadow_shader; - + Shader* bloom_shader; TextBox textbox; @@ -179,7 +181,7 @@ class Gource : public SDLApp { QuadTree* dirNodeTree; QuadTree* userTree; - + std::string message; float message_timer; From b01471d68af87b7e317c80cbee44d2ec2f7e9915 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 23:47:41 +1200 Subject: [PATCH 24/56] Resized console on Windows to fit help message. --- src/gource_settings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gource_settings.cpp b/src/gource_settings.cpp index 2632419a..91aa5f4c 100644 --- a/src/gource_settings.cpp +++ b/src/gource_settings.cpp @@ -26,7 +26,7 @@ void GourceSettings::help(bool extended_help) { SDLAppCreateWindowsConsole(); //resize window to fit help message - SDLAppResizeWindowsConsole(800); + SDLAppResizeWindowsConsole(820); #endif printf("Gource v%s\n", GOURCE_VERSION); From 0f77b34ae2766b12ffbfa22aa35a7ec717b65558 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 19 Apr 2011 23:51:18 +1200 Subject: [PATCH 25/56] Added status of bloom VBO. --- src/gource.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/gource.cpp b/src/gource.cpp index dc6ab2c4..209fc4a6 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -2434,6 +2434,7 @@ void Gource::draw(float t, float dt) { if(!gGourceSettings.ffp) { font.print(1,560,"File VBO: %d/%d vertices, %d texture changes", file_vbo.vertices(), file_vbo.capacity(), file_vbo.texture_changes()); font.print(1,580,"User VBO: %d/%d vertices, %d texture changes", user_vbo.vertices(), user_vbo.capacity(), user_vbo.texture_changes()); + font.print(1,600,"Bloom VBO: %d/%d vertices", bloom_vbo.vertices(), bloom_vbo.capacity()); } if(selectedUser != 0) { @@ -2441,7 +2442,7 @@ void Gource::draw(float t, float dt) { } if(selectedFile != 0) { - font.print(1,600,"%s: %d files (%d visible)", selectedFile->getDir()->getPath().c_str(), + font.print(1,620,"%s: %d files (%d visible)", selectedFile->getDir()->getPath().c_str(), selectedFile->getDir()->fileCount(), selectedFile->getDir()->visibleFileCount()); } } From d291e96330c1f07a52f383d552e416b7d09adc7d Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 20 Apr 2011 00:04:05 +1200 Subject: [PATCH 26/56] Updated codeblocks project to with bloom shader / vbo. --- gource.win32.cbp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gource.win32.cbp b/gource.win32.cbp index 53c628a9..108748c3 100644 --- a/gource.win32.cbp +++ b/gource.win32.cbp @@ -33,12 +33,16 @@ + + + + From ffed750a7cfd0e5bae9ede5df59dbfb42f683053 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 20 Apr 2011 10:27:13 +1200 Subject: [PATCH 27/56] Eliminated edge colour banding using low frequency noise. --- data/shaders/bloom.frag | 2 ++ 1 file changed, 2 insertions(+) diff --git a/data/shaders/bloom.frag b/data/shaders/bloom.frag index d7c39b60..a467a49d 100644 --- a/data/shaders/bloom.frag +++ b/data/shaders/bloom.frag @@ -6,5 +6,7 @@ void main() float intensity = min(1.0, cos(length(pos*2.0)/gl_TexCoord[0].x)); float gradient = intensity * smoothstep(0.0, 2.0, intensity); + gradient *= smoothstep(1.0,0.33333+fract(sin(dot(pos.xy ,vec2(11.3713,67.3219))) * 2351.3718)*0.66667, 1.0-intensity); + gl_FragColor = gl_Color * gradient; } From cb944eaba44a50b1daf5fbd41b12c6952c082501 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 20 Apr 2011 10:27:54 +1200 Subject: [PATCH 28/56] Fixed Makefile. --- Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.am b/Makefile.am index cc7917cd..cdd0c445 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5,6 +5,7 @@ bin_PROGRAMS = gource gource_SOURCES = \ src/action.cpp src/action.h \ src/apache.cpp src/apache.h \ + src/bloom.cpp src/bloom.h \ src/bzr.cpp src/bzr.h \ src/commitlog.cpp src/commitlog.h \ src/core/bounds.h \ From dea5f59fc6710c61d47ed720c1d41409d80581a3 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 20 Apr 2011 14:23:02 +1200 Subject: [PATCH 29/56] Updated ChangeLog. --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index 8ea63600..f7cd6675 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 0.34: * Now using VBOs and shaders for faster rendering when OpenGL 2.0 is available. + * Eliminated most bloom colour banding artifacts (requires OpenGL 2.0). * New font rendering library derived from FTGL (FTGL no longer required). * Added --no-vsync option. From 2c20274f8e303404733779a2798d7ee7cc969e24 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 20 Apr 2011 21:51:59 +1200 Subject: [PATCH 30/56] Eliminate more banding. Sample the gradient a small random offset along the radius of the bloom. --- data/shaders/bloom.frag | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/data/shaders/bloom.frag b/data/shaders/bloom.frag index a467a49d..81960feb 100644 --- a/data/shaders/bloom.frag +++ b/data/shaders/bloom.frag @@ -3,10 +3,14 @@ varying vec3 pos; void main() { - float intensity = min(1.0, cos(length(pos*2.0)/gl_TexCoord[0].x)); - float gradient = intensity * smoothstep(0.0, 2.0, intensity); + float r = fract(sin(dot(pos.xy ,vec2(11.3713,67.3219))) * 2351.3718); - gradient *= smoothstep(1.0,0.33333+fract(sin(dot(pos.xy ,vec2(11.3713,67.3219))) * 2351.3718)*0.66667, 1.0-intensity); + float offset = (0.5 - r) * gl_TexCoord[0].x * 0.045; + + float intensity = min(1.0, cos((length(pos*2.0)+offset)/gl_TexCoord[0].x)); + float gradient = intensity * smoothstep(0.0, 2.0, intensity); + + gradient *= smoothstep(1.0,0.67+r*0.33, 1.0-intensity); gl_FragColor = gl_Color * gradient; } From 2b6334c0c6141dc6f8a1663286f056422738656d Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 20 Apr 2011 21:53:34 +1200 Subject: [PATCH 31/56] Handle case where files are hidden but we still need projected position of the selected file. --- src/gource.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gource.cpp b/src/gource.cpp index 209fc4a6..d2bb8a37 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -2198,6 +2198,12 @@ void Gource::draw(float t, float dt) { root->calcScreenPos(viewport, modelview, projection); + //need to calc screen pos of selected file if hiding other + //file names + if(selectedFile!=0 && gGourceSettings.hide_filenames) { + selectedFile->calcScreenPos(selectedFile->getDir()->getPos()+vec2f(5.5f, -2.0f)); + } + screen_project_time = SDL_GetTicks() - screen_project_time; //update file and user vbos From 98d9b0c4f0a1284f1c7ed4aff04e90bef8325985 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Sun, 24 Apr 2011 23:43:02 +1200 Subject: [PATCH 32/56] Fixed indentation. --- data/shaders/shadow.vert | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/shaders/shadow.vert b/data/shaders/shadow.vert index d1866500..df9b6994 100644 --- a/data/shaders/shadow.vert +++ b/data/shaders/shadow.vert @@ -1,6 +1,6 @@ void main(void) { - gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_TexCoord[0] = gl_MultiTexCoord0; - gl_FrontColor = gl_Color; + gl_FrontColor = gl_Color; } From 9045665961eab4de7bf1dd4dc08c6923d2a53116 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Sun, 24 Apr 2011 23:43:26 +1200 Subject: [PATCH 33/56] Parameterized shadow_strength. --- data/shaders/shadow.frag | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/data/shaders/shadow.frag b/data/shaders/shadow.frag index 8b58e3ea..6235f7f3 100644 --- a/data/shaders/shadow.frag +++ b/data/shaders/shadow.frag @@ -1,8 +1,9 @@ uniform sampler2D tex; +uniform float shadow_strength; void main(void) { vec4 colour = texture2D(tex,gl_TexCoord[0].st); - gl_FragColor = vec4(0.0, 0.0, 0.0, gl_Color.w * colour.w * 0.5); + gl_FragColor = vec4(0.0, 0.0, 0.0, gl_Color.w * colour.w * shadow_strength); } From fe485bee147bc28c2cc1c4786629858e5eabc993 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Sun, 24 Apr 2011 23:50:58 +1200 Subject: [PATCH 34/56] Renamed class. --- src/bloom.cpp | 30 ++++++++++++++---------------- src/bloom.h | 6 +++--- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/src/bloom.cpp b/src/bloom.cpp index 71dd5338..a07c0402 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -17,9 +17,9 @@ #include "bloom.h" -//bloom_buf +//bloombuf -bloom_buf::bloom_buf(int data_size) : data_size(data_size) { +bloombuf::bloombuf(int data_size) : data_size(data_size) { bufferid = 0; buffer_size = 0; vertex_count = 0; @@ -29,12 +29,12 @@ bloom_buf::bloom_buf(int data_size) : data_size(data_size) { //fprintf(stderr, "size of bloom_vertex = %d\n", sizeof(bloom_vertex)); } -bloom_buf::~bloom_buf() { +bloombuf::~bloombuf() { if(bufferid !=0) glDeleteBuffers(1, &bufferid); delete[] data; } -void bloom_buf::resize(int new_size) { +void bloombuf::resize(int new_size) { bloom_vertex* _data = data; @@ -49,26 +49,24 @@ void bloom_buf::resize(int new_size) { delete[] _data; } -void bloom_buf::reset() { +void bloombuf::reset() { vertex_count = 0; } -size_t bloom_buf::vertices() { +size_t bloombuf::vertices() { return vertex_count; } -size_t bloom_buf::capacity() { +size_t bloombuf::capacity() { return data_size; } -void bloom_buf::add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord) { +void bloombuf::add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord) { - vec2f offset = pos - dims * 0.5; - - bloom_vertex v1(offset, colour, texcoord); - bloom_vertex v2(offset + vec2f(dims.x, 0.0f), colour, texcoord); - bloom_vertex v3(offset + dims, colour, texcoord); - bloom_vertex v4(offset + vec2f(0.0f, dims.y), colour, texcoord); + bloom_vertex v1(pos, colour, texcoord); + bloom_vertex v2(pos + vec2f(dims.x, 0.0f), colour, texcoord); + bloom_vertex v3(pos + dims, colour, texcoord); + bloom_vertex v4(pos + vec2f(0.0f, dims.y), colour, texcoord); int i = vertex_count; @@ -84,7 +82,7 @@ void bloom_buf::add(GLuint textureid, const vec2f& pos, const vec2f& dims, const data[i+3] = v4; } -void bloom_buf::update() { +void bloombuf::update() { if(vertex_count==0) return; //note possibly better to have a queue and cycle them here @@ -105,7 +103,7 @@ void bloom_buf::update() { glBindBuffer(GL_ARRAY_BUFFER, 0); } -void bloom_buf::draw() { +void bloombuf::draw() { if(vertex_count==0 || bufferid==0) return; glBindBuffer(GL_ARRAY_BUFFER, bufferid); diff --git a/src/bloom.h b/src/bloom.h index fd3395c6..7f8ed7fd 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -36,7 +36,7 @@ class bloom_vertex { char padding[22]; }; -class bloom_buf { +class bloombuf { bloom_vertex* data; int data_size; @@ -48,8 +48,8 @@ class bloom_buf { void resize(int new_size); public: - bloom_buf(int data_size = 1); - ~bloom_buf(); + bloombuf(int data_size = 1); + ~bloombuf(); void reset(); From d6e0e64284e14b565036187aebd933870be1aded Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Sun, 24 Apr 2011 23:52:38 +1200 Subject: [PATCH 35/56] Changed font settings for files, set colour / alpha on font object. Call calcScreenPos() uses provided matrices. --- src/dirnode.cpp | 33 ++++++++-------------- src/dirnode.h | 10 +++---- src/file.cpp | 73 +++++++++++++++++++++++++++---------------------- src/file.h | 12 ++++---- src/pawn.cpp | 18 ++---------- src/pawn.h | 7 +++-- src/user.cpp | 32 +++++++++++----------- src/user.h | 5 +++- 8 files changed, 90 insertions(+), 100 deletions(-) diff --git a/src/dirnode.cpp b/src/dirnode.cpp index 3f6c9904..dec5e8b8 100644 --- a/src/dirnode.cpp +++ b/src/dirnode.cpp @@ -892,7 +892,7 @@ void RDirNode::logic(float dt) { since_last_node_change += dt; } -void RDirNode::drawDirName(const FXFont& dirfont) const{ +void RDirNode::drawDirName(FXFont& dirfont) const{ if(parent==0) return; if(gGourceSettings.hide_dirnames) return; @@ -900,10 +900,11 @@ void RDirNode::drawDirName(const FXFont& dirfont) const{ float alpha = gGourceSettings.highlight_dirs ? 1.0 : std::max(0.0f, 5.0f - since_last_node_change) / 5.0f; - glColor4f(1.0, 1.0, 1.0, alpha); + //glColor4f(1.0, 1.0, 1.0, alpha); vec2f mid = spline.getMidPoint(); + dirfont.setAlpha(alpha); dirfont.draw(mid.x, mid.y, path_token); } @@ -929,19 +930,7 @@ void RDirNode::calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* pro //first pass - calculate positions of names for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { RFile* f = *it; - - vec2f text_pos = f->getAbsolutePos(); - text_pos.x += 5.5f; - - if(f->isSelected()) - text_pos.y -= 2.0f; - else - text_pos.y -= 1.0f; - - gluProject( text_pos.x, text_pos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z); - screen_y = (float)viewport[3] - screen_y; - f->screenpos.x = screen_x; - f->screenpos.y = screen_y; + f->calcScreenPos(viewport, modelview, projection); } } @@ -951,7 +940,7 @@ void RDirNode::calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* pro } } -void RDirNode::drawNames(const FXFont& dirfont) { +void RDirNode::drawNames(FXFont& dirfont) { if(!gGourceSettings.hide_dirnames && isVisible()) { drawDirName(dirfont); @@ -962,7 +951,7 @@ void RDirNode::drawNames(const FXFont& dirfont) { if(!(gGourceSettings.hide_filenames || gGourceSettings.hide_files) && in_frustum) { for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { RFile* f = *it; - f->drawName(); + if(!f->isSelected()) f->drawName(); } } @@ -1008,7 +997,7 @@ void RDirNode::drawShadows(float dt) const{ } } -void RDirNode::updateFilesVBO(qbuf2f& buffer, float dt) const{ +void RDirNode::updateFilesVBO(quadbuf& buffer, float dt) const{ if(in_frustum) { @@ -1018,7 +1007,7 @@ void RDirNode::updateFilesVBO(qbuf2f& buffer, float dt) const{ vec3f col = f->getColour(); float alpha = f->getAlpha(); - buffer.add(f->graphic->textureid, f->getAbsolutePos(), vec2f(f->size, f->graphic_ratio*f->size), vec4f(col.x, col.y, col.z, alpha)); + buffer.add(f->graphic->textureid, f->getAbsolutePos() - f->dims*0.5f, f->dims, vec4f(col.x, col.y, col.z, alpha)); } } @@ -1028,7 +1017,7 @@ void RDirNode::updateFilesVBO(qbuf2f& buffer, float dt) const{ } } -void RDirNode::updateBloomVBO(bloom_buf& buffer, float dt) { +void RDirNode::updateBloomVBO(bloombuf& buffer, float dt) { if(in_frustum && isVisible()) { @@ -1038,7 +1027,9 @@ void RDirNode::updateBloomVBO(bloom_buf& buffer, float dt) { vec4f bloom_texcoords(bloom_radius, pos.x, pos.y, 0.0f); - buffer.add(0, pos, vec2f(bloom_diameter, bloom_diameter), vec4f(bloom_col.x, bloom_col.y, bloom_col.z, 1.0f), bloom_texcoords); + vec2f bloom_dims(bloom_diameter, bloom_diameter); + + buffer.add(0, pos - bloom_dims*0.5f,bloom_dims, vec4f(bloom_col.x, bloom_col.y, bloom_col.z, 1.0f), bloom_texcoords); } for(std::list::const_iterator it = children.begin(); it != children.end(); it++) { diff --git a/src/dirnode.h b/src/dirnode.h index b9cf702b..e16cc5fa 100644 --- a/src/dirnode.h +++ b/src/dirnode.h @@ -22,12 +22,12 @@ #include "core/bounds.h" #include "core/quadtree.h" #include "core/pi.h" +#include "core/vbo.h" #include "gource_settings.h" #include "spline.h" #include "file.h" -#include "vbo.h" #include "bloom.h" #include @@ -97,7 +97,7 @@ class RDirNode : public QuadItem { void updateFilePositions(); void adjustPath(); - void drawDirName(const FXFont& dirfont) const; + void drawDirName(FXFont& dirfont) const; public: RDirNode(RDirNode* parent, const std::string & abspath); ~RDirNode(); @@ -189,14 +189,14 @@ class RDirNode : public QuadItem { void checkFrustum(const Frustum & frustum); - void updateFilesVBO(qbuf2f& buffer, float dt) const; - void updateBloomVBO(bloom_buf& buffer, float dt); + void updateFilesVBO(quadbuf& buffer, float dt) const; + void updateBloomVBO(bloombuf& buffer, float dt); void drawShadows(float dt) const; void drawFiles(float dt) const; void drawBloom(float dt); - void drawNames(const FXFont& dirfont); + void drawNames(FXFont& dirfont); void calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* projection); diff --git a/src/file.cpp b/src/file.cpp index 3b261b2f..d4d84dc8 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -50,18 +50,20 @@ RFile::RFile(const std::string & name, const vec3f & colour, const vec2f & pos, if(!file_selected_font.initialized()) { file_selected_font = fontmanager.grab("FreeSans.ttf", 18); - file_selected_font.dropShadow(false); - file_selected_font.roundCoordinates(true); + file_selected_font.dropShadow(true); + file_selected_font.roundCoordinates(false); + file_selected_font.setColour(vec4f(1.0f, 1.0f, 0.0f, 1.0f)); } - + if(!file_font.initialized()) { file_font = fontmanager.grab("FreeSans.ttf", 14); - file_font.dropShadow(false); - file_font.roundCoordinates(true); + file_font.dropShadow(true); + file_font.roundCoordinates(false); + file_font.setColour(vec4f(1.0f, 1.0f, 1.0f, 1.0f)); } - + //namelist = glGenLists(1); - label = 0; + //label = 0; setSelected(false); dir = 0; @@ -101,7 +103,7 @@ bool RFile::overlaps(const vec2f& pos) const { } void RFile::setFilename(const std::string& abs_file_path) { - + fullpath = abs_file_path; size_t pos = fullpath.rfind('/'); @@ -127,13 +129,13 @@ int call_count = 0; void RFile::setSelected(bool selected) { // if(font.getFTFont()!=0 && this->selected==selected) return; - if(label && this->selected==selected) return; + //if(label && this->selected==selected) return; + +// if(!label) label = new FXLabel(); - if(!label) label = new FXLabel(); - Pawn::setSelected(selected); - updateLabel(); +// updateLabel(); //pre-compile name display list //glNewList(namelist, GL_COMPILE); @@ -142,13 +144,13 @@ void RFile::setSelected(bool selected) { } void RFile::updateLabel() { - bool show_file_ext = gGourceSettings.file_extensions; +/* bool show_file_ext = gGourceSettings.file_extensions; if(selected) { label->setText(file_selected_font, (selected || !show_file_ext) ? name : ext); } else { label->setText(file_font, (selected || !show_file_ext) ? name : ext); - } + }*/ } void RFile::colourize() { @@ -270,31 +272,36 @@ void RFile::setHidden(bool hidden) { Pawn::setHidden(hidden); } -void RFile::drawNameText(float alpha) const { +void RFile::calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* projection) { - if(!selected && alpha <= 0.01) return; + static GLdouble screen_x, screen_y, screen_z; - vec3f nameCol = getNameColour(); - float name_alpha = selected ? 1.0 : alpha; - - glPushMatrix(); + vec2f text_pos = getAbsolutePos(); + text_pos.x += 5.5f; - glTranslatef(screenpos.x, screenpos.y, 0.0); + if(selected) + text_pos.y -= 2.0f; + else + text_pos.y -= 1.0f; - //hard coded drop shadow - glPushMatrix(); - glTranslatef(1.0, 1.0, 0.0); - glColor4f(0.0, 0.0, 0.0, name_alpha * 0.7f); - //glCallList(namelist); - label->draw(); - glPopMatrix(); + gluProject( text_pos.x, text_pos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z); + screen_y = (float)viewport[3] - screen_y; - //draw name - glColor4f(nameCol.x, nameCol.y, nameCol.z, name_alpha); - //glCallList(namelist); - label->draw(); + screenpos.x = screen_x; + screenpos.y = screen_y; +} + +void RFile::drawNameText(float alpha) { + if(!selected && alpha <= 0.01) return; + + float name_alpha = selected ? 1.0 : alpha; - glPopMatrix(); + if(selected) { + file_selected_font.draw(screenpos.x, screenpos.y, name); + } else { + file_font.setAlpha(name_alpha); + file_font.draw(screenpos.x, screenpos.y, gGourceSettings.file_extensions ? ext : name); + } } void RFile::draw(float dt) { diff --git a/src/file.h b/src/file.h index 1d85a3a8..5ded9e03 100644 --- a/src/file.h +++ b/src/file.h @@ -41,14 +41,14 @@ class RFile : public Pawn { vec2f dest; float distance; - FXLabel* label; - + // FXLabel* label; + //GLuint namelist; void setFilename(const std::string& abs_file_path); const vec3f& getNameColour() const; - void drawNameText(float alpha) const; + void drawNameText(float alpha); public: std::string path; std::string fullpath; @@ -71,14 +71,16 @@ class RFile : public Pawn { void touch(const vec3f & colour); void setSelected(bool selected); - + void updateLabel(); - + void setHidden(bool hidden); void setDest(const vec2f & dest){ this->dest = dest; } void setDistance(float distance){ this->distance = distance; } + void calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* projection); + void logic(float dt); void draw(float dt); diff --git a/src/pawn.cpp b/src/pawn.cpp index 3ef68d74..df7b7557 100644 --- a/src/pawn.cpp +++ b/src/pawn.cpp @@ -89,6 +89,7 @@ void Pawn::setGraphic(TextureResource* graphic) { } this->graphic = graphic; + this->dims = vec2f(size, size*graphic_ratio); } @@ -113,26 +114,11 @@ void Pawn::calcScreenPos(const vec2f& offset) { screenpos = display.project(vec3f(pos.x+offset.x, pos.y+offset.y, 0.0f)); } -void Pawn::drawNameText(float alpha) const { - - if(alpha>0.0) { - vec3f nameCol = getNameColour(); - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - glColor4f(nameCol.x, nameCol.y, nameCol.z, alpha); - - font.draw(pos.x - ((float)namewidth/2.0), pos.y - size*1.2, name.c_str()); // above player - } -} - - bool Pawn::nameVisible() const { return (!selected && name_interval < 0.0 || isHidden()) ? false : true; } -void Pawn::drawName() const { +void Pawn::drawName() { if(!nameVisible()) return; float done = nametime - name_interval; diff --git a/src/pawn.h b/src/pawn.h index 38da0e2d..15e42044 100644 --- a/src/pawn.h +++ b/src/pawn.h @@ -52,12 +52,12 @@ class Pawn : public QuadItem { int tagid; FXFont font; - + bool mouseover; virtual bool nameVisible() const; - virtual void drawNameText(float alpha) const; + virtual void drawNameText(float alpha) {}; virtual const vec3f& getNameColour() const; protected: bool selected; @@ -66,6 +66,7 @@ class Pawn : public QuadItem { float graphic_ratio; TextureResource* graphic; vec3f screenpos; + vec2f dims; Pawn(const std::string& name, vec2f pos, int tagid); const vec2f & getPos() const { return pos; } @@ -98,7 +99,7 @@ class Pawn : public QuadItem { void draw(float dt); void drawShadow(float dt); - void drawName() const; + void drawName(); }; extern float gGourceShadowStrength; diff --git a/src/user.cpp b/src/user.cpp index 8135828e..c0309a22 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -374,30 +374,30 @@ bool RUser::nameVisible() const { return (Pawn::nameVisible() || gGourceSettings.highlight_all_users || highlighted) ? true : false; } -void RUser::drawNameText(float alpha) const { - if(gGourceSettings.hide_users) return; - - float user_alpha = getAlpha(); +void RUser::calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* projection) { - if(gGourceSettings.highlight_all_users || highlighted || selected || alpha>0.0) { - vec3f nameCol = getNameColour(); + static GLdouble screen_x, screen_y, screen_z; - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); + vec2f text_pos = pos; + text_pos.y -= dims.y * 0.5f; - vec3f drawpos = vec3f(pos.x, pos.y, 0.0); + gluProject( text_pos.x, text_pos.y, 0.0f, modelview, projection, viewport, &screen_x, &screen_y, &screen_z); - vec3f screenpos = display.project(drawpos - vec3f(0.0, 0.5 * size * graphic_ratio, 0.0f )); - screenpos.x -= namewidth * 0.5; - screenpos.y -= font.getMaxHeight(); + screen_y = (float)viewport[3] - screen_y; - glColor4f(nameCol.x, nameCol.y, nameCol.z, (selected||highlighted||gGourceSettings.highlight_all_users) ? user_alpha : alpha); + screenpos.x = screen_x - namewidth * 0.5; + screenpos.y = screen_y - font.getMaxHeight(); +} - display.push2D(); +void RUser::drawNameText(float alpha) { + float user_alpha = getAlpha(); - font.draw(screenpos.x, screenpos.y, name); // above user + if(gGourceSettings.highlight_all_users || highlighted || selected || alpha>0.0) { + vec3f name_col = getNameColour(); + float name_alpha = (selected||highlighted||gGourceSettings.highlight_all_users) ? user_alpha : alpha; - display.pop2D(); + font.setColour(vec4f(name_col.x, name_col.y, name_col.z, name_alpha)); + font.draw(screenpos.x, screenpos.y, name); } } diff --git a/src/user.h b/src/user.h index c8891c61..6a030ac9 100644 --- a/src/user.h +++ b/src/user.h @@ -56,7 +56,7 @@ class RUser : public Pawn { void updateFont(); const vec3f& getNameColour() const; - void drawNameText(float alpha) const; + void drawNameText(float alpha); public: RUser(const std::string& name, vec2f pos, int tagid); @@ -83,6 +83,9 @@ class RUser : public Pawn { void applyForceToActions(); void applyForceAction(RAction* action); void applyForceUser(RUser* u); + + void calcScreenPos(GLint* viewport, GLdouble* modelview, GLdouble* projection); + void logic(float t, float dt); void drawActions(float dt); From c96cee31279eaa46d47f7c82c9b097985d2210fb Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 25 Apr 2011 00:14:47 +1200 Subject: [PATCH 36/56] Single-pass text and drop shadows for the OpenGL 2.0 pipeline. Thanks to Chris Forbes for helping me with the blending code. --- ChangeLog | 3 +- Makefile.am | 5 +- data/shaders/text.frag | 13 ++++ data/shaders/text.vert | 6 ++ gource.win32.cbp | 9 ++- src/core | 2 +- src/gource.cpp | 98 +++++++++++++++++++------ src/gource.h | 17 +++-- src/vbo.cpp | 163 ----------------------------------------- src/vbo.h | 77 ------------------- 10 files changed, 118 insertions(+), 275 deletions(-) create mode 100644 data/shaders/text.frag create mode 100644 data/shaders/text.vert delete mode 100644 src/vbo.cpp delete mode 100644 src/vbo.h diff --git a/ChangeLog b/ChangeLog index f7cd6675..14f983ad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,8 @@ 0.34: * Now using VBOs and shaders for faster rendering when OpenGL 2.0 is available. - * Eliminated most bloom colour banding artifacts (requires OpenGL 2.0). + * Eliminated bloom colour banding artifacts (requires OpenGL 2.0). * New font rendering library derived from FTGL (FTGL no longer required). + * Single pass font/shadow rendering (with lots of help from Chris Forbes). * Added --no-vsync option. 0.33: diff --git a/Makefile.am b/Makefile.am index cdd0c445..b1e6fb10 100644 --- a/Makefile.am +++ b/Makefile.am @@ -14,6 +14,7 @@ gource_SOURCES = \ src/core/display.cpp src/core/display.h \ src/core/frustum.cpp src/core/frustum.h \ src/core/fxfont.cpp src/core/fxfont.h \ + src/core/gl.h \ src/core/logger.cpp src/core/logger.h \ src/core/mousecursor.cpp src/core/mousecursor.h \ src/core/pi.h \ @@ -32,6 +33,7 @@ gource_SOURCES = \ src/core/utf8/core.h \ src/core/utf8/unchecked.h \ src/core/utf8/utf8.h \ + src/core/vbo.cpp src/core/vbo.h \ src/core/vectors.h \ src/custom.cpp src/custom.h \ src/cvs-exp.cpp src/cvs-exp.h \ @@ -52,7 +54,6 @@ gource_SOURCES = \ src/svn.cpp src/svn.h \ src/textbox.cpp src/textbox.h \ src/user.cpp src/user.h \ - src/vbo.cpp src/vbo.h \ src/zoomcamera.cpp src/zoomcamera.h CPPFLAGS = -DSDLAPP_RESOURCE_DIR=\"$(pkgdatadir)\" @@ -60,7 +61,7 @@ CPPFLAGS = -DSDLAPP_RESOURCE_DIR=\"$(pkgdatadir)\" dist_pkgdata_DATA = data/beam.png data/bloom.tga data/bloom_alpha.tga data/cursor.png data/file.png data/no_photo.png data/gource.style shadersdir = $(pkgdatadir)/shaders -dist_shaders_DATA = data/shaders/shadow.vert data/shaders/shadow.frag data/shaders/bloom.vert data/shaders/bloom.frag +dist_shaders_DATA = data/shaders/shadow.vert data/shaders/shadow.frag data/shaders/bloom.vert data/shaders/bloom.frag data/shaders/text.vert data/shaders/text.frag install-data-hook: mkdir -p -m 755 ${DESTDIR}/$(mandir)/man1 diff --git a/data/shaders/text.frag b/data/shaders/text.frag new file mode 100644 index 00000000..2f010e1b --- /dev/null +++ b/data/shaders/text.frag @@ -0,0 +1,13 @@ +uniform sampler2D tex; +uniform float shadow_strength; +uniform float texel_size; + +void main(void) +{ + float colour_alpha = texture2D(tex,gl_TexCoord[0].xy).w; + float shadow_alpha = texture2D(tex,gl_TexCoord[0].xy - vec2(texel_size)).w * shadow_strength; + + float combined_alpha = 1.0 - (1.0-shadow_alpha)*(1.0-colour_alpha); + + gl_FragColor = gl_Color * vec4(vec3(colour_alpha / combined_alpha), combined_alpha); +} diff --git a/data/shaders/text.vert b/data/shaders/text.vert new file mode 100644 index 00000000..df9b6994 --- /dev/null +++ b/data/shaders/text.vert @@ -0,0 +1,6 @@ +void main(void) +{ + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_FrontColor = gl_Color; +} diff --git a/gource.win32.cbp b/gource.win32.cbp index 108748c3..2a584c09 100644 --- a/gource.win32.cbp +++ b/gource.win32.cbp @@ -37,6 +37,8 @@ + + @@ -58,6 +60,7 @@ + @@ -83,8 +86,12 @@ + + + + @@ -130,8 +137,6 @@ - - diff --git a/src/core b/src/core index 65f3f935..a02b6b46 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit 65f3f93590581bfcc06eac1b4481aa26dbca16b2 +Subproject commit a02b6b467ba04167c7ffc198820f46468d3ecc82 diff --git a/src/gource.cpp b/src/gource.cpp index d2bb8a37..a72be171 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -52,13 +52,19 @@ Gource::Gource(FrameExporter* exporter) { beamtex = texturemanager.grab("beam.png"); usertex = texturemanager.grab("no_photo.png"); - shadow_shader = bloom_shader = 0; + shadow_shader = text_shader = bloom_shader = 0; if(!gGourceSettings.ffp) { - shadow_shader = shadermanager.grab("shadow"); - bloom_shader = shadermanager.grab("bloom"); + shadow_shader = shadermanager.grab("shadow"); + bloom_shader = shadermanager.grab("bloom"); + text_shader = shadermanager.grab("text"); } + //calculate once + GLint max_texture_size; + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size); + font_texel_size = 1.0f / (float) std::min( 512, max_texture_size ); + logotex = 0; backgroundtex = 0; @@ -2032,7 +2038,7 @@ void Gource::updateVBOs(float dt) { float alpha = user->getAlpha(); vec3f col = user->getColour(); - user_vbo.add(user->graphic->textureid, user->getPos(), vec2f(user->size, user->graphic_ratio*user->size), vec4f(col.x, col.y, col.z, alpha)); + user_vbo.add(user->graphic->textureid, user->getPos() - user->dims*0.5f, user->dims, vec4f(col.x, col.y, col.z, alpha)); } user_vbo.update(); @@ -2055,6 +2061,7 @@ void Gource::drawFileShadows(float dt) { if(!gGourceSettings.ffp) { shadow_shader->use(); + shadow_shader->setFloat("shadow_strength", 0.5); glBindTexture(GL_TEXTURE_2D, gGourceSettings.file_graphic->textureid); @@ -2079,6 +2086,7 @@ void Gource::drawUserShadows(float dt) { if(!gGourceSettings.ffp) { shadow_shader->use(); + shadow_shader->setFloat("shadow_strength", 0.5); vec2f shadow_offset = vec2f(2.0, 2.0) * gGourceSettings.user_scale; @@ -2198,10 +2206,14 @@ void Gource::draw(float t, float dt) { root->calcScreenPos(viewport, modelview, projection); + for(std::map::iterator it = users.begin(); it!=users.end(); it++) { + it->second->calcScreenPos(viewport, modelview, projection); + } + //need to calc screen pos of selected file if hiding other //file names if(selectedFile!=0 && gGourceSettings.hide_filenames) { - selectedFile->calcScreenPos(selectedFile->getDir()->getPos()+vec2f(5.5f, -2.0f)); + selectedFile->calcScreenPos(viewport, modelview, projection); } screen_project_time = SDL_GetTicks() - screen_project_time; @@ -2228,22 +2240,54 @@ void Gource::draw(float t, float dt) { glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - name_draw_time = SDL_GetTicks(); + text_time = text_update_time = SDL_GetTicks(); //switch to 2D, preserve current state display.push2D(); - root->drawNames(font); + if(!gGourceSettings.ffp) { + fontmanager.startBuffer(); + } - //switch back - display.pop2D(); + font.roundCoordinates(false); + + root->drawNames(font); - if(!(gGourceSettings.hide_usernames || gGourceSettings.hide_users)) { + if(!(gGourceSettings.hide_usernames || gGourceSettings.hide_users)) { for(std::map::iterator it = users.begin(); it!=users.end(); it++) { it->second->drawName(); } } + text_update_time = SDL_GetTicks() - text_update_time; + + text_vbo_commit_time = 0; + text_vbo_draw_time = 0; + + if(!gGourceSettings.ffp) { + + text_vbo_commit_time = SDL_GetTicks(); + + fontmanager.commitBuffer(); + + text_vbo_commit_time = SDL_GetTicks() - text_vbo_commit_time; + + text_vbo_draw_time = SDL_GetTicks(); + + text_shader->use(); + text_shader->setFloat("shadow_strength", 0.7); + text_shader->setFloat("texel_size", font_texel_size); + + fontmanager.drawBuffer(); + + glUseProgramObjectARB(0); + + text_vbo_draw_time = SDL_GetTicks() - text_vbo_draw_time; + } + + //switch back + display.pop2D(); + //draw selected item names again so they are over the top if(selectedUser !=0) selectedUser->drawName(); @@ -2253,7 +2297,7 @@ void Gource::draw(float t, float dt) { display.pop2D(); } - name_draw_time = SDL_GetTicks() - name_draw_time; + text_time = SDL_GetTicks() - text_time; if(debug) { glDisable(GL_TEXTURE_2D); @@ -2323,6 +2367,8 @@ void Gource::draw(float t, float dt) { glPopMatrix(); } + font.roundCoordinates(true); + if(splash>0.0f) { int logowidth = fontlarge.getWidth("Gource"); int logoheight = 100; @@ -2399,7 +2445,7 @@ void Gource::draw(float t, float dt) { //debug info if(debug) { - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + font.setAlpha(1.0f); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); @@ -2427,20 +2473,24 @@ void Gource::draw(float t, float dt) { font.print(1,340," - Files: %u ms", draw_files_time); font.print(1,360," - Users: %u ms", draw_users_time); font.print(1,380," - Bloom: %u ms", draw_bloom_time); - font.print(1,400,"Text: %u ms", name_draw_time); - font.print(1,420,"Mouse Trace: %u ms", trace_time); - font.print(1,440,"Logic Time: %u ms", logic_time); - font.print(1,460,"File Inner Loops: %d", gGourceFileInnerLoops); - font.print(1,480,"User Inner Loops: %d", gGourceUserInnerLoops); - font.print(1,500,"Dir Inner Loops: %d (QTree items = %d, nodes = %d, max node depth = %d)", gGourceDirNodeInnerLoops, + font.print(1,400,"Text: %u ms", text_time); + font.print(1,420,"- Update: %u ms", text_update_time); + font.print(1,440,"- VBO Commit: %u ms", text_vbo_commit_time); + font.print(1,460,"- VBO Draw: %u ms", text_vbo_draw_time); + font.print(1,480,"Mouse Trace: %u ms", trace_time); + font.print(1,500,"Logic Time: %u ms", logic_time); + font.print(1,520,"File Inner Loops: %d", gGourceFileInnerLoops); + font.print(1,540,"User Inner Loops: %d", gGourceUserInnerLoops); + font.print(1,560,"Dir Inner Loops: %d (QTree items = %d, nodes = %d, max node depth = %d)", gGourceDirNodeInnerLoops, dirNodeTree->item_count, dirNodeTree->node_count, dirNodeTree->max_node_depth); - font.print(1,520,"Dir Bounds Ratio: %.2f, %.5f", dir_bounds.width() / dir_bounds.height(), rotation_remaining_angle); - font.print(1,540,"String Hash Seed: %d", gStringHashSeed); + font.print(1,580,"Dir Bounds Ratio: %.2f, %.5f", dir_bounds.width() / dir_bounds.height(), rotation_remaining_angle); + font.print(1,600,"String Hash Seed: %d", gStringHashSeed); if(!gGourceSettings.ffp) { - font.print(1,560,"File VBO: %d/%d vertices, %d texture changes", file_vbo.vertices(), file_vbo.capacity(), file_vbo.texture_changes()); - font.print(1,580,"User VBO: %d/%d vertices, %d texture changes", user_vbo.vertices(), user_vbo.capacity(), user_vbo.texture_changes()); - font.print(1,600,"Bloom VBO: %d/%d vertices", bloom_vbo.vertices(), bloom_vbo.capacity()); + font.print(1,620,"Text VBO: %d/%d vertices, %d texture changes", fontmanager.font_vbo.vertices(), fontmanager.font_vbo.capacity(), fontmanager.font_vbo.texture_changes()); + font.print(1,640,"File VBO: %d/%d vertices, %d texture changes", file_vbo.vertices(), file_vbo.capacity(), file_vbo.texture_changes()); + font.print(1,660,"User VBO: %d/%d vertices, %d texture changes", user_vbo.vertices(), user_vbo.capacity(), user_vbo.texture_changes()); + font.print(1,680,"Bloom VBO: %d/%d vertices", bloom_vbo.vertices(), bloom_vbo.capacity()); } if(selectedUser != 0) { @@ -2448,7 +2498,7 @@ void Gource::draw(float t, float dt) { } if(selectedFile != 0) { - font.print(1,620,"%s: %d files (%d visible)", selectedFile->getDir()->getPath().c_str(), + font.print(1,700,"%s: %d files (%d visible)", selectedFile->getDir()->getPath().c_str(), selectedFile->getDir()->fileCount(), selectedFile->getDir()->visibleFileCount()); } } diff --git a/src/gource.h b/src/gource.h index 8e2b82cc..719a6173 100644 --- a/src/gource.h +++ b/src/gource.h @@ -48,7 +48,7 @@ #include "apache.h" #include "svn.h" -#include "vbo.h" +#include "core/vbo.h" #include "bloom.h" #include "slider.h" #include "textbox.h" @@ -112,9 +112,9 @@ class Gource : public SDLApp { RUser* hoverUser; RUser* selectedUser; - qbuf2f user_vbo; - qbuf2f file_vbo; - bloom_buf bloom_vbo; + quadbuf user_vbo; + quadbuf file_vbo; + bloombuf bloom_vbo; GLuint selectionDepth; @@ -128,9 +128,13 @@ class Gource : public SDLApp { TextureResource* logotex; TextureResource* backgroundtex; TextureResource* usertex; + Shader* shadow_shader; + Shader* text_shader; Shader* bloom_shader; + float font_texel_size; + TextBox textbox; FXFont font, fontlarge, fontmedium; @@ -165,7 +169,10 @@ class Gource : public SDLApp { Uint32 draw_scene_time; Uint32 logic_time; Uint32 trace_time; - Uint32 name_draw_time; + Uint32 text_time; + Uint32 text_update_time; + Uint32 text_vbo_commit_time; + Uint32 text_vbo_draw_time; bool track_users; diff --git a/src/vbo.cpp b/src/vbo.cpp deleted file mode 100644 index 0fcc43d3..00000000 --- a/src/vbo.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* - Copyright (C) 2011 Andrew Caudwell (acaudwell@gmail.com) - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version - 3 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "vbo.h" - -//qbuf2f - -qbuf2f::qbuf2f(int data_size) : data_size(data_size) { - bufferid = 0; - buffer_size = 0; - vertex_count = 0; - - data = new qbuf2f_vertex[data_size]; - - //fprintf(stderr, "size of qbuf2f_vertex = %d\n", sizeof(qbuf2f_vertex)); -} - -qbuf2f::~qbuf2f() { - if(bufferid !=0) glDeleteBuffers(1, &bufferid); - delete[] data; -} - -void qbuf2f::resize(int new_size) { - - qbuf2f_vertex* _data = data; - - data = new qbuf2f_vertex[new_size]; - - for(int i=0;i data_size) { - resize(vertex_count*2); - } - - data[i] = v1; - data[i+1] = v2; - data[i+2] = v3; - data[i+3] = v4; - - if(textures.empty() || textures.back().textureid != textureid) { - textures.push_back(qbuf2f_tex(i, textureid)); - } -} - -void qbuf2f::update() { - if(vertex_count==0) return; - - //note possibly better to have a queue and cycle them here - if(bufferid==0) { - glGenBuffers(1, &bufferid); - } - - glBindBuffer(GL_ARRAY_BUFFER, bufferid); - - //recreate buffer if less than the vertex_count - if(buffer_size < vertex_count) { - buffer_size = data_size; - glBufferData(GL_ARRAY_BUFFER, buffer_size*sizeof(qbuf2f_vertex), &(data[0].pos.x), GL_DYNAMIC_DRAW); - } else { - glBufferSubData(GL_ARRAY_BUFFER, 0, vertex_count*sizeof(qbuf2f_vertex), &(data[0].pos.x)); - } - - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void qbuf2f::draw() { - if(vertex_count==0 || bufferid==0) return; - - glBindBuffer(GL_ARRAY_BUFFER, bufferid); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - glVertexPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), 0); - glColorPointer(4, GL_FLOAT, sizeof(qbuf2f_vertex), (GLvoid*)8); // offset pos (2x4 bytes) - glTexCoordPointer(2, GL_FLOAT, sizeof(qbuf2f_vertex), (GLvoid*)24); // offset pos + colour (2x4 + 4x4 bytes) - - int last_index = vertex_count-1; - - for(std::vector::iterator it = textures.begin(); it != textures.end();) { - qbuf2f_tex* tex = &(*it); - - int end_index; - - it++; - - if(it == textures.end()) { - end_index = last_index; - } else { - end_index = (*it).start_index; - } - - glBindTexture(GL_TEXTURE_2D, tex->textureid); - glDrawArrays(GL_QUADS, tex->start_index, end_index - tex->start_index + 1); - - if(end_index==last_index) break; - } - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - - glBindBuffer(GL_ARRAY_BUFFER, 0); -} diff --git a/src/vbo.h b/src/vbo.h deleted file mode 100644 index 4d15cdc0..00000000 --- a/src/vbo.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (C) 2011 Andrew Caudwell (acaudwell@gmail.com) - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version - 3 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef GOURCE_VBO_H -#define GOURCE_VBO_H - -#include - -#include "core/display.h" -#include "core/vectors.h" -#include "core/logger.h" - -//note this should be 32 bytes (8x4 bytes) -class qbuf2f_vertex { -public: - qbuf2f_vertex() {}; - qbuf2f_vertex(const vec2f& pos, const vec4f& colour, const vec2f& texcoord) : pos(pos), colour(colour), texcoord(texcoord) {}; - - vec2f pos; - vec4f colour; - vec2f texcoord; -}; - -//maintain ranges corresponding to each texture -class qbuf2f_tex { -public: - qbuf2f_tex() {}; - qbuf2f_tex(int start_index, GLuint textureid) : start_index(start_index), textureid(textureid) {}; - int start_index; - GLuint textureid; -}; - -class qbuf2f { - - qbuf2f_vertex* data; - int data_size; - - std::vector textures; - - GLuint bufferid; - int buffer_size; - - int vertex_count; - - void resize(int new_size); -public: - qbuf2f(int data_size = 1); - ~qbuf2f(); - - void reset(); - - size_t vertices(); - size_t capacity(); - size_t texture_changes(); - - void add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour); - void add(GLuint textureid, const vec2f& pos, const vec2f& dims, const vec4f& colour, const vec4f& texcoord); - - void update(); - void draw(); -}; - -#endif From 82bbcf2d88e91c7c1c3b6227bc1c4fa2a65d3c52 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 25 Apr 2011 00:23:51 +1200 Subject: [PATCH 37/56] Removed unused class from codeblocks project file. --- gource.win32.cbp | 2 -- 1 file changed, 2 deletions(-) diff --git a/gource.win32.cbp b/gource.win32.cbp index 2a584c09..57d22f6c 100644 --- a/gource.win32.cbp +++ b/gource.win32.cbp @@ -86,8 +86,6 @@ - - From 68ac8acd620a1aad72752869178545d99ab61530 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 25 Apr 2011 09:40:51 +1200 Subject: [PATCH 38/56] Fixed bug where tree is out of alignment with object positions in windowed mode due to using the wrong display dimensions internally. --- ChangeLog | 2 ++ src/core | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 14f983ad..d1a06396 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,8 @@ * New font rendering library derived from FTGL (FTGL no longer required). * Single pass font/shadow rendering (with lots of help from Chris Forbes). * Added --no-vsync option. + * Fixed bug where tree is out of alignment with object positions in windowed + mode due to using the wrong display dimensions internally. 0.33: * Added --hide root option to not draw branches from the root directory. diff --git a/src/core b/src/core index a02b6b46..602ce805 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit a02b6b467ba04167c7ffc198820f46468d3ecc82 +Subproject commit 602ce8051b973780e0e16569aeee46e86d87f420 From bcca58a592eddae995a54f3523857e057ab630d4 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 25 Apr 2011 10:02:03 +1200 Subject: [PATCH 39/56] Fixed texture not being wiped correctly before due to wrong memset arguments. --- src/core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core b/src/core index 602ce805..d6eac341 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit 602ce8051b973780e0e16569aeee46e86d87f420 +Subproject commit d6eac341b938f76e301616060e3f29a163639c87 From 13fe01b25e09992be4b1f7b47026137ab69d3811 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 25 Apr 2011 10:13:14 +1200 Subject: [PATCH 40/56] Made shader class throw exceptions rather than exit itself. --- src/core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core b/src/core index d6eac341..76c705d0 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit d6eac341b938f76e301616060e3f29a163639c87 +Subproject commit 76c705d01e7d62cbf9143da8fdca3032b1fc8090 From 26a67edf3468f31ad4aa01e3be132525723b1b92 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 25 Apr 2011 22:18:29 +1200 Subject: [PATCH 41/56] Perform OpenGL 2.0 check in Gource constructor where it wont be overwritten. --- src/gource.cpp | 9 +++++++-- src/main.cpp | 3 --- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gource.cpp b/src/gource.cpp index a72be171..a3bb1e18 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -26,9 +26,11 @@ int gGourceUserInnerLoops = 0; Gource::Gource(FrameExporter* exporter) { this->logfile = gGourceSettings.path; - commitlog = 0; + //disable OpenGL 2.0 functions if not supported + if(!GLEW_VERSION_2_0) gGourceSettings.ffp = true; + if(!gGourceSettings.file_graphic) { gGourceSettings.file_graphic = texturemanager.grab("file.png"); } @@ -794,7 +796,7 @@ void Gource::keyPress(SDL_KeyboardEvent *e) { } if (e->keysym.sym == SDLK_p) { - if(GLEW_VERSION_2_0) { + if(GLEW_VERSION_2_0 && bloom_shader != 0) { gGourceSettings.ffp = !gGourceSettings.ffp; } } @@ -2466,6 +2468,7 @@ void Gource::draw(float t, float dt) { font.print(1,200,"Update Tree: %u ms", update_dir_tree_time); font.print(1,220,"Update VBOs: %u ms", update_vbos_time); font.print(1,240,"Projection: %u ms", screen_project_time); + font.print(1,260,"Draw Scene: %u ms", draw_scene_time); font.print(1,280," - Edges: %u ms", draw_edges_time); font.print(1,300," - Shadows: %u ms", draw_shadows_time); @@ -2481,8 +2484,10 @@ void Gource::draw(float t, float dt) { font.print(1,500,"Logic Time: %u ms", logic_time); font.print(1,520,"File Inner Loops: %d", gGourceFileInnerLoops); font.print(1,540,"User Inner Loops: %d", gGourceUserInnerLoops); + font.print(1,560,"Dir Inner Loops: %d (QTree items = %d, nodes = %d, max node depth = %d)", gGourceDirNodeInnerLoops, dirNodeTree->item_count, dirNodeTree->node_count, dirNodeTree->max_node_depth); + font.print(1,580,"Dir Bounds Ratio: %.2f, %.5f", dir_bounds.width() / dir_bounds.height(), rotation_remaining_angle); font.print(1,600,"String Hash Seed: %d", gStringHashSeed); diff --git a/src/main.cpp b/src/main.cpp index 4f571af8..b428b8c8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -121,9 +121,6 @@ int main(int argc, char *argv[]) { display.init("Gource", gGourceSettings.display_width, gGourceSettings.display_height, gGourceSettings.fullscreen); - //disable OpenGL 2.0 functions if not supported - if(!GLEW_VERSION_2_0) gGourceSettings.ffp = true; - } catch(SDLInitException& exception) { char errormsg[1024]; From 95912a17481bb2469693548a2dc03c455aa26813 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 25 Apr 2011 22:19:36 +1200 Subject: [PATCH 42/56] Use non ARB commands in shader class. --- src/core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core b/src/core index 76c705d0..e0a6abd0 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit 76c705d01e7d62cbf9143da8fdca3032b1fc8090 +Subproject commit e0a6abd0a200024fe362b2059901e842b18d0bf1 From f0d6056082839e8fa8fec4fcc6f547dd484a6dc3 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Mon, 25 Apr 2011 22:48:28 +1200 Subject: [PATCH 43/56] Fixed FTUnicodeStringItr iterator usage. --- src/core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core b/src/core index e0a6abd0..d715955e 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit e0a6abd0a200024fe362b2059901e842b18d0bf1 +Subproject commit d715955ec4bfdb04625fd8bc09e1f669ece2ddcb From 26b4a5161c9f64a112b62240ea1909e3550f7ebf Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Tue, 26 Apr 2011 23:25:58 +1200 Subject: [PATCH 44/56] Fixed unicode text rendering. --- src/core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core b/src/core index d715955e..4f860fe5 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit d715955ec4bfdb04625fd8bc09e1f669ece2ddcb +Subproject commit 4f860fe5608203937e0f1a1cca76fa57103c4d91 From df4abb7f8c1e6e2af6b8019b520fde27c0bbc402 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 27 Apr 2011 11:45:22 +1200 Subject: [PATCH 45/56] Removed old debian package code (not maintained from here). --- debian/changelog | 83 -------------------------------------------- debian/compat | 1 - debian/control | 20 ----------- debian/copyright | 41 ---------------------- debian/dirs | 1 - debian/docs | 2 -- debian/rules | 89 ------------------------------------------------ 7 files changed, 237 deletions(-) delete mode 100644 debian/changelog delete mode 100644 debian/compat delete mode 100644 debian/control delete mode 100644 debian/copyright delete mode 100644 debian/dirs delete mode 100644 debian/docs delete mode 100755 debian/rules diff --git a/debian/changelog b/debian/changelog deleted file mode 100644 index 161d6866..00000000 --- a/debian/changelog +++ /dev/null @@ -1,83 +0,0 @@ -gource (0.24) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Tue, 26 Jan 2010 14:39:18 +1300 - -gource (0.23) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Tue, 22 Dec 2009 12:18:06 +1300 - -gource (0.22) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Sun, 13 Dec 2009 08:19:51 +1300 - -gource (0.21) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Sat, 12 Dec 2009 16:07:50 +1300 - -gource (0.20) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Sat, 12 Dec 2009 13:43:10 +1300 - -gource (0.18) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Fri, 27 Nov 2009 16:35:57 +1300 - -gource (0.17) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Wed, 25 Nov 2009 15:08:02 +1300 - -gource (0.16) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Sat, 14 Nov 2009 15:44:13 +1300 - -gource (0.15) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Wed, 21 Oct 2009 10:27:13 +1300 - -gource (0.14) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Thu, 24 Sep 2009 21:42:00 +1200 - -gource (0.13) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Thu, 24 Sep 2009 18:05:46 +1200 - -gource (0.12) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Tue, 22 Sep 2009 13:24:37 +1200 - -gource (0.11) unstable; urgency=low - - * New upstream version. - - -- Andrew Caudwell Wed, 16 Sep 2009 18:17:50 +1200 - -gource (0.1) unstable; urgency=low - - * Initial release. - - -- Andrew Caudwell Wed, 16 Sep 2009 15:04:09 +1200 diff --git a/debian/compat b/debian/compat deleted file mode 100644 index 7f8f011e..00000000 --- a/debian/compat +++ /dev/null @@ -1 +0,0 @@ -7 diff --git a/debian/control b/debian/control deleted file mode 100644 index 6878960a..00000000 --- a/debian/control +++ /dev/null @@ -1,20 +0,0 @@ -Source: gource -Section: graphics -Priority: optional -Maintainer: Andrew Caudwell -Build-Depends: debhelper (>= 7), libsdl1.2-dev, libsdl-image1.2-dev, libpcre3-dev, libftgl-dev -Standards-Version: 3.8.0 -Homepage: http://gource.googlecode.com/ -Vcs-Browser: http://github.com/acaudwell/gource -Vcs-Git: git://github.com/acaudwell/gource.git - -Package: gource -Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends} -Description: graphical source control visualisation - OpenGL-based 3D visualisation tool for source control repositories. - . - The repository is displayed as a tree where the root of the repository is the - centre, directories are branches and files are leaves. Contributors to the - source code appear and disappear as they contribute to specific files and - directories. diff --git a/debian/copyright b/debian/copyright deleted file mode 100644 index cefe9a7e..00000000 --- a/debian/copyright +++ /dev/null @@ -1,41 +0,0 @@ -This package was debianized by Andrew Caudwell on -Wed, 16 Sep 2009 15:04:09 +1200. - -It was downloaded from http://gource.googlecode.com/ - -Upstream Author: Andrew Caudwell - -Copyright: 2009 Andrew Caudwell - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version - 3 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -You are free to distribute this software under the terms of the GNU General -Public License. On Debian systems, the complete text of the GNU General -Public License can be found in the /usr/share/common-licenses/GPL-3 file. - -The files in src/core are from the same author but licensed under the -revised BSD license. On Debian systems, the complete text of the BSD license -can be found in the /usr/share/common-licenses/BSD file. - -src/ppm.*: - Copyright (C) 2009 Johannes Schindelin (johannes.schindelin@gmx.de) - Licensed under the GNU General Public License, version 3 or later. - -UTF-8 CPP (src/core/utf8/): - Copyright 2006 Nemanja Trifunovic (BSD style license) - -data/fonts/FreeSans.ttf: - Copyright (C) 2002 Free Software Foundation. - Primoz Peterlin - Licensed under the GNU General Public License, version 2 or later. diff --git a/debian/dirs b/debian/dirs deleted file mode 100644 index e7724817..00000000 --- a/debian/dirs +++ /dev/null @@ -1 +0,0 @@ -usr/bin diff --git a/debian/docs b/debian/docs deleted file mode 100644 index 3a1b9684..00000000 --- a/debian/docs +++ /dev/null @@ -1,2 +0,0 @@ -THANKS -README diff --git a/debian/rules b/debian/rules deleted file mode 100755 index 48a72367..00000000 --- a/debian/rules +++ /dev/null @@ -1,89 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- -# Sample debian/rules that uses debhelper. -# This file was originally written by Joey Hess and Craig Small. -# As a special exception, when this file is copied by dh-make into a -# dh-make output file, you may use that output file without restriction. -# This special exception was added by Craig Small in version 0.37 of dh-make. - -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 - - -# These are used for cross-compiling and for saving the configure script -# from having to guess our platform (since we know it already) -DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) -DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) - - -CFLAGS = -Wall -g - -ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) - CFLAGS += -O0 -else - CFLAGS += -O2 -endif - -config.status: configure - dh_testdir - ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs" - - -build: build-stamp - -build-stamp: config.status - dh_testdir - - $(MAKE) - - touch $@ - -clean: - dh_testdir - dh_testroot - rm -f build-stamp - - [ ! -f Makefile ] || $(MAKE) distclean -ifneq "$(wildcard /usr/share/misc/config.sub)" "" - cp -f /usr/share/misc/config.sub config.sub -endif -ifneq "$(wildcard /usr/share/misc/config.guess)" "" - cp -f /usr/share/misc/config.guess config.guess -endif - - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_clean -k - dh_installdirs - - $(MAKE) install DESTDIR=$(CURDIR)/debian/gource - - -# Build architecture-independent files here. -binary-indep: build install -# We have nothing to do by default. - -# Build architecture-dependent files here. -binary-arch: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples - dh_installman - dh_link - dh_strip - dh_compress - dh_fixperms - dh_installdeb - dh_shlibdeps - dh_gencontrol - dh_md5sums - dh_builddeb - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install From e7a1eafeea8878d56a88dd054e628c6ab114adf1 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 27 Apr 2011 15:28:59 +1200 Subject: [PATCH 46/56] Reduce number of state changes drawing text on non GL2 cards. --- src/core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core b/src/core index 4f860fe5..ae76ad4c 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit 4f860fe5608203937e0f1a1cca76fa57103c4d91 +Subproject commit ae76ad4cd186a41915548e1465f153b30b09ecbd From 55693788a7ab2de95ded9100ec7ba9711bc23087 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 27 Apr 2011 15:33:57 +1200 Subject: [PATCH 47/56] Handle case where we didn't draw anything. --- src/core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core b/src/core index ae76ad4c..ec11e999 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit ae76ad4cd186a41915548e1465f153b30b09ecbd +Subproject commit ec11e99907398ae29baed892ce757982af6ca35c From 6a653428559b89789db306d5426af28c88ab8de8 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 27 Apr 2011 17:49:23 +1200 Subject: [PATCH 48/56] Note change to max-files default (now 0 - off). --- ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/ChangeLog b/ChangeLog index d1a06396..5d2b8a99 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,7 @@ * Added --no-vsync option. * Fixed bug where tree is out of alignment with object positions in windowed mode due to using the wrong display dimensions internally. + * Removed default max-files limit. 0.33: * Added --hide root option to not draw branches from the root directory. From ff549d9d02bda12874694c5f8d735111be5cc78e Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 27 Apr 2011 22:38:11 +1200 Subject: [PATCH 49/56] Made getName() pass a constant reference. --- src/pawn.cpp | 4 ---- src/pawn.h | 3 ++- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/pawn.cpp b/src/pawn.cpp index df7b7557..684dff5c 100644 --- a/src/pawn.cpp +++ b/src/pawn.cpp @@ -102,10 +102,6 @@ void Pawn::setSelected(bool selected) { this->selected = selected; } -std::string Pawn::getName() { - return name; -} - const vec3f& Pawn::getNameColour() const { return namecol; } diff --git a/src/pawn.h b/src/pawn.h index 15e42044..adbfbeca 100644 --- a/src/pawn.h +++ b/src/pawn.h @@ -82,7 +82,8 @@ class Pawn : public QuadItem { float getSize(); int getTagID(); - std::string getName(); + + const std::string& getName() const { return name; } virtual void setSelected(bool selected); bool isSelected() { return selected; }; From ef8a3f1f3c77c1a8773c306d6e711ca7aa70a8a0 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Wed, 27 Apr 2011 22:39:03 +1200 Subject: [PATCH 50/56] Don't add hidden files to VBO. --- src/dirnode.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/dirnode.cpp b/src/dirnode.cpp index dec5e8b8..6e37cfd2 100644 --- a/src/dirnode.cpp +++ b/src/dirnode.cpp @@ -1004,6 +1004,8 @@ void RDirNode::updateFilesVBO(quadbuf& buffer, float dt) const{ for(std::list::const_iterator it = files.begin(); it!=files.end(); it++) { RFile* f = *it; + if(f->isHidden()) continue; + vec3f col = f->getColour(); float alpha = f->getAlpha(); From 3f689daa26095079027be35915085f38d499b041 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Thu, 28 Apr 2011 13:33:51 +1200 Subject: [PATCH 51/56] Faster mouse trace code. Don't mouse over hidden files or users. --- src/gource.cpp | 42 ++++++++++++++++++++++-------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/gource.cpp b/src/gource.cpp index a3bb1e18..72c5667b 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -1686,40 +1686,42 @@ void Gource::logic(float t, float dt) { } void Gource::mousetrace(float dt) { - //fprintf(stderr, "start trace\n"); - //projected mouse pos - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - gluPerspective(camera.getFov(), (GLfloat)display.width/(GLfloat)display.height, camera.getZNear(), -camera.getPos().z); - camera.look(); - vec2f projected_mouse = display.unproject(mousepos).truncate(); - glPopMatrix(); + vec3f cam_pos = camera.getPos(); + vec2f projected_mouse = vec2f( -(mousepos.x * 2.0f - ((float)display.width)) / ((float)display.height), + (1.0f - (2.0f * mousepos.y) / ((float)display.height))) + * cam_pos.z; + projected_mouse.x += cam_pos.x; + projected_mouse.y += cam_pos.y; + //find user/file under mouse RFile* fileSelection = 0; RUser* userSelection = 0; - std::set userset; + if(!gGourceSettings.hide_users) { + + std::set userset; - userTree->getItemsAt(userset, projected_mouse); + userTree->getItemsAt(userset, projected_mouse); - for(std::set::iterator it = userset.begin(); it != userset.end(); it++) { - RUser* user = (RUser*) *it; - if(!user->isFading() && user->quadItemBounds.contains(projected_mouse)) { - userSelection = user; - break; + for(std::set::iterator it = userset.begin(); it != userset.end(); it++) { + RUser* user = (RUser*) *it; + if(!user->isFading() && user->quadItemBounds.contains(projected_mouse)) { + userSelection = user; + break; + } } + } - if(!userSelection) { + if(!userSelection && !gGourceSettings.hide_files) { std::set dirset; - + dirNodeTree->getItemsAt(dirset, projected_mouse); - + for(std::set::iterator it = dirset.begin(); it != dirset.end(); it++) { RDirNode* dir = (RDirNode*) *it; @@ -1735,7 +1737,7 @@ void Gource::mousetrace(float dt) { break; } } - } + } } // is over a file From d7353963442cb48dbfcee4bd6d3e89529cdd0df1 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Thu, 28 Apr 2011 13:35:22 +1200 Subject: [PATCH 52/56] Updated packaging scripts. --- dev/bin/build_tar.pl | 9 +++++---- dev/bin/build_win32.pl | 9 ++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/dev/bin/build_tar.pl b/dev/bin/build_tar.pl index ad9898b1..ea1af846 100755 --- a/dev/bin/build_tar.pl +++ b/dev/bin/build_tar.pl @@ -48,8 +48,7 @@ sub gource_version { qr{^/COPYING$}, qr{^/INSTALL$}, qr{^/README$}, - qr{/Makefile\.am$}, - qr{/Makefile\.in$}, + qr{/Makefile\.(?:am|in)$}, qr{^/aclocal\.m4$}, qr{^/m4/.+\.m4$}, qr{^/configure(?:\.ac)?$}, @@ -64,8 +63,10 @@ sub gource_version { qr{^/data/gource\.1$}, qr{^/data/gource\.style$}, qr{^/data/fonts/README$}, - qr{^/config\.guess$}, - qr{^/config\.sub$}, + qr{^/data/shaders/bloom\.(?:vert|frag)$}, + qr{^/data/shaders/shadow\.(?:vert|frag)$}, + qr{^/data/shaders/text\.(?:vert|frag)$}, + qr{^/config\.(?:guess|sub)$}, qr{^/install-sh$}, qr{^/missing$}, qr{^/depcomp$}, diff --git a/dev/bin/build_win32.pl b/dev/bin/build_win32.pl index 283a79c5..e59b7f94 100644 --- a/dev/bin/build_win32.pl +++ b/dev/bin/build_win32.pl @@ -39,6 +39,7 @@ sub dosify { doit("mkdir -p $WINBUILD"); doit("mkdir -p $WINBUILD/data/"); doit("mkdir -p $WINBUILD/data/fonts/"); +doit("mkdir -p $WINBUILD/data/shaders/"); doit("cp gource.exe $WINBUILD"); doit("cp data/beam.png $WINBUILD/data/"); @@ -49,6 +50,12 @@ sub dosify { doit("cp data/bloom_alpha.tga $WINBUILD/data/"); doit("cp data/gource.style $WINBUILD/data/"); doit("cp data/fonts/FreeSans.ttf $WINBUILD/data/fonts/"); +doit("cp data/shaders/bloom.frag $WINBUILD/data/shaders/"); +doit("cp data/shaders/bloom.vert $WINBUILD/data/shaders/"); +doit("cp data/shaders/shadow.frag $WINBUILD/data/shaders/"); +doit("cp data/shaders/shadow.vert $WINBUILD/data/shaders/"); +doit("cp data/shaders/text.frag $WINBUILD/data/shaders/"); +doit("cp data/shaders/text.vert $WINBUILD/data/shaders/"); dosify('README', "$WINBUILD/README.txt"); dosify('ChangeLog', "$WINBUILD/ChangeLog.txt"); @@ -60,11 +67,11 @@ sub dosify { doit("cp dev/win32/SDL.dll $WINBUILD"); doit("cp dev/win32/SDL_image.dll $WINBUILD"); doit("cp dev/win32/pcre3.dll $WINBUILD"); -doit("cp dev/win32/ftgl.dll $WINBUILD"); doit("cp dev/win32/jpeg.dll $WINBUILD"); doit("cp dev/win32/libpng12-0.dll $WINBUILD"); doit("cp dev/win32/zlib1.dll $WINBUILD"); doit("cp dev/win32/glew32.dll $WINBUILD"); +doit("cp dev/win32/freetype6.dll $WINBUILD"); chdir($WINBUILD); doit("zip -r gource-$VERSION.win32.zip *"); From dcdbd36479e9a54ba76aa8fe486ca78c397925b7 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Thu, 28 Apr 2011 13:36:17 +1200 Subject: [PATCH 53/56] Added -rc1 to version. --- ChangeLog | 2 +- configure.ac | 2 +- src/gource_settings.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5d2b8a99..00e08098 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,4 @@ -0.34: +0.34-rc1: * Now using VBOs and shaders for faster rendering when OpenGL 2.0 is available. * Eliminated bloom colour banding artifacts (requires OpenGL 2.0). * New font rendering library derived from FTGL (FTGL no longer required). diff --git a/configure.ac b/configure.ac index 9046e60d..a81fe3ec 100644 --- a/configure.ac +++ b/configure.ac @@ -3,7 +3,7 @@ AC_PREREQ(2.61) -AC_INIT(Gource, 0.34, [acaudwell@gmail.com]) +AC_INIT(Gource, 0.34-rc1, [acaudwell@gmail.com]) AC_CONFIG_SRCDIR([src/main.h]) AM_INIT_AUTOMAKE([dist-bzip2 foreign subdir-objects]) diff --git a/src/gource_settings.h b/src/gource_settings.h index 4d8772fd..44b1efc2 100644 --- a/src/gource_settings.h +++ b/src/gource_settings.h @@ -18,7 +18,7 @@ #ifndef GOURCE_SETTINGS_H #define GOURCE_SETTINGS_H -#define GOURCE_VERSION "0.34" +#define GOURCE_VERSION "0.34-rc1" #include From d8e7f0311db6d2d938b34235de0f5f4756d84e00 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Thu, 28 Apr 2011 22:40:07 +1200 Subject: [PATCH 54/56] Initialize VBO empty by default. --- src/bloom.cpp | 6 +++--- src/bloom.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/bloom.cpp b/src/bloom.cpp index a07c0402..20da3d5a 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -24,14 +24,14 @@ bloombuf::bloombuf(int data_size) : data_size(data_size) { buffer_size = 0; vertex_count = 0; - data = new bloom_vertex[data_size]; + data = data_size > 0 ? new bloom_vertex[data_size] : 0; //fprintf(stderr, "size of bloom_vertex = %d\n", sizeof(bloom_vertex)); } bloombuf::~bloombuf() { if(bufferid !=0) glDeleteBuffers(1, &bufferid); - delete[] data; + if(data != 0) delete[] data; } void bloombuf::resize(int new_size) { @@ -46,7 +46,7 @@ void bloombuf::resize(int new_size) { data_size = new_size; - delete[] _data; + if(_data != 0) delete[] _data; } void bloombuf::reset() { diff --git a/src/bloom.h b/src/bloom.h index 7f8ed7fd..611c0b46 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -48,7 +48,7 @@ class bloombuf { void resize(int new_size); public: - bloombuf(int data_size = 1); + bloombuf(int data_size = 0); ~bloombuf(); void reset(); From c50da5b206c1c7878ebe5edd756430c51b65a172 Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Thu, 28 Apr 2011 22:41:47 +1200 Subject: [PATCH 55/56] Draw user actions using VBOs. --- src/action.cpp | 43 +++++++++++++------------ src/action.h | 4 ++- src/core | 2 +- src/gource.cpp | 87 +++++++++++++++++++++++++++++++------------------- src/gource.h | 4 ++- src/user.cpp | 9 +++++- src/user.h | 2 ++ 7 files changed, 94 insertions(+), 57 deletions(-) diff --git a/src/action.cpp b/src/action.cpp index 199eb998..b1599d72 100644 --- a/src/action.cpp +++ b/src/action.cpp @@ -27,10 +27,6 @@ RAction::RAction(RUser* source, RFile* target, float addedtime) { rate = 0.5; } -bool RAction::isFinished() { - return (progress >= 1.0) ? true : false; -} - void RAction::logic(float dt) { if(progress >= 1.0) return; @@ -43,6 +39,29 @@ void RAction::logic(float dt) { progress = std::min(progress + action_rate * dt, 1.0f); } +void RAction::drawToVBO(quadbuf& buffer) const { + if(isFinished()) return; + + vec2f src = source->getPos(); + vec2f dest = target->getAbsolutePos(); + + vec2f offset = (dest - src).normal().perpendicular() * target->getSize() * 0.5; + vec2f offset_src = offset * 0.3f; + + float alpha = 1.0 - progress; + float alpha2 = alpha * 0.1; + + vec4f col1 = vec4f(colour, alpha); + vec4f col2 = vec4f(colour, alpha2); + + quadbuf_vertex v1(src - offset_src, col1, vec2f(0.0f, 0.0f)); + quadbuf_vertex v2(src + offset_src, col1, vec2f(0.0f, 1.0f)); + quadbuf_vertex v3(dest + offset, col2, vec2f(1.0f, 1.0f)); + quadbuf_vertex v4(dest - offset, col2, vec2f(1.0f, 0.0f)); + + buffer.add(0, v1, v2, v3, v4); +} + void RAction::draw(float dt) { if(isFinished()) return; @@ -71,22 +90,6 @@ void RAction::draw(float dt) { glTexCoord2f(1.0,0.0); glVertex2f(dest.x - offset.x, dest.y - offset.y); glEnd(); - -/* - glBegin(GL_QUADS); - glColor4fv(col2); - glTexCoord2f(0.0,0.0); - glVertex2f(src.x - offset_src.x, src.y - offset_src.y); - glTexCoord2f(1.0,0.0); - glVertex2f(src.x + offset_src.x, src.y + offset_src.y); - - glColor4fv(col1); - glTexCoord2f(0.0,0.0); - glVertex2f(dest.x + offset.x, dest.y + offset.y); - glTexCoord2f(1.0,0.0); - glVertex2f(dest.x - offset.x, dest.y - offset.y); - glEnd(); -*/ } CreateAction::CreateAction(RUser* source, RFile* target, float addedtime) : RAction(source, target, addedtime) { diff --git a/src/action.h b/src/action.h index 2d6cae64..f0a8846a 100644 --- a/src/action.h +++ b/src/action.h @@ -38,9 +38,11 @@ class RAction { RAction(RUser* source, RFile* target, float addedtime); - bool isFinished(); + inline bool isFinished() const { return (progress >= 1.0); }; virtual void logic(float dt); + + void drawToVBO(quadbuf& buffer) const ; void draw(float dt); }; diff --git a/src/core b/src/core index ec11e999..9900acfa 160000 --- a/src/core +++ b/src/core @@ -1 +1 @@ -Subproject commit ec11e99907398ae29baed892ce757982af6ca35c +Subproject commit 9900acfa6f5fe8b7d7da48e404305ff5c2558551 diff --git a/src/gource.cpp b/src/gource.cpp index 72c5667b..c262f1a0 100644 --- a/src/gource.cpp +++ b/src/gource.cpp @@ -642,7 +642,7 @@ void Gource::selectFile(RFile* file) { void Gource::selectNextUser() { - debugLog("selectNextUser()\n"); + //debugLog("selectNextUser()\n"); int currTagId = -1; @@ -949,7 +949,7 @@ void Gource::reset() { } void Gource::deleteFile(RFile* file) { - debugLog("removing file %s\n", file->fullpath.c_str()); + //debugLog("removing file %s\n", file->fullpath.c_str()); root->removeFile(file); @@ -972,7 +972,7 @@ void Gource::deleteFile(RFile* file) { tagfilemap.erase(file->getTagID()); file_key.dec(file); - debugLog("removed file %s\n", file->fullpath.c_str()); + //debugLog("removed file %s\n", file->fullpath.c_str()); delete file; } @@ -1016,7 +1016,7 @@ RUser* Gource::addUser(const std::string& username) { users[username] = user; tagusermap[tagid] = user; - debugLog("added user %s, tagid = %d\n", username.c_str(), tagid); + //debugLog("added user %s, tagid = %d\n", username.c_str(), tagid); return user; } @@ -1034,7 +1034,7 @@ void Gource::deleteUser(RUser* user) { users.erase(user->getName()); tagusermap.erase(user->getTagID()); - debugLog("deleted user %s, tagid = %d\n", user->getName().c_str(), user->getTagID()); + //debugLog("deleted user %s, tagid = %d\n", user->getName().c_str(), user->getTagID()); delete user; } @@ -1046,7 +1046,7 @@ bool Gource::canSeek() { } void Gource::seekTo(float percent) { - debugLog("seekTo(%.2f)\n", percent); + //debugLog("seekTo(%.2f)\n", percent); if(commitlog == 0 || !commitlog->isSeekable()) return; @@ -1689,19 +1689,19 @@ void Gource::mousetrace(float dt) { vec3f cam_pos = camera.getPos(); - vec2f projected_mouse = vec2f( -(mousepos.x * 2.0f - ((float)display.width)) / ((float)display.height), + vec2f projected_mouse = vec2f( -(mousepos.x * 2.0f - ((float)display.width)) / ((float)display.height), (1.0f - (2.0f * mousepos.y) / ((float)display.height))) * cam_pos.z; projected_mouse.x += cam_pos.x; projected_mouse.y += cam_pos.y; - + //find user/file under mouse RFile* fileSelection = 0; RUser* userSelection = 0; if(!gGourceSettings.hide_users) { - + std::set userset; userTree->getItemsAt(userset, projected_mouse); @@ -1719,9 +1719,9 @@ void Gource::mousetrace(float dt) { if(!userSelection && !gGourceSettings.hide_files) { std::set dirset; - + dirNodeTree->getItemsAt(dirset, projected_mouse); - + for(std::set::iterator it = dirset.begin(); it != dirset.end(); it++) { RDirNode* dir = (RDirNode*) *it; @@ -1737,7 +1737,7 @@ void Gource::mousetrace(float dt) { break; } } - } + } } // is over a file @@ -1934,15 +1934,22 @@ void Gource::drawScene(float dt) { void Gource::drawActions(float dt) { if(gGourceSettings.hide_users) return; - glBindTexture(GL_TEXTURE_2D, beamtex->textureid); glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); + glBindTexture(GL_TEXTURE_2D, beamtex->textureid); + glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - //draw actions - for(std::map::iterator it = users.begin(); it!=users.end(); it++) { - it->second->drawActions(dt); + if(!gGourceSettings.ffp) { + + action_vbo.draw(); + + } else { + + //draw actions + for(std::map::iterator it = users.begin(); it!=users.end(); it++) { + it->second->drawActions(dt); + } } } @@ -2033,26 +2040,39 @@ void Gource::screenshot() { void Gource::updateVBOs(float dt) { if(gGourceSettings.ffp) return; - user_vbo.reset(); + if(!gGourceSettings.hide_users) { - //use a separate vbo for each user texture - for(std::map::iterator it = users.begin(); it!=users.end(); it++) { - RUser* user = it->second; + user_vbo.reset(); + action_vbo.reset(); + + //use a separate vbo for each user texture + for(std::map::iterator it = users.begin(); it!=users.end(); it++) { + RUser* user = it->second; - float alpha = user->getAlpha(); - vec3f col = user->getColour(); + float alpha = user->getAlpha(); + vec3f col = user->getColour(); - user_vbo.add(user->graphic->textureid, user->getPos() - user->dims*0.5f, user->dims, vec4f(col.x, col.y, col.z, alpha)); + user_vbo.add(user->graphic->textureid, user->getPos() - user->dims*0.5f, user->dims, vec4f(col.x, col.y, col.z, alpha)); + + //draw actions + user->updateActionsVBO(action_vbo); + } + + user_vbo.update(); + action_vbo.update(); } - user_vbo.update(); - bloom_vbo.reset(); - root->updateBloomVBO(bloom_vbo, dt); - bloom_vbo.update(); + if(!gGourceSettings.hide_bloom) { + bloom_vbo.reset(); + root->updateBloomVBO(bloom_vbo, dt); + bloom_vbo.update(); + } - file_vbo.reset(); - root->updateFilesVBO(file_vbo, dt); - file_vbo.update(); + if(!gGourceSettings.hide_files) { + file_vbo.reset(); + root->updateFilesVBO(file_vbo, dt); + file_vbo.update(); + } } void Gource::drawFileShadows(float dt) { @@ -2497,7 +2517,8 @@ void Gource::draw(float t, float dt) { font.print(1,620,"Text VBO: %d/%d vertices, %d texture changes", fontmanager.font_vbo.vertices(), fontmanager.font_vbo.capacity(), fontmanager.font_vbo.texture_changes()); font.print(1,640,"File VBO: %d/%d vertices, %d texture changes", file_vbo.vertices(), file_vbo.capacity(), file_vbo.texture_changes()); font.print(1,660,"User VBO: %d/%d vertices, %d texture changes", user_vbo.vertices(), user_vbo.capacity(), user_vbo.texture_changes()); - font.print(1,680,"Bloom VBO: %d/%d vertices", bloom_vbo.vertices(), bloom_vbo.capacity()); + font.print(1,680,"Action VBO: %d/%d vertices", action_vbo.vertices(), action_vbo.capacity()); + font.print(1,700,"Bloom VBO: %d/%d vertices", bloom_vbo.vertices(), bloom_vbo.capacity()); } if(selectedUser != 0) { @@ -2505,7 +2526,7 @@ void Gource::draw(float t, float dt) { } if(selectedFile != 0) { - font.print(1,700,"%s: %d files (%d visible)", selectedFile->getDir()->getPath().c_str(), + font.print(1,720,"%s: %d files (%d visible)", selectedFile->getDir()->getPath().c_str(), selectedFile->getDir()->fileCount(), selectedFile->getDir()->visibleFileCount()); } } diff --git a/src/gource.h b/src/gource.h index 719a6173..63b7aa62 100644 --- a/src/gource.h +++ b/src/gource.h @@ -112,8 +112,10 @@ class Gource : public SDLApp { RUser* hoverUser; RUser* selectedUser; - quadbuf user_vbo; quadbuf file_vbo; + quadbuf user_vbo; + quadbuf action_vbo; + bloombuf bloom_vbo; GLuint selectionDepth; diff --git a/src/user.cpp b/src/user.cpp index c0309a22..2b5c37e1 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -401,8 +401,15 @@ void RUser::drawNameText(float alpha) { } } +void RUser::updateActionsVBO(quadbuf& buffer) { + + for(std::list::iterator it = activeActions.begin(); it != activeActions.end(); it++) { + RAction* action = *it; + action->drawToVBO(buffer); + } +} + void RUser::drawActions(float dt) { - if(gGourceSettings.hide_users) return; for(std::list::iterator it = activeActions.begin(); it != activeActions.end(); it++) { RAction* action = *it; diff --git a/src/user.h b/src/user.h index 6a030ac9..324dabbc 100644 --- a/src/user.h +++ b/src/user.h @@ -88,6 +88,8 @@ class RUser : public Pawn { void logic(float t, float dt); + void updateActionsVBO(quadbuf& buffer); + void drawActions(float dt); void draw(float dt); }; From 7d19f700a0728e1aead5c973f90ca0794dddeb4a Mon Sep 17 00:00:00 2001 From: Andrew Caudwell Date: Sun, 1 May 2011 16:32:48 +1200 Subject: [PATCH 56/56] Fixed padding size of bloom_vertex. --- src/bloom.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bloom.h b/src/bloom.h index 611c0b46..43aa3fc3 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -28,12 +28,13 @@ class bloom_vertex { public: bloom_vertex() {}; - bloom_vertex(const vec2f& pos, const vec4f& colour, const vec4f& texcoord) : pos(pos), colour(colour), texcoord(texcoord) {}; + bloom_vertex(const vec2f& pos, const vec4f& colour, const vec4f& texcoord) : + pos(pos), colour(colour), texcoord(texcoord) {}; vec2f pos; vec4f colour; vec4f texcoord; - char padding[22]; + char padding[24]; }; class bloombuf {