Jump to content

  • Log In with Google      Sign In   
  • Create Account

Brother Bob

Member Since 26 Nov 2001
Offline Last Active Today, 09:51 AM

#5207818 Low Level Memory Management C++

Posted by Brother Bob on 31 January 2015 - 03:35 AM

If you're asking how to recreate std::vector with separate memory allocations and object constructions, then you'll do the following:

  1. Allocate memory with the operator new() or malloc() function.
  2. Construct individual objects with placement new.
  3. Destruct objects by calling their destructor.
  4. Release memory with the operator delete() or free() function.

If you're specifically asking about point 3, then destroying an object is as simple as calling the ~T() member function on it (replace T with the class name, or template type parameter you use). Look here for some example memory management: clicky.

#5206767 Why is this taboo?

Posted by Brother Bob on 26 January 2015 - 03:33 PM

This was a double post with replies. The two threads have been merged.

#5206684 Constructor gotcha's?

Posted by Brother Bob on 26 January 2015 - 06:01 AM

One thing that tripped me up in the early days of learning c++ was calling virtual functions in constructors.

Do not call virtual functions in constructors, as they will not work properly!



Depends on what you mean by "not work properly" though. Calling virtual functions in constructors is well defined and well behaved by the language, but may not be obvious or work how you initially expect it work. I suspect that the problem was a lack of understanding of what will happen, rather than it "not working properly".

#5206361 Constructor gotcha's?

Posted by Brother Bob on 24 January 2015 - 04:15 AM


the order of initialization in constructor initializer lists is the *member declaration order*, not the order in which members are lexically arranged in the initialization list.


so if i have member variables:

int a;

int b;


and in my constructor i say:




it will process a=b*2 first?


don't recall if i heard of that one before or not. then again, i first learned c++ syntax when it first came out, and haven't really used it much since. so maybe its just yet another thing that i've already forgotten.


No, that is assignment but Josh is talking about initialization and the initializer list.

struct foo {
    foo() : b(5), a(b*2) {}
    int a;
    int b;

In this class, a is declared before b and therefore a is also initialized with twice the value of b, before b has been initializer. Code in the constructor is executed top-down, but that code is executed after the initializer list.

#5206171 Textured cube with glDrawElements

Posted by Brother Bob on 23 January 2015 - 04:47 AM

A cube with more attributes than just position ultimately has 24 unique vertices. If you build the sides of the cube using triangles, you have to generate a total of 32 vertices. However, the shared edge of the two triangles per side also share unique vertices so out of the 32 vertices you need to generate there are only 24 unique ones.


So you can still gain something by using indexed primitives because some of the triangles share unique vertices. On the other hand, a cube is close to the worst case for indexed primitives because it only has sharp edges with discontinuous vertex attributes that prevents vertex sharing. Compare to smooth surfaces, such as a sphere, where attributes typically flow smoothly across the surface most of the time.

#5205632 Serving large files over TCP

Posted by Brother Bob on 20 January 2015 - 03:17 PM

Unless my understanding of TCP is completely wrong, if I send a huge chunk, TCP can split them up and piece them back together on their end, and that's TCP's job.  But in this case, I purposely split the packets myself, so as far as I understand, TCP sees the packets independently.  Am I correct/wrong on this?


If you mean that a single call to send() [or equivalent function] may split your buffer and transport it with multiple IP packets and the receiver is required to assemble it back in order, then you are correct. If you also mean that two buffers sent by two different calls to send() may arrive out of order at the receiver end, then you are mistaken.


Your data may arrive out of order on the IP level since individual IP packets are independent in that sense, but the two buffers will ultimately be delivered to you in order on the TCP layer. Your mistake is that you see TCP as a message or packet-based protocol. It is not, it is a stream-based protocol; you send a stream of data and you receive a stream of data. Any splitting into packets or individual messages happens only on the IP level when the TCP stream is transported by IP packets. This is all managed by the TCP layer for you: stream in, stream out.


Forget about packages when talking about TCP. There is only a stream you put data into and/or get data from. A single call to send() may be split into multiple IP packages, or multiple calls to send() may be combined into a single IP packet, when the data is actually transmitted. Likewise, there is no requirement to match a call to send() by a call to recv(). You can receive your data in any buffers you like, independent on what and how much you send. This is an entirely different concept from UDP.


You may, for other reasons, have to implement a separate messaging protocol on top of TCP, but that's a different issue. Your issue was effectively about different send() calls arriving out of order from the TCP layer, and that's not correct.

#5204351 What is the gradient symbol for

Posted by Brother Bob on 14 January 2015 - 06:49 PM



Where did the extra factor of `rlen' come from?

Its the distance vector between two particle positions and rlen is the magnitude of this vector.


What I mean is that
final float term = 45.0f / ((float)Math.PI * (float)Math.pow(kH, 6) * rlen);
should probably be
final float term = 45.0f / ((float)Math.PI * (float)Math.pow(kH, 6));
Unless you can explain where "the extra factor of rlen" came from.


Observe the different symbols in his equations: the argument to the function is r (bold and upface) which is presumably a vector, whereas the equations contain r (normal weight and slanted) that is used in a scalar context. His code maps to his equation under the assumption that r=|r|.

#5203875 How can sample rate be 44000Hz?

Posted by Brother Bob on 13 January 2015 - 04:28 AM


. And depending on the "width" of the middle region, you must keep a margin between the highest frequencies in your original signal and half the sampling rate (essentially what Aressera already said).


How is that "margin" between the highest frequencies and half the sampling rate measured? One is a continuous signal(?) while the other is a digital signal(samples per second.)


If you have a sampling rate of 44 kHz, the Nyquist frequency is at 22 kHz. Since your anti-aliasing and reconstruction filter has a transition band (the middle part mentioned earlier) between the pass band and the rejection band, the effective cutoff frequency of the filter has to be lower. Say that you have a cutoff at 18 kHz and a rejection band starting at 22 kHz (a filter passing from 0 to 18 kHz, blocking from 22 and up in this case since you want to eliminate everything above 22 kHz); that means the middle part gives you a margin of 22-18=4 kHz. Your analog signals are therefore effectively limited to 18 kHz, despite having a Nyquist frequency of 22 kHz.

#5203778 Should I use the gradient to get the Normal of a Sin wave?

Posted by Brother Bob on 12 January 2015 - 04:02 PM

Look here for the equation of a surface normal. The normal at a point (x,z) of the function f(x,z) is (fx(x,z), -1, fz(x,z)) given your notation. Note that your fy should be -1 according to the link, not 0 as in your example.

#5199949 intersection of two lines

Posted by Brother Bob on 25 December 2014 - 04:46 AM

Consider all points on a lined defined as s+t*v, where s is a single point on the line, v is the direction of the line, and t is a parameter that produces points along the line. In your code, where you have two points, you can just define s=p0 and v=p1-p0. If t=0, then p=p0; if t=1, then p=p1, and so on.


You want to find the intersection point between two line segments, which is a point common to two line segments. Thus, you have the two lines

  • s0 + t0 * v0, where s0 = p0 and v0 = p1-p0 from your code, and
  • s1 + t1 * v1, where s0 = p2 and v0 = p3-p2 from your code.

Find a common point along the two lines by solving for t0 and/or t1 from

  • ​s0 + t0 * v0 = s1 + t1 * v1

This is a normal linear equation system, so rearrange and reformulate the problem on matrix form.

  • t0 * v0 - t1 * v= s1 - s0
  • [v0, -v1] * [t0, t1]T = s1 - s0

Note that I assume column vectors here, and that the V-matrix is a 2-by-2 matrix where the two vectors v0 and v1 are the columns of the V-matrix. Finally, solve for t0 and t1.

  • [t0, t1]T = [v0, -v1]-1 * (s1 - s0)

When you have t0 and t1, just plug any of them back into the corresponding lines to find the intersection point. Both of them will produce the same point.


Now that we have the theory, you can identify the maths with the code:

  • My direction vectors v0 and v1 corresponds to your s1 and s2.
  • My (s1 - s0) corresponds to your u, although there is a sign difference here that will be cancelled later, so no worries.
  • Your ip is the determinant of my [v0, -v1]-1.
  • Your s and t are the x and y coordinates of the multiplication of my V-matrix and (s1 - s0).
  • Your i being assigned inside the if-statements is when you plug one of the t's into its corresponding line equation to produce the intersection point.
  • The first if-statement checks if the resulting points are outside of the two line segments bounded by the two points. That happens when t<0 or when t>1. Remove that if-statement if you want the lines to extend indefinitely.

The theory above to find the intersection point is equally valid for 3-dimensional lines as well. It will, however, find the points along the two lines that are closest to each other, and you need to find some other method to invert the V-matrix since it's no longer square; for example, the pseudo-inverse.

#5199239 I need help with some maths

Posted by Brother Bob on 20 December 2014 - 06:18 AM

Start by assuming that the circle is centered at the origin; thus, translate everything by -p, and your click point becomes t-p. Now you can just normalize the point t-p so that it ends up on the edge of the unit circle, and then multiply by the desired radius for your desired circle. Finally, translate that point back by p to negate the initial translation by -p.


In short, using vector maths:

x = p + r*normalize(t-p);

#5198734 constructor for class that contains another class and constructor C++

Posted by Brother Bob on 17 December 2014 - 03:16 AM

As BitMaster said, the base class is responsible for initializing itself. You don't initialize the base class from derived classes, but instead you delegate the work to it from the derived class' constructor.

template <class _cType> class  t4dpoint : public t3dpoint<_cType> {
    _cType w;
    // the t3dpoint base class is automatically default initialized if not specified, and then initialize our own member
    t4dpoint<_cType>() : w(1.0)
    { }
    // initialize the t3dpoint base class and then initialize our own member
    t4dpoint<_cType>(_cType x, _cType y, _cType z, _cType w) : t3dpoint(x,y,z), w(w)
    { }

#5198611 declare custom types of ints?

Posted by Brother Bob on 16 December 2014 - 03:13 PM


Use enums, or wrap the integers in different classes.

If we are talking about C++ it should be enum class instead of the standard enum as the latter one is basically just an int with a fancy name.

Note that enum class was introduced in C++11 so it might not be available for your compiler.


Depends on what you want to do with the enum, what extra protection you want, and what possibilities you are willing to drop. The OP asked for a way to prevent passing one kind of value to a parameter or a different kind (passing an animation as a model, or vice versa) and you don't need the new strong enums for that.

#5198597 declare custom types of ints?

Posted by Brother Bob on 16 December 2014 - 02:35 PM

Use enums, or wrap the integers in different classes.

#5196219 My "Hello World" OpenGL application doesn't display anything

Posted by Brother Bob on 04 December 2014 - 04:17 AM

Your perspective matrix has a znear of 1. Your modelview is identity. Your points are at z=0. They are outside of your view area. Try placing your points at z>=1.

The symptom is correct, but it has to be z <= -1, because the Z-axis is pointing out from the screen towards you. It may be confusing, but the clip plane values are the distances along the negative Z-axis, which mean that a near clip plane value of 1 places the near clip plane value at Z = -1.