Delphi/C++Builder TBitmap: How to determinine scanline order? - gdi+

Delphi's TBitmap type is basically a wrapper over a GDI BITMAP and PALETTE, and can support both top-down and bottom-up scanline ordering.
I have a TBitmap which I need to convert to GDI+ Bitmap, in order to rotate and composite it.
My bitmap is 32-bit ARGB, which windows supports, but VCL doesn't natively 'understand'.
TBitmap *bmp;
...
When I use the following constructor, the alpha channel doesn't work for compositing, but otherwise everything works.
Gdiplus::Bitmap b(bmp->Handle, NULL);
So, I tried the constructor below, which takes size, pixel data and format params.
Gdiplus::Bitmap b(bmp->Width, bmp->Height, bmp->Width *4, PixelFormat32bppARGB,
(BYTE*) bmp->ScanLine[bmp->Height-1]); // bottom up storage
This gets the alpha, but the bitmap is upside down, so I tried this
Gdiplus::Bitmap b(bmp->Width, bmp->Height, - bmp->Width *4, PixelFormat32bppARGB,
(BYTE*) bmp->ScanLine[0]); // negative stride for bottom up bitmaps?!
Now, that works, but of course I'm hard-coded into bottom-up bitmaps. However, I can't find a way of determining if the TBitmap is top-down or bottom-up. They're stored internally with negative height but the height value is massaged before it's passed back to user code.
How can I find out the scanline ordering, or - better yet - is there another way of creating a GDIPlus bitmap from a TBitmap?

The TBitmap::ScanLine property accounts for top-down and bottom-up. For a bottom-up bitmap, ScanLine[0] returns the last row, and ScanLine[Height-1] returns the first row, of the raw pixel data. For a top-down bitmap, ScanLine[0] returns the first row, and ScanLine[Height-1] returns the last row, of the raw pixel data.
To determine if a TBitmap is bottom-up or top-down, you have to manually retreive its BITMAPINFOHEADER structure, which TBitmap does not natively expose. You can use the Win32 API GetObject() function to retreive a DIBSECTION structure, which has a BITMAPINFOHEADER member.

Related

QOpenGLFramebufferObject toImage efficiency

The toImage() method seems to be very slow in terms of real-time rendering. I render to the frame buffer using OpenGL but I need to then fetch the colour data back effeciently, is there a better way to do this than with a Qt fbo's toImage method? I do want to return a QImage.
Note: Using the toImage() function I get ~ 10fps when my target is at least 30fps. The buffer needs to hold RGBA data on a texture that is 1200*674 (so 1200*674*4 bytes are fetched)

how to make sprites stick together in game maker?

I don't know how to get sprites to stick to each other so they become one big object instead of tiny little pieces, for example:
attaching a thruster to a box, then the thruster stays in that spot while pushing the box, and also is there a certain term for what I'm talking about?
You could also attach all parts to one of the objects, it would sort of look like:
//Main object
x = 5;
y = 20;
//other object step event
x = obj_main.x + <any value to put it where you want>;
y = obj_main.y + <any value to put it where you want>;
//This will force the parts to follow the main object.
`
`
You can use an array, defined in the 'main' object to use a sort of grid to define where each piece is and then either draw each individual sprite, based on its position in the array, originating from the 'main' object's coordinates. Or just create an individual instance of an object if you would like to have additional functionality by trading off some performance.
For more information on arrays and how to position sprites and objects based on set coordinates, check out the GML documentation provided below:
Arrays:
https://docs.yoyogames.com/source/dadiospice/002_reference/001_gml%20language%20overview/401_06_arrays.html
lengthdir:
https://docs.yoyogames.com/source/dadiospice/002_reference/maths/real%20valued%20functions/lengthdir_x.html
what I did was make the object disabled, so when I press left and right it doesn't go anywhere, only the other piece would move, but when it came into contact it allowed the other piece to move along with it, and set its speed to the corresponding objects speed, in simpler term, when I collide with it, it turns the movement on and goes in the same direction as the current object in the same speed, making it look like its sticking

How to free resources of QString when use it inside std::vector

I have a structure "rs" for every record of my dataset.
All records are in a vector "r".
My record count is in “rc”.
....
struct rs{
uint ip_i;//index
QString ip_addr;//ip address
};
std::vector <rs> r;//rows ordered by key
int rc;//row count
....
I would like to control this memory usage.
That's why I don't want to use r.insert and r.erase.
When I need to insert a record, I will:
Increase size of r by r.resize(..);r.shrink_to_fit() (if needed).
Shift elements of r to the right (if needed) by std::rotate.
Put new values: r[i].ip_i=...;r[i].ip_addr=...
When I need to delete a record, I will:
Shift elements of r to the left (if needed) by std::rotate.
For example, std::rotate(r.begin()+i,r.begin()+i+1,r.begin()+rc);.
Free resources of r[rc].ip_addr.
How to free resouces of QString r[rc].ip_addr?
I've tried to do r[i].ip_addr.~QString() and catched an runtime error.
Make r.resize() (if needed).
I don't want to loose memory because of Qstring copies stayed after rows deleting.
How can I control them?
Thanks.
QString handles all memory control for you. Just treat it as a regular object and you'll be fine. std::vector is OO-aware, so it will call destructors when freeing elements.
The only thing you should not do is use low-level memory manipulation routines like memcpy or memset. std::vector operations are safe.
If you really want to free a string for a record that is within [0..size-1] range (that is, you do not actually decrease size with resize() after moving elements), then calling r[i].ip_addr.clear() would suffice. Or better yet, introduce the clear() method in your structure that will call ip_addr.clear() (in case you add more fields that need to be cleared). But you can only call it on a valid record, of course, not one beyond your actual vector size (no matter what the underlying capacity is, it's just an implementation detail).
On a side note, it probably makes sense to use QList instead since you're using Qt anyway, unless you have specific reasons to use std::vector. As far as memory control goes, QList offers reserve method which allows you reserve exactly as many elements as you need. Inserting then would look like
list.reserve(list.size() + 1);
list.insert(i, r);

Drawing with OpenGL in OOP

I try to code an OpenGL project with Qt (v5.1.1) on OS X 10.9, in the manner of the modern pipeline implementation. The program is supposed to be a multi-agent based system or particle system. However I lack in understanding how to draw something out of another class.
In cinder there were some simple drawThisAndThat() command you could call. I read the 6th edition of the 'OpenGL Superbible'. From this and several tutorials all examples seem to cover just programs where all modifications are made out of the class that initializes OpenGL.
I would like to instantiate some objects moving on a grid and draw pixel to display their position. I know I have to call void glVertexAttrib4fv(GLuint index, const GLfloat * vi); but this is not sufficient.
Do I need to call glEnableVertexAttribArray(1); and glDrawArrays(GL_POINTS, 0, 3); as well and what else?
Am I right, to instantiate the class controlling the particles after instantiating OpenGL and bevor the main loop?
How do I manage that the particle draws himself while erasing the position he was drawn bevor?
The program is based on this code.
To answer your questions completely I would have to write a wall of text, I will try to only point out the most important aspects. I hope this will help you enough to use your knowledge and probably further reading to get it to work.
all modifications are made out of the class that initializes OpenGL
You can encapsulate update(time) and draw() methods for your Objects which you then call in your main loop.
Do I need to call glEnableVertexAttribArray(1); and glDrawArrays(GL_POINTS, 0, 3); as well and what else?
I would put all particles into one vertex array to avoid rebinding of different vertex arrays after each particle. Then you would have to use glBindVertexArray(vaid); and glDrawArrays(GL_POINTS, 0, vertexCount); in your draw() call. Be careful with vertexCount, it's not the number of floats (as your question implies) but the number of vertices, which should be 1 in your example or the number of particles in my suggested approach (If I'm correct in assuming that the 3 stands for "x, y, and z of my vertex").
And since you only have particles glDrawElements(...); would probably already fit your needs.
Am I right, to instantiate the class controlling the particles after instantiating OpenGL and bevor the main loop?
Probably your instantiation order is correct that way. You definitely should do all instantiations before calling the main loop in your case.
How do I manage that the particle draws himself while erasing the position he was drawn bevor?
If understand your last question correctly: Simply by changing the elements in your buffer objects (glBufferData(...);). Since you will clear the screen and swap buffers after each loop this will make them move. Just update their position with an update(time) call, e.g. pos = pos + dir * time;, put the new positions into a buffer and push that buffer with glBufferData(...) to the vertex array. Remember to bind the vertex array before pushing the buffer.
Some additional things I'd like to point out.
glEnableVertexAttribArray(1); is to enable a vertex attribute in your shader program to be able to pass data to that attribute. You should create a shader program
id = glCreateProgram()
// ... create and attach shaders here
// then bind attribute locations, e.g. positionMC
glBindAttribLocation(id, 0, "positionMC");
glLinkProgram(id);
And after initializing the vertex array with glGenVertexArrays(); you should enable all attributes your vertex array needs in your shader program. In this example positionMC would be at location 0, so you would call something like
glUseProgram(pid);
glBindVertexArray(vaid);
glEnableVertexAttribArray(1);
glVertexAttribPointer(...);
This has only to be done once, since OpenGL stores the state for every particular vertex array. By rebinding a vertex array you will restore that state.
In the main loop all you have to do now is calling your update and draw methods, e.g.:
handleInputs();
update(deltaTime);
glClear(...);
draw();
swapBuffers();

Flash/Flex: "Warning: filter will not render" problem

In my flex application, I have a custom TitleWindow that pops up in modal fashion. When I resize the browser window, I get this warning:
Warning: Filter will not render. The DisplayObject’s filtered dimensions (1286, 107374879) are too large to be drawn.
Clearly, I have nothing set with a height of 107374879.
After that, any time I mouse over anything in the Flash Player (v. 10), the CPU churns at 100%. When I close the TitleWindow, the problem subsides. Sadly, the warning doesn't seem to indicate which DisplayObject object is too large to draw. I've tried attaching explicit height/widths to the TitleWindow and the components within, but still no luck.
[Edit]
The plot thickens:
I found that the problem only occures when I set the PopUpManager's createPopUp modal parameter to "true." I don't see the behavior when modal is set to "false." It's failing while applying the graying filter to other components that comes from being modal. Any ideas how I can track down the one object that has not been initialized but is being filter during the modal phase?
Thanks for reading.
This might not be the case in your application, but I have come across similar cases where a height or width of an object has been set to some unreasonable big number as the result of misuse of an unsigned integer in calculations for positioning, height or width.
Schematic code for such a scenario could be like this:
var offset:uint = 30;
var position:uint = txt.textHeight - offset;
divider.y = position;
The code wrongfully assumes that txt.textHeight will always be bigger than 30. If it is not, txt.textHeight - offset will be a negative number, that when stored in an uint will instead become a very large number.
Let's say for example that the text in txt, presumed to be a long multiline text, instead is a single line that is 20 pixels heigh. The result will then be -10, and when stored in the uint var position, the value of position will be 4294967286.
The above is crappy code, an example, but in a real world situation the uint problem can occur in some more complex way, that might be harder to spot right away. I guess it is seldom a good idea to use an unsigned integer for stuff like x and y positions, that can have negative values.
You could write some code to recursively step down the hierarchy of DisplayObjectContainer and DisplayObject objects and check for the large height.
Should be pretty simple to write. A function something like this should do the trick:
function RecurseDisplayObjects(DisplayObject obj):void
{
//check for height and do a trace() or whatever here
if(obj is DisplayObjectContainer)
{
var container:DisplayObjectContainer = obj as DisplayObjectContainer;
for(var i:int=0; i<container.numChildren; i++)
{
RecurseDisplayObjects(container.getChildAt(i);
}
}
}
You would need to start this off by passing it the top level DisplayObject in your application. (possibly obtained with DisplayObject.root)
The other option you have is to get the Flex framework source and modify it to give you a more meaningful error.
The problem is probably not in your TitleWindow, but in objects below it. The filter failing to render is probably the blur filter flash applies over everything below the modal dialog. If one of the objects on the stage is too big to apply blur on it in real time, you get the error you mentioned.
I solved that problem by applying a mask to the object below the titlewindow, set to the size of the stage. That will probably solve your problem but you should definitely look into why something gets to that size, doesn't sound healthy. :-)
Sadly I have no idea, but we're trying to track down a similar issue in ours. Maybe this will help?
http://www.mail-archive.com/flashcoders#chattyfig.figleaf.com/msg48091.html
I had a similar issue, tracked it down to an alpha filter applied to an object scaled to -0.23453422334. Once I rounded the scale to 2 significant digits everything worked fine. A difficult error to track down however.

Resources