Jump to content

  • Log In with Google      Sign In   
  • Create Account

Brother Bob

Member Since 26 Nov 2001
Offline Last Active Today, 05:59 PM

#5290111 how good is rand() ?

Posted by Brother Bob on 04 May 2016 - 01:05 PM

 

 

"The rand function returns a pseudorandom integer in the range 0 to RAND_MAX (32767). "  so it returns 0 thru 32766, but not 32767, right?

 

Correct.  In modern math notation this type of function works with [0,x)  meaning it includes zero but stops just short of x.  This is also common in many other systems.  Graphics, for example, typically draw segments in the [A,B) form, starting exactly at A and ending the instant before B.

 

 

I tried this in VS2015 and it does return RAND_MAX.. is it not supposed to?

#include <iostream>
int main() {
	for(int i = 0; i < 200000; ++i) {
		int r = rand();
		if(r == RAND_MAX)
			std::cout << "MAX\n";
		else if(r == (RAND_MAX - 1))
			std::cout << "ALMOST\n";
		else if(r == 0)
			std::cout << "ZERO\n";
	}
}

The range for both rand() and the <random> library (at least the uniform integer distributions when comparing with rand) are inclusive at both ends. The range is therefore [0, RAND_MAX], not [0, RAND_MAX). This is different from, for example, iterator ranges in the standard library which are half-open.




#5286832 Template-related compiler bug or... ?

Posted by Brother Bob on 14 April 2016 - 03:25 AM

 

There's a few other ways to write that function, but that's probably the least crazy.

 

A third and not-so-crazy option is to make the type of the second parameter a non-deduced type.

#include <type_traits>
 
Foo<T>& operator*=(Foo<T>& left, typename std::identity<T>::type right) {
    ...
}

Passing the type through a dependent type like that excludes that T from the deduction process. The parameter instead participates in conversion once the actual type has been resolved.




#5272606 Opengl culling confusion

Posted by Brother Bob on 25 January 2016 - 01:32 PM

If you have decided that a front face has its vertices in counter clockwise order, then you will see a counter clockwise order when you look at the front face of the polygon and a clockwise order if you look at the back face. OpenGL performs backface culling by looking at the screen space winding order. If, after projection onto the screen, the face has a counter clockwise order, it has to be the front side. Similarly, if the order is clockwise, it has to be the back face and it will be culled. There is no way to view a triangle from the other side and not change the apparent winding order.




#5261132 Can someone please explain + example of 'ownership'

Posted by Brother Bob on 09 November 2015 - 08:53 AM

As I said, it was just a simple explanation to show the concept of ownership, I didn't go in details.

There are two types of ownership being answers here. You're describing ownership as in a parent/child relationship in an object hierarchy while BitMaster and Olof are describing ownership as in object lifetime management.

 

Object lifetime management has nothing to do with parent/child relationships but about when and how dynamic resources are released to avoid, for example, memory leaks when you forget to free on an allocated object.




#5257430 How do I solve?

Posted by Brother Bob on 15 October 2015 - 11:47 PM

You have already asked this question: clicky.


#5253251 C++ Question About Objects

Posted by Brother Bob on 21 September 2015 - 12:24 AM

If all you are actually concerned about is the syntax and the separate call to load, then just do the loading in the constructor instead of in a separate load function.

Level level("level1");



#5250627 Non-linear zoom for 2D

Posted by Brother Bob on 04 September 2015 - 05:10 PM

Do linear interpolation in logarithmic domain instead.

  1. Calculate the logarithm of your start and end values, whatever they represent. Any log-base is fine.
  2. Linearly interpolate between the two logarithms as usual.
  3. For every step in your animation/interpolation, calculate the inverse of the chosen logarithm to determine the instantaneous linear scale.

The natural log() and exp() functions work just fine for step 1 and 3, respectively.




#5249762 acos ( ) in Java has gone bezierk

Posted by Brother Bob on 30 August 2015 - 02:20 PM

It's 1.325 radians, which is the same as 75.930 degrees.




#5242690 Technical audio questions?

Posted by Brother Bob on 25 July 2015 - 04:41 PM

For technical questions, there are a few suitable places for different kinds of audio related questions. You have Maths and Physics for mathematical and theoretical questions, APIs and Tools if you have problems with specific audio APIs, and then there's always the last resort for anything related to programming: General Programming. Pick a place that seems suitable; we'll move it if it's entirely out of place.




#5242402 Vector cast

Posted by Brother Bob on 24 July 2015 - 08:26 AM

Assuming you're using C++, have the Add function take a const reference instead so you can pass temporary objects to it and your two last examples will be fine. Temporary objects cannot bind to non-const references.




#5241077 Texturing occasionally off by a pixel

Posted by Brother Bob on 17 July 2015 - 10:56 AM

 

...but I just want to open the possibility that if you have to correct this at several places around your code base, then maybe it wasn't designed with integer coordinates in mind to begin with? smile.png

 
Ironically, it was/is, but I switched to floats (~8 months ago) because that was what OpenGL expects, and so motion can be "smoother" for moving objects.
pos += (velocity * deltaTime);
If 'pos' is integer, then I was thinking it might give more jittery movement. In situations like movement, wouldn't it be better to accumulate the decimal portion over time?

 

Keeping floating point positions, velocities, accelerations, time and such is fine. Fractional motion can be achieved with integers as well, look for example at how Bresenham's line algorithm works: it can move fractional distances along the Y-axis as you sweep along the X-axis where the X distance is greater than the Y-distance all with integer pixel locations.

 

 

 

Joke aside; only the output from the vertex shader has to produce integer coordinates. Any intermediate calculation can, technically, be done in full decimal arithmetics, but just make sure you round the result in one place: the output from the vertex shader.


That's a thought - so you're saying I might be able to just get away with:
gl_Position = (ModelViewProjectionMatrix * vec4(round(vPosition), 0.0f, 1.0f));

 

If anything it has to be round(ModelViewProjectionMatrix * vec4(...)); Remember, the final coordinates has to be integers. This is probably the simplest solution, along with full floating point values for intermediate calculations. You are still at the mercy of rounding errors, but at this point the errors are on the order of floating point epsilon rather than half a pixel.




#5241020 Texturing occasionally off by a pixel

Posted by Brother Bob on 17 July 2015 - 03:53 AM

Thanks guys, that helps a bundle.
 
I've temporarily enabled Linear filtering, for testing - previously I had it on Nearest, because Linear isn't what I want for 2D artwork (it's also Nearest for mipmaps, because I intend to store additional unrelated spritesheets in the mipmap levels).

If done correctly, it shouldn't matter which filter mode you use. From a debugging perspective, using full linear interpolation both along the texel axes and the mipmap axis is arguably better, since everything should be perfectly aligned anyway and any misalignment will be visible as a result. Of course, use nearest filtering for production when you're certain everything is correct.

 

So I'm "fixing" the problem currently by using std::round() on the values before I send them to the videocard - both on the camera position and on the polygon positions.
 
Visual it works, but software design-wise is this the right way to go about fixing it? With the camera it feels right, but with the polygons - either I'm doing it low-level and rounding everything right before it's uploaded to a VBO, which feels wasteful and hackish, or I'm doing it higher level and doing it when positioning polygons - which means there'll eventually be twenty or thirty places in my code where I need to make sure to round values, and if I miss one, it can visually give bad results - though this does seem the more correct way.

Correct design or not, absolutely no fractional coordinates can come out from the vertex shader in the end. It is of course hard to comment on your, for me unknown, design, but I just want to open the possibility that if you have to correct this at several places around your code base, then maybe it wasn't designed with integer coordinates in mind to begin with? smile.png

 

Joke aside; only the output from the vertex shader has to produce integer coordinates. Any intermediate calculation can, technically, be done in full decimal arithmetics, but just make sure you round the result in one place: the output from the vertex shader. This may even give you better result as you're not rounding decimal values all the time. If you do rotations and other transformations and keep rounding intermediate results, you will keep adding rounding errors up to 0.5 pixels at every stage. That could add up to several pixels worth of error, just not tiny normal floating point rounding errors.

 

Keeping coordinates internally in decimal precision and just round for the purpose of rendering is totally fine. Just keep in mind that you are then still subject to rounding errors. For example, if you need to keep two independent sprites just next to each other on a pixel-basis, the two objects may be transformed slightly different and causing them to sometimes be rendered with a pixel between them or with a pixel overlapping. That may not be an issue in a situation like in your images above.




#5240632 Texturing occasionally off by a pixel

Posted by Brother Bob on 15 July 2015 - 06:10 PM

[Edit 2:] I've confirmed that the camera position's fractional value is basically setting the fractional value of the object's position, which sets the default fractional value of the corner quads being rendered. So basically, any object that I've placed but haven't yet moved the camera on, will be something like QuadPos = xx.125, CameraPos = yy.125.

 

Speculation: So when subtracting the camera pos from the quad's pos (which I'm assuming the MVP matrix basically does), will result in the quad having an xx.000 fractional value after the vertex shader, which might get rounded the wrong when rasterizing in the fragment shader?

You edited this as posted by reply, and I just wanted to address this particular bit since it could be the source of misunderstanding.

 

The rasterinzation rules in OpenGL essentially state that a pixel is rasterized if its center is located within the boundary of the triangle. A pixel's coordinate in "pixel space" range from (x,y) at its lower-left corner (or upper-right, or upper-left, or whatever depending on the orientation of the projection matrix) to (x+1, y+1) at its upper-right corner, and the pixel's center is located at (x+.5, y+.5).

 

So if you have a quad corner located at (x+.5, y+.5), you are at the mercy of rounding errors whether that pixel is located just inside or just outside the quad. An integer coordinate (x,y) on the other hand has a good margin; it has to be off by 0.5 units before reaching a pixel center where the rasterization happens. The quad at a corner (x,y) covers the corner pixel to 100%, and the neighbouring three pixels to 0%, so there's absolutely no ambiguity which pixels are rendered.




#5240630 Texturing occasionally off by a pixel

Posted by Brother Bob on 15 July 2015 - 06:00 PM

If you want pixel perfect rendering, you're going to have to precisely control the coordinates to ensure that they are always integer coordinates after any applied transformation. That means you cannot have fractional translations in your ModelViewProjectionMatrix matrix either. After rotating the objects, round the resulting values to snap them to precise pixel locations. All points you show have fractional coordinates and that won't play well with pixel perfect rendering.

 

I don't have a direct answer to the problem itself, but I recommend that you start from scratch to get familiar with how pixel perfect rendering works in OpenGL and work from there to isolate your current problem. For visual debugging purpose, turn on linear texture filtering to ensure that texels are perfectly aligned with the pixels (the texture will look sharp when aligned, and blurry when not) and enable polygon smoothing (glEnable(GL_POLYGON_SMOOTH), although not sure if that's still in the core profile contexts beyond OpenGL 3.0)  and alpha blending to ensure that your quads are rendered on exact pixel boundaries as well. Take a screenshot and inspect the result close-up on a pixel basis to ensure that the texture is rendered sharp, there's no leakege from pixel smoothing around the border of your quad, and that there are exactly the correct number of pixels being rendered.

 

In the end, the rasterization rules are well defined and quite easy to set up. But fractional coordinates are your enemy here, especially a 0.5 pixel offset.




#5240606 Texturing occasionally off by a pixel

Posted by Brother Bob on 15 July 2015 - 03:54 PM

For filled primitives, such as triangles and other surfaces you put your texture on, you don't offset your coordinates at all. The offset should only be applied to line and point primitives. Assuming, of course, that you apply the usual projection matrix such as glOrtho(0, width, 0, height) or some similar variant thereof.






PARTNERS