Jump to content

  • Log In with Google      Sign In   
  • Create Account

Brother Bob

Member Since 26 Nov 2001
Offline Last Active Yesterday, 05:07 PM

#5149611 gluLookAt() and matrix stack operations deprecated?

Posted by Brother Bob on 26 April 2014 - 05:25 AM

All matrix operations and everything that came with it, such as the stack, are all gone. There's not even anything called a model view matrix in OpenGL anymore. You have to manage all matrices yourself now and load them to your shaders as necessary.




#5149031 Array Location? (C Programming)

Posted by Brother Bob on 23 April 2014 - 01:55 PM

Now is an excellent time to use the debugger to step through your program line by line.

 

First iteration searches for the letter 'a' in the string "abcd" and advances the string to "bcd". The second iteration searches for the letter 'a' in "bcd" and finds nothing, so the string is reset to "abcd", and proceeds to find 'b' and the string is advanced to "bcd". The third iteration searches for the letter 'a' and finds nothing, so the string is reset to "abcd", and proceeds to find 'b'... and so on.




#5148700 How to get float value that is less then 1 without the higher part

Posted by Brother Bob on 22 April 2014 - 06:39 AM

Look at it from a different angle instead: how do you obtain the integer part so that you can subtract it from the original number? You can cast the float to an integer, or using the floor function, for example.




#5145760 How to make semi-transparent simple shadows not stack?

Posted by Brother Bob on 09 April 2014 - 02:21 PM

Use the stencil buffer to only render shadows where no shadow has yet been drawn. Set up the stencil buffer to clear to zero, and set up the stencil test to only render a shadow if the stencil value is zero and to increase the stencil value when a shadow is rendered.

 

A second shadow will not be rendered on top of an existing shadow, since the stencil value will not be zero for the overlapping areas. The final result is that the shadow effect for any pixel under any of the multiple shadows will be rendered exactly once.




#5144127 Oh no, not this topic again: LH vs. RH.

Posted by Brother Bob on 03 April 2014 - 10:02 AM


I think the key part of what Buckeye said is " as commonly implemented". but no, you should not need to swap matrix multiplication order for handedness, only for majorness, as Mona2000 mentioned. The only real place that handedness matters is in the projection transform, or how our mapping of the 3D vector space is converted to 2D.

 

Not even majorness matters. What determines whether the vector goes on the left or the right hand side of the matrix depends on whether you use row or column vectors and nothing else. A column vector cannot go anywhere but on the right hand side, and a row vector cannot go anywhere but on the left hand side of a multiplication with a matrix, and majorness or handedness are irrelevant.




#5143474 Math notation for binomial square

Posted by Brother Bob on 31 March 2014 - 08:36 AM

What's wrong with (a+b)2, isn't that the square of the sum of a and b?




#5142131 MSVS's preprocessor vs gcc's preprocessor

Posted by Brother Bob on 25 March 2014 - 04:55 PM

The gl.h file depends on other files, for example on Windows you need to include windows.h before gl.h. On the other hand, glut.h handles that already. If you include glut.h, then don't include gl.h or glu.h, because it's doing that already as well as preparing the correct symbols for gl.h and glu.h to work.




#5141665 C++ Template Class -Creating a static method overload in derived class hides...

Posted by Brother Bob on 24 March 2014 - 04:14 AM

Hi I have a some code in my engine similar to following snippet - 

...

So basically what I am trying to do here is there's a static method in template base class and I am trying to create an overload with string parameter. I want to use both of them.

But the problem is if I create the static method overload in derived class it hides the base class version. I am not sure if I am missing something here or this is the intended behavior ????

Right now as a work around I am using BaseClass<DerivedClass,InitDataType_t>::GetInstance(initData); inside main.

 

Also If I don't create any overload in derived class then DerivedClass::GetInstance(initData); works fine without any warning or error. Which I think how it should be.

 

Creating a static method overload in derived class hides the base class method, which I feel is a bug or maybe I am missing something here? So can anyone please provide an insight to whats really going on here ?

The behavior is correct and indended. You're not overloading here, but overriding. Overriding a base class function in a derived class hides the base class definition unless explicitly qualified with the base class name as you discovered. This applies to non-static member functions as well, not just static ones.

 

You can "unhide" the base class symbols in the derived class with the using statement. Something like this should work:

class DerivedClass : public BaseClass< DerivedClass, InitDataType_t >
{
using BaseClass::GetInstance;
public:
static T1* GetInstance(const cstring& somestring);
}



#5141401 Encryption with time played

Posted by Brother Bob on 23 March 2014 - 04:48 AM

Use a proper and tested encryption mechanism instead of inventing your own. A real encryption mechanism is safe because it is safe by design and not because the hacker can't figure out which methods you use.

 

Besides, time is not a very secret either; the hacker also knows the time. But there's also the problem of keeping the clients in sync. Just using the time down to the minute does save you the problem of keeping them in sync or handling timing issues. For example, the transit time of a package over a network is not zero, so how would you for example handle time stamps which ticks to the next minute after the package is sent but before it is received at the other end?




#5141218 C++ c

Posted by Brother Bob on 22 March 2014 - 08:24 AM

 

Make elements a T * instead of unsigned char *. Saves you all that pointer casting and sizeof-calls in your pointer arithmetics.

I did that at first, but I adjusted my code according to fastcall22's second response using placement new.

 

 fastcall22 told you to use placement new, and I suggested that you change the pointer type from unsigned char to your template type T to get rid of the manual pointer arithmetics. Those are not mutually exclusive; you want placement new and a proper pointer type.
 
Instead of:
 

unsigned char *elements = new unsigned char[count*sizeof(T)];
...
new (elements + i * sizeof(T)) T(*((T*)(oldElements + i * sizeof(T))))

you do something like:

T *elements = operator new(count*sizeof(T));
...
new (elements + i) T(oldElements[i]);

 

Don't relocate objects with the C memory functions. You need to properly copy construct and release objects, or move the objects with the move constructor if you want to take advantage of the move-mechanics in C++11. For trivial objects, this is equivalent as a memory move, but for objects with side effects when constructing/destructing/moving objects, this is highly important to get right. Also ensure that you don't assign to the new memory; you must construct the object in the new memory since otherwise you'll assign something to an non-constructed object.

I think I am currently not relocating objects with C memory functions. I use placement new to copy construct the old objects. But I just noticed that I forgot to call the destructors of the released objects when relocating.

 

I apologize, I misread your code; the memcpy function was for the integer pointers and not the actual object pointers. Without looking into the exact details, it does indeed look like the correct approach at least.
 

It turns out that I don't need this class. If anything I will make a version only for trivial objects. But I learned plenty about placement new, smart pointers, initialization lists and the rule of three/five, so thanks! I appreciate all the responses.smile.png

It was kind of what I figured with my first question. Even if it doesn't apply in this particular case, knowing about object lifetimes and such is a great experience anyway.




#5141132 C++ c

Posted by Brother Bob on 21 March 2014 - 05:24 PM

You mentioned that you load everything into a vertex buffer. Are you loading non-trivial objects that has to ensure proper constructor and destructor calls into vertex buffers, or are you just over-engineering a container of primitive types?

 

In any case, I've got some general comments on your memory management itself. May or may not be relevant to your particular case considering my question above.

  1. Make elements a T * instead of unsigned char *. Saves you all that pointer casting and sizeof-calls in your pointer arithmetics.
  2. Allocate the memory directly with the operator new() function instead of going through the new [] operator. Then you also have to release the memory with the operator delete() function instead of using the delete [] operator. Thus: elements = operator new(elementCapacity*sizeof(T)) and operator delete(elements).
  3. Don't relocate objects with the C memory functions. You need to properly copy construct and release objects, or move the objects with the move constructor if you want to take advantage of the move-mechanics in C++11. For trivial objects, this is equivalent as a memory move, but for objects with side effects when constructing/destructing/moving objects, this is highly important to get right. Also ensure that you don't assign to the new memory; you must construct the object in the new memory since otherwise you'll assign something to an non-constructed object.

Point 1 and 2 are about allocating the raw memory buffer. Point 3 is about how you manage objects manually in your own memory buffers and can be really tricky to get right if you don't understand object life times and if, how and when objects are constructed or nor.




#5139298 random generators

Posted by Brother Bob on 15 March 2014 - 02:13 PM

You need an engine for every independent and deterministic stream of random numbers.

 

Say, for example, that you want enemies to appear randomly during the game but in a predictable way so that you can save the game and replay or continue to play with the same stream or enemies (not only for replay, but also to stop the player from reloading because the stream of enemies was not in favor of the player; reloading with a predictable state ensures the same stream of enemies in the future as well, so no use reloading to get an easier game).

 

You also want your power-ups to appear randomly, but for the same replay and reload purposes as with enemies, you want to ensure a predictable stream of random numbers. Let's say a new power-up is generated every time a power-up is picked up (the game contains, say, three of them at any time).

 

With a common engine in this case, enemies are generated based on if and when a power-up is picked up, and that breaks replayability and predictability. You need to decide if things such as replayability and predictability are important.




#5139247 Need help: a vector of different extended classes

Posted by Brother Bob on 15 March 2014 - 10:08 AM

Look up slicing; your vector stores Entity objects by value, so only the Entity part of your EntityArrow ends up in the vector. Your vectors has to store pointers and you need to allocate your Entity objects dynamically instead.




#5139214 glOrtho - a beginner question

Posted by Brother Bob on 15 March 2014 - 06:22 AM

gluLookAt does nothing more than apply an equivalent rotation and translation. If you can describe the orientation and location of the plane by some parameters to gluLookAt, then you're set.

 

For example, if the center of the plane is located at (px, py, pz) with a normal pointing towards the direction (nx, ny, nz), then you should be able to locate the view point with something like gluLookAt(px, py, pz, px+nx, py+ny, pz+nz, ux, uy, uz) where the vector (ux,uy,uz) orients the plane (you may want to orient the up vector along, for example, the point X3-X1).

 

The orthographic projection is then set up with width and height corresponding to the distance between X1 and X2, and X1 and X3, respectively. Make the projection symmetric if the point (px, py, pz) is at the center of the plane.

 

You can also replace the call to gluLookAt with the equivalent rotation and translation yourself if you know your linear algebra. The vector X=(X2-X1), Y=(X3-X1) and Z=X cross Y, or some variant thereof, defines the coordinate system as seen from the projection plane. A translation to shift by (px, py, pz) the coordinate system is also necessary.




#5138137 Function Pointers in Structs

Posted by Brother Bob on 11 March 2014 - 10:49 AM

Some obvious drawback are:

  1. The object has to physically contain a pointer for every "member function" you want to use.
  2. The syntax is worse in the sense that you have to provide the object twice: once to obtain the function pointer and once to pass it to the function. In C++, for example, the hidden this-parameter is implied from the syntax you use to call the member function on and you only mention the object once.
  3. No way to force the two objects to be the same. Nothing stops you from doing test1.get_a(&test2).

Don't fool yourself that it's more OO because you have an object on the left hand side of a period and a function on the right hand side; OO is just as fine with the object as a parameter instead. It's about how you design your objects and functions to operate on them, not about what syntax you use to call a function.

 

One benefit of storing a function pointer is to get runtime-dynamic behavior. For example, as Olof said, it is a similar approach to how virtual functions are typically implemented. For compile-time behavior, there's no reason to store the function pointers.






PARTNERS