Jump to content

  • Log In with Google      Sign In   
  • Create Account


SuperVGA

Member Since 10 Sep 2008
Offline Last Active Apr 15 2014 09:25 AM
-----

Topics I've Started

Fastest map-like collection for <GUID, BaseClass*> lookup

27 February 2014 - 05:58 AM

I currently have 

std::map<const guid, CommWrapper >* comm_table;

 

where guid

 struct guid
 {
  unsigned char d[16];
  
  // Less-comparer for std::map with GUID keys
  bool operator<(const guid& rhs) const
  {
   for(unsigned c = 0; 16 != c; ++c)
   {
    if(d[c] == rhs.d[c]) {
  continue;
    }
    return d[c] < rhs.d[c];
   }
   return false;
  } 
 };

 

But it seems to be way slower than the approach i took before, where i just based the (gu)id on the index the pointer had in a std::vector.

for instance truck would be in comm_table[5], and thus its id would be 5.

 

But I kinda like the idea of using some big, fancy guids. It's just really slow for autonomous inter-instance communication,
and I'm wondering if I'm doing it right. Perhaps there's no reason to go this way at all.

 

Or am i just using a wrong collection?


Geometry Clipmap Question

23 November 2013 - 01:22 PM

Hi Guys! Been a while! My project sees constant changes, and it really helps that I learned to stick to stuff.

That said, I often see myself rewriting a module or replacing it with others. Feels clean.

 

I've tried to grasp the principle of Geoclipmapping. Following various articles, but mostly the one from GPU gems 2 (see, I even used the colours :P) I get that all the vertices should move relative to the camera movement,

and thus represent static points in the world. While I'm mostly successful at this, the "rings" that represent the overlap between the detail levels

cause me some headaches. (They're the ones on the picture which fades to a darker colour on the inside)

Attached File  geoclipmaps.png   104.22KB   6 downloads

 

I've done it so that these rings will snap to the same points where the outer vertices on the ring within are. That means that these in-between rings

scale a bit, and that the quads in the corners have issues snapping to the inside.

 

The individual rings are each offset with eye.xy modulo size (where size is the size of an individual quad in that ring) - when I look at these isolated,
they move seamlessly, so I think I got those right. But I can't wrap my head around how the ones on the inside can stay without being distorted a bit. And how to do the corners at all.

 

Any feedback or hints highly appreciated! :D

Have a good weekend,


Vsync with GLee

01 September 2013 - 07:51 AM

Hi Guys,

 

I've again stuck with something I shouldn't and spent way too much time staring myself blind on something what I thought was simple. I got it to work some time ago, but lost my code for it. I even did a small app to demonstrate my issue.

 

I can't for the world make my windowed gl context start up with vsync enabled (The vsync state is decided by the driver) - once I enter glutGameMode and go back to windowed mode, vsync is now enabled. I have vsync set as the first thing after these two very important lines:

// Initialize glut
glutInit(&argc, argv);
// Initialize glee
GLeeInit();

Followed by:

glutInitWindowSize(gl_current_width, gl_current_height);
glut_window_hWnd = glutCreateWindow(window_title.c_str());
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE | GLUT_ALPHA | GLUT_STENCIL);

// Set swap interval
#ifdef _WIN32
 char *extensions = (char*)glGetString( GL_EXTENSIONS );
 if( strstr( extensions, "WGL_EXT_swap_control\0" ) == 0 )
 {
  return; // Error: WGL_EXT_swap_control extension not supported on your computer.");
 }
 else
 {
  wglSwapIntervalEXT = (GLEEPFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress( "wglSwapIntervalEXT\0" );
  if( wglSwapIntervalEXT )
  {
   wglSwapIntervalEXT(1);
  }
 }
#endif
#ifdef __linux__
 glXSwapIntervalSGI(1);    // Nix
#endif

I can't make it work without changing display mode. Should I call wglSwapIntervalEXT elsewhere?

I think GLee supplies wglSwapIntervalEXT already, and I've noticed that it ends up targeting the same procedure, but I just wanted to make sure.

Calling wglSwapIntervalEXT(1) should've been sufficient.

 

I've tested on 4 cards; an nVidia GTX 275, an AMD Radeon 6500M, an nVidia Quadro 3000M and Intel HD 4500.

All exhibit the same behaviour (also, all run Win7 64bit. It might have something to do with it, although I can't see why)

 

 

EDIT: Why, thank you for removing half of my post! smile.png

EDIT 2: Sanitized code, removed religious glError checks...


Making glOrtho work (or writing an intuitive projection matrix)

14 July 2013 - 02:04 PM

Hi guys,

 

I've messed around with my fixed (only the width and heights) orthographic projection in relation to guis.

Now I'd like to put my neat, flexible Projection class to use and create a Camera that will render me an overview map.

 

The view vectors are potentially much different than the 2d stuff, as it doesn't need to picture my level from straight above, necessarily.

 

Unlike what many people say on the webs, it can be necessary to provide negative near and far clipping values to glOrtho, to get the wanted result. This is AFAIK because of some old ortho stuff from the early days of OpenGl.
(See http://mlucassmith.tumblr.com/post/10869898438/why-i-hate-glortho-and-all-its-offspring for more on glOrtho and why it doesn't behave like glFrustrum.)

 

What I'm getting if I just mess around with the values a bit (in case I want the ortho camera oriented directly downwards) is this:

 

Attached File  argh.png   60.29KB   7 downloads

 

 

(The floor slabs are gray on the top colored on the underside)

I have depth buffering enabled, but it looks like (perhaps because of the inverted clipping plane values (near  -100, far: 100) the depth values are swapped) If it's not this, then it's the "up" vector not working as I intend it to, and it mirrors the projection somehow.

I get the correct projection by swapping near and far, and swapping the target and the eye vectors. (aside from being an orthographic projection, it's similar to me seeing the toy car in my kid's room when i see from the toy car, vieweing from me (near, 32.0f) to it (far, 0.1f)) in the direction of where i stand.

 

I read up on projection matrices (just how to set them up), and I messed with the values to initially copy the behavior of glOrtho:

    GLfloat tx = -((ortho_right+ortho_left) / (ortho_right-ortho_left));
    GLfloat ty = -((ortho_top+ortho_bottom) / (ortho_top-ortho_bottom));
    GLfloat tz = -((clip_far+clip_near) / (clip_far-clip_near));
    GLfloat cx =  (2.0f / (ortho_right - ortho_left));
    GLfloat cy =  (2.0f / (ortho_top   - ortho_bottom));
    GLfloat cz = -(2.0f / (clip_far    - clip_near));
    
    GLfloat mtx[16] ={  cx, 0.0f, 0.0f,   0.0f,
                      0.0f,   cy, 0.0f,   0.0f,
                      0.0f, 0.0f,   cz,   0.0f,
                      tx, ty, tz, 1.0f };
    glMultMatrixf(mtx);

I'd like to fix this so I end up with a more intuitive "myOrtho()" (meaning the clip_near resembles the direct linear distance ahead of the camera, in the view direction in which the near clipping plane exists, and the clip_far resembles the one of the far clipping plane (both being positive values)).

 

Unfortunately, my general projection matrix math is very rusty, and I barely managed to copy the khronos man page description for glOrtho.

Have you guys tried this before? The alternative would be to negate view directions and the near and far clipping values on every frame drawn into an orthographic projection. And I'm reluctant to do that as it seems a bit hackish. Shouldn't the projection just "work"?


Static Initialization and Ctors

26 June 2013 - 11:26 AM

Hi guys,

 

Have been messing with this for a few days now, and now, even though I'm stripping all the code I can, it doesn't seem to change behaviour.

I'm talking about a Segfault that occurs when i try to insert a pair (or anything, really) into a static map, in my constructor.

 

SceneElement.h :

#ifndef SCENEELEMENT_H
#define SCENEELEMENT_H
 
#include <string>
#include <vector>
#include <map>
 
namespace world
{
    class SceneElement
    {
        protected:
            const std::string name;
const unsigned ssid;
            static unsigned element_ssid_tail;
            
        public:
            static std::map< unsigned, SceneElement* > element_ssid_table;
            static std::map< std::string, SceneElement* > element_name_table;
    
            SceneElement(const std::string &_name = "Unnamed element", const bool _visible = true);
            SceneElement(const SceneElement& orig);
            virtual ~SceneElement();
    };
}
 
#endif /* SCENEELEMENT_H */

 

SceneElement.cpp :

#include "SceneElement.h"
#include <iostream>
 
namespace world
{
    unsigned SceneElement::element_ssid_tail = 1; // 0 is an invalid subsystem id
    std::map< unsigned, SceneElement* > SceneElement::element_ssid_table = std::map< unsigned, SceneElement* >();
    std::map< std::string, SceneElement* > SceneElement::element_name_table = std::map< std::string, SceneElement* >();
    
    SceneElement :: SceneElement(const std::string &_name, const bool _visible) :
            ssid(SceneElement::element_ssid_tail),
            name(_name)
    {
        ++SceneElement::element_ssid_tail;
        std::cout << this << std::endl; // Outputs reasonable address
        std::cout << &SceneElement::element_ssid_table << std::endl; // Outputs reasonable address
        std::cout << &SceneElement::element_name_table << std::endl; // Outputs reasonable address (located a few bytes after the previous map)
        std::cout << SceneElement::element_ssid_table.size() << std::endl; // Outputs 0
        std::cout << SceneElement::element_ssid_tail << std::endl; // Outputs 2
        
         // Setting the maps here makes everything work. I'd guess that the static map hasn't been initialized properly....
        //SceneElement::element_ssid_table = std::map< unsigned, SceneElement* >();
        //SceneElement::element_name_table = std::map< std::string, SceneElement* >();
        // Crashes!
        SceneElement::element_ssid_table.insert( std::pair< unsigned, SceneElement* >(ssid, this) );
        SceneElement::element_name_table.insert( std::pair< std::string, SceneElement* >(name, this) );
    }
    
    SceneElement :: SceneElement(const SceneElement& orig) :
            ssid(SceneElement::element_ssid_tail),
            name(orig.name)
    {
        ++SceneElement::element_ssid_tail;
        // Crashes!
        SceneElement::element_ssid_table.insert( std::pair< unsigned, SceneElement* >(ssid, this) );
        SceneElement::element_name_table.insert( std::pair< std::string, SceneElement* >(name, this) );
    }
    
    SceneElement::~SceneElement()
    {
        SceneElement::element_ssid_table[ssid] = NULL;
        SceneElement::element_name_table[name] = NULL;
    }
}

 

The punchline here is, that I've got a GuiElement class that behaves that exact same way, but never crashes.

And I'm not fond of undefined behaviour, so if I'm just being lucky with GuiElement, then I'd rather change it to a "safe" implementation.

 

I felt confident that everything static, that had been included, compiled and linked would be initialized first thing,

and it looks like the maps have actually been created. Would you give me a hand?

Tips on preventing segfaults are also welcome. I usually create on construction or on the stack, avoid "new" where possible,

and deal in refs instead of pointers, when possible. But this apparently, I have not been able to escape.


PARTNERS