Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [C++] al_put_pixel() problem? Bitmap not rendering correctly.

This thread is locked; no one can reply to it. rss feed Print
[C++] al_put_pixel() problem? Bitmap not rendering correctly.
Skyrunner
Member #14,886
January 2013

The attached file shows the output. It is constant. It doesn't change at all, always rendering the exact pixel-for-pixel output each time it is run with different parameters.

al_set_target_bitmap(bitmap);
  al_lock_bitmap(bitmap, al_get_bitmap_format(bitmap), ALLEGRO_LOCK_READWRITE);

  for (int ycounter = 0; ycounter < w; ycounter++)
    for (int xcounter = 0; xcounter < h; xcounter++)
      al_put_pixel(xcounter, ycounter, al_map_rgb( 0, 0, (int)topograph.at(xcounter, ycounter)));

  al_unlock_bitmap(bitmap);

////
al_set_target_backbuffer(root);
al_clear_to_color(al_map_rgb(0,0,0));
al_draw_bitmap(thisRegion->bitmap, 0, 0, 0);
al_flip_display();

The topograph.at() is a std::vector. The contents of the vector vary, from the scaled output of rand(), to a libnoise Perlin noise module, to full zeros. All values are [0,255]. Yet it always outputs those bars. Am I doing anything obviously wrong? If any more information is needed, I'm happy to provide. :D

someone972
Member #7,719
August 2006
avatar

topograph.at(xcounter, ycounter)
This looks fishy; std::vector::at only takes one argument, so it shouldn't even compile like this. The loop looks fine other than that, so if you fix getting the topograph value and it still looks the same, I would suspect that the way topograph is being filled with values is at fault.

______________________________________
As long as it remains classified how long it took me to make I'll be deemed a computer game genius. - William Labbett
Theory is when you know something, but it doesn't work. Practice is when something works, but you don't know why. Programmers combine theory and practice: Nothing works and they don't know why. -Unknown
I have recklessly set in motion a chain of events with the potential to so-drastically change the path of my life that I can only find it to be beautifully frightening.

Jeff Bernard
Member #6,698
December 2005
avatar

This looks fishy; std::vector::at only takes one argument, so it shouldn't even compile like this.

(Assuming topograph is populated correctly.) Probably the comma operator is being used, which doesn't make sense, the compiler should have thrown an error. So, what's actually happening is, xcounter just keeps getting re-used and ycounter is ignored.:

for (int ycounter = 0; ycounter < w; ycounter++)
    for (int xcounter = 0; xcounter < h; xcounter++)
      al_put_pixel(xcounter, ycounter, al_map_rgb( 0, 0, (int)topograph.at(xcounter)));

What you probably wanted:

al_put_pixel(xcounter, ycounter, al_map_rgb( 0, 0, (int)topograph.at(xcounter+ycounter*h)));

Is there a reason you compare ycounter against w (width) and xcounter against h (height)? Normally those two are the other way around.

(Assuming otherwise.) Finally, are you calling srand? Otherwise, there's a reason why you always get the same output.

--
I thought I was wrong once, but I was mistaken.

Skyrunner
Member #14,886
January 2013

Okay, for starters, I should apologize sincerely and hope I don't get sent to programmer hell D:

I posted incorrect information: topograph is not a std::vector, but rather a class that encapsulates a vector. The vector is used to store a heightmap, and access is done by multiplying y by h and adding x.

I conducted a few tests, and I've determined that the issue is most likely in that very function.

When the entire populating stage of topograph was skipped, and rand()%256 inserted in its place, the screen showed random noise as it should.
When topograph was populated via Perlin, scaled, and displayed using the code posted in the OP, it showed the bars.
When topograph was populated via rand(), scaled, and displayed, it showed the bars.
When topograph was populated via rand()%256, not scaled, and displayed, it showed bars.

(int)topograph.at(xcounter, ycounter) is the culprit, or perhaps scale() is, too.

Sorry for causing consternation over the wrong information >_<

Arthur Kalliokoski
Second in Command
February 2005
avatar

Those "bars" are exactly what you'd get if you put X directly into the blue component of the pixels (wraparound at 256 starts a new "bar").

“Throughout history, poverty is the normal condition of man. Advances which permit this norm to be exceeded — here and there, now and then — are the work of an extremely small minority, frequently despised, often condemned, and almost always opposed by all right-thinking people. Whenever this tiny minority is kept from creating, or (as sometimes happens) is driven out of a society, the people then slip back into abject poverty. This is known as "bad luck.”

― Robert A. Heinlein

Skyrunner
Member #14,886
January 2013

The exact problem was this:

topograph.at() returns double*.
A vector normally has memory addresses that are sequential.
I didn't dereference the at()'s result, so the address value was plugged in and it wrapped around in bars like that xD
Oh, the stupid mistakes.

Go to: