|
Now got another problem... if we lock windows and then unlock the drawing in the buffers are lost...
What should be done to handle windows lock/unlock conditions?
Thank you.
- ns -
|
|
|
|
|
I get the feeling that the best approach for you is to use a FBO and do offscreen rendering.
Google "opengl render to texture", you can bind a frame buffer at the start of your rendering, then blit it as needed.
|
|
|
|
|
Thank you very much. I shall try for that.
- ns -
|
|
|
|
|
I'm working with a file format that outputs graphics (in line segments only, no polygons, no points), but has a very screwy way of doing so. Without giving too much away, I'm able to retrieve the list of points from the file with some fairly straightforward calls. However, I need to transform these points and store them (they'll later be used to draw, but I need the points for further manipulation). The problem is that the way the points are currently stored is as follows:
A) The origin (0,0) is in the middle of the drawing, like you would have on a piece of graph paper. I need to transform it so that it will look right on the screen.
B) The image is centered on the origin.
C) The image is inverted along the Y axis.
D) The points in question are already in a nice data structure that includes color and other information.
How can I quickly transform all these points such that if I just used DrawLines, that they would come out correctly? All the matrix code I can find is based around applying transforms to the graphics object, which I don't need to do at the moment. Also, in what order should I do the relevant transforms? I'm thinking that I should flip it first, then shift it (+width, +height). Is that the correct approach?
Performance is not an issue, as users won't be waiting on this operation to complete (or if they are, I can revisit the issue with the intent of collecting more money from them).
Thanks in advance,
Will
|
|
|
|
|
Hi,
you would need one or more of the transform methods in the Graphics class.
Graphics.TranslateTransform does translation, such as moving the origin to the center;
Graphics.ScaleTransform does scaling, and if you use a negative number you are actually flipping the drawing;
Graphics.RotateTransform does rotations, which you don't seem to need.
I trust all of these internally construct a single 3*3 transformation matrix which then gets applied
to all the drawing methods called thereafter.
When you would use more than one of the above, you can choose the order; first scale, then translate,
or first translate, then scale can be made to result in exactly the same, but it would require different parameter values since the first transformation gets applied to the parameters of the second translation.
You can also calculate the entire transformation matrix yourself and just use Graphics.Matrix
Hint: initially you will probably make mistakes in the polarity and magnitude of the transformation parameters, sending your points way outside your plotting area, hence I suggest you start with a very small drawing in a big surface, improving the chance you do see something. You then can fix whatever needs fixing step by step.
|
|
|
|
|
As a heads up - keep in mind the GDI+ Matrix object is marked IDisposable. Fairly crazy for a small float array I know - but you will leak handles if you don't dispose of it.
Also creating / destroying these seems to be moderately expensive. I used GDI+ for a crap debug renderer for Entanglar before I got a DirectX one up - and it was quite slow until I started reusing the "camera" matrix every frame with "LoadThisStuff(float[])".
|
|
|
|
|
Mark Churchill wrote: keep in mind the GDI+ Matrix object is marked IDisposable
Quite a surprise indeed. I didn't know that... Thanks.
|
|
|
|
|
Nor did I. Why would they do that?
I wish they had a way to transform Size objects. Say, for instance that I'm measuring a piece of text and I get a size from it. If the text is going to be rotated, I need to somehow figure out how large it will be, but the matrix object doesn't have any methods for this.
|
|
|
|
|
it all is a bit mysterious...
And I never used Matrix class explicitly; at most I use Graphics.TranslateTransform() and similar
methods, without touching the matrices myself.
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
|
|
|
|
|
Greetings,
I am currently using bitmap fonts in a Win32 application, following closely the method presented in NeHe's tutorial 13[^] (wglUseFontBitmaps, glRasterPos2f, glCallLists etc.).
I have found that for most graphics cards everything works as expected, however for some "cheap" graphics cards (e.g., on board a toshiba laptop of a work mate) no text is displayed. I have checked all the font creation and drawing calls for errors and no errors are being returned. I would like to have bitmap fonts work on all hardware instead of use a different method for displaying fonts.
I am posting in the hope that some guru here has seen this behavour and worked out what is going on, because I am stuck.
Thanks,
Dave
Nunquam obliviscar
|
|
|
|
|
Solved my own problem in the end after being stuck for a couple of days.
I was drawing a quad as a background and then drawing the text on top of the quad. After significant trial and error, I realised that he glCallLists function used to display the bitmap characters was being processed after the quad was being drawn, causing the text to appear behind the quad instead of on top of it, but only on some hardware.
The solution was as simple as changing the z location of the text (using glRasterPos3i instead of glRasterPos2i) so the text is explicitly above the background quad.
Thanks to anybody following this post and obscure bug for your reading time!
Nunquam obliviscar
|
|
|
|
|
Hi Everyone,
I'm using SplitContainer, now i need to Fill Panel2 with Red Color Background
Without using Panel2 paint event how to Draw it.
|
|
|
|
|
Since you don't want to use the paint event, THIS IS HARDLY A GRAPHICS QUESTION!
You would be more likely to get an answer in the forum for the language you are using.
However, In the Properties window expand the Panel2 Property and set the BackColor Property to whatever you want.
Henry Minute
If you open a can of worms, any viable solution *MUST* involve a larger can.
|
|
|
|
|
Regards
I have a problem. I cant get to refresh an image the second time it should be displayed. I am using gdi+ function Graphics::DrawImage. The image displays correctly but the second time (in a loop) the function is called the image isn't refreshed. Instead the image stays (on screen) as the first time it was drawn. I know that the image (bitmap) is changed between the two calls for DrawImage function because, when I do something with the window the image is drawn to, (like resizing it, minimizing etc.), the image is refreshed, but if I do nothing the image stays as it is the first time DrawImage draws it. I am changing image's pixels in another function named Render(), that is called before DrawImage.
Is there another function that draws image on screen, or is there a clear screen function. (I tried with graphics.Clear(color) function but after it the screen is filled with the color 'color' and again it it stays like that indefinitely)
The bitmap is created in memory and isn't read from the disk (although it's the same thing once it is in memory).
Here is part of the code which is called continously (in a loop):
void Prikaz(HDC hdc){
Graphics graphics(hdc);
Render();
Bitmap FrameBuffer((BITMAPINFO*) &((*BMPSlika).InfoHeader), (*BMPSlika).PixelData);
graphics.DrawImage(&FrameBuffer,0,0);
}
BMPSlika is a pointer to the bitmap image structure.
|
|
|
|
|
It's not clear what you're using as a framework for the rest of your application, but I think you might be missing the "invalidate" call on the window after you draw to it to get it refreshed.
"Republicans are the party that says government doesn't work and then they get elected and prove it." -- P.J. O'Rourke
|
|
|
|
|
I'm using .net framework, and i don't have invalidate function. is there an equivalent in .net?
I'm using MFC in standard windows libraries, in VS 2008, (VC++ 2008).
modified on Monday, January 12, 2009 11:19 AM
|
|
|
|
|
I don't use .Net so I can't speak definitively about it but a quick search of MSDN.Microsoft.com shows that most .Net windows have an Invalidate function.
Um, you just confused me since you modifed your post. If you're using MFC, you have an Invalidate on your View class. Earlier, you said you didn't have MFC which would be true if you were using VS 2008 Express.
"Republicans are the party that says government doesn't work and then they get elected and prove it." -- P.J. O'Rourke
|
|
|
|
|
uff sorry about that...
i searched through the project settings and found out that it is using MFC standard windows libraries... before that I hurriedly concluded, since I can't use invalidate function and I've not fount an mfc90.dll (in VS2008), that I dont have MFC...
|
|
|
|
|
there is a problem and I cant use invalidate, i'll work on that. in the meanwhile here is WndProc procedure, it might bee something here that prevents image being refreshed. I think some of the variables in PAINTSTRUCT ps, HWND hWnd, and HDC hdc are not properly set for the image to be refreshed; (firstly I think it has something to do with PAINTSTRUCT);
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam){
PAINTSTRUCT ps;
HDC hdc;
switch(message){
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
Prikaz(hdc);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
SnimiBitmap();
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
this is WndProc process, in case it can solve my problem. I think there is something with this WM_PAINT case, it is called only when I resize, minimize, move it offscreen OR when i hold mouse pointer over the (display) window.
In first three situations when I resize, minimize, or move offscreen, the image does get refreshed, (the WM_PAINT case is executed and in it the Prikaz(hdc) iz executed which displays new image)
In the fourth situation, when I hold a mouse pointer over the display window, the WM_PAINT case is switched and the Prikaz(hdc) does get executed (including all the functions in Prikaz(hdc)), but the image doesn't get refreshed...?
this leads me to conclusion that, in situation when the mouse is over the display window, something is not "properly" set in this line, (since the Prikaz(hdc) uses argument hdc):
hdc = BeginPaint(hWnd, &ps);
I have seen the variables in ps (which is an PAINTSTRUCT structure), the hWnd (which is of HWND type) and hdc (HDC type (:lol))... In each situation they hold different values except for ps.fErase, ps.fIncUpdate, ps.fRestore. they are allways set to value 0;
there is allso ps.rgbReserved which is an pointer to an array of bytes but i'll examine it more closely.
if anyone knows about PAINTSTRUCT structure or hWnd and hdc, what is wrong with them when the image doesn't get refreshed, please let me know. in meanwhile I will try something with ps.rgbReserved, and try to get invalidate() function to include in my code, (this has something to do with .NET namespaces to do i think)....
|
|
|
|
|
You mentioned something about a loop in your first post - where is this loop and
what is it (supposed to be) doing?
WM_PAINT is posted to your window's message queue by the system. The parameters are
not in your control, nor are they wrong, nor should you be trying to send/post a WM_PAINT
message yourself.
Window rendering has been the same since the beginning of Windows....the problem is in YOUR code,
not some problem in MFC (which you're not using apparently), .NET (which you're not using apparently),
or the system.
void Prikaz(HDC hdc){
Graphics graphics(hdc);
Render();
Bitmap FrameBuffer((BITMAPINFO*) &((*BMPSlika).InfoHeader), (*BMPSlika).PixelData);
graphics.DrawImage(&FrameBuffer,0,0);
}
This code has nothing to do with WM_PAINT or Invalidatexxxx() functions. The bitmap will be rendered
immediately if the HDC and the Bitmap are valid.
According to your comments, your WM_PAINT handling code is working fine, so where else are
you calling this from and how are you obtaining the HDC?
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Read the message please.
Mark Salsbery wrote: You mentioned something about a loop in your first post - where is this loop and
what is it (supposed to be) doing?
for "loop" i meant calling the Prikaz() function over again (that was in first post)
Mark Salsbery wrote: WM_PAINT is posted to your window's message queue by the system. The parameters are
not in your control, nor are they wrong, nor should you be trying to send/post a WM_PAINT
message yourself.
i'm not trying to change the message to constantly switch to WM_PAINT case, nor I said the parameters are whong (READ THE MESSAGES and then answer them if you wish to)
Mark Salsbery wrote:
Window rendering has been the same since the beginning of Windows....the problem is in YOUR code,
not some problem in MFC (which you're not using apparently), .NET (which you're not using apparently),
or the system.
the problem IS in my code (that's why I asked for help in the first place) , and there IS a problem with my .NET config in my VS.
Mark Salsbery wrote: This code has nothing to do with WM_PAINT or Invalidatexxxx() functions. The bitmap will be rendered
immediately if the HDC and the Bitmap are valid.
that code is called when the WM_PAINT message is set.
the bitmap is rendered (correctly), but only the first time the WM_PAINT is called. the WM_PAINT is called (in my program) only when i do something with the window the image is displayed in, like resizing, minimizing, holding a mouse pointer over the window.....
in the first two situations, when i resize it or minimize (and maximize ofc) the image that is displayed gets updated... (my image in the program is constantly changed in the Render() function)
in the last situation when i hold a mouse pointer over the window the WM_PAINT case gets executed, and whit it the Prikaz function, but then the image doesnt get updated.
I was asking for a way to constantly update the image when WM_PAINT is switched.
Mark Salsbery wrote: According to your comments, your WM_PAINT handling code is working fine, so where else are
you calling this from and how are you obtaining the HDC?
i dont understand you, i'm not calling it from anywhere else in my code.
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam){
PAINTSTRUCT ps;
HDC hdc;
switch(message){
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
Prikaz(hdc, hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
SnimiBitmap();
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
i'm geting it with the BeginPaint
|
|
|
|
|
OK I've gone through your posts....there's so much contradicting information it
makes it really hard to follow
From all I can see, you are not using .NET and you're not using MFC.
If your window redraws fine when you resize it, move it, or move another window over
and then off it, then your WM_PAINT handler code is working fine.
Here's the code I have so far:
void Prikaz(HDC hdc){
Graphics graphics(hdc);
Render();
Bitmap FrameBuffer((BITMAPINFO*) &((*BMPSlika).InfoHeader), (*BMPSlika).PixelData);
graphics.DrawImage(&FrameBuffer,0,0);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam){
PAINTSTRUCT ps;
HDC hdc;
switch(message){
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
Prikaz(hdc, hWnd);
return 0;
case WM_DESTROY:
PostQuitMessage(0);
SnimiBitmap();
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
Prikaz() is only called from the WM_PAINT handler code, correct?
How many places is Render() called from?
If you call an Invalidate function from Render() to force a repaint of
the window (or a portion of the window) then you'll have an infinite redraw
loop, which will really slow down your UI
So if you're calling Render() perhaps from another thread that is updating the bitmap,
then the code making the call to Render() should then call an invalidate function
like InvalidateRect() to tell the system it should send another WM_PAINT.
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
Yes, Prikaz is only called from the WM_PAINT handler code.
Render() is called only from Prikaz(), (that is a bit stupid, i could do completely without Prikaz())
In render() i'm just repainting the bitmap, and calling it from prikaz().
it's a problem i cant use invalidate, (someone refered to it in .net or mfc),
Mark Salsbery wrote: call an invalidate function
like InvalidateRect() to tell the system it should send another WM_PAINT.
i need that function that tells the system to send another WM_PAINT, but as i have seen in some case when WM_PAINT handler is executed, (i mean on Prikaz() in WM_PAINT handler to be executed) the image on the screen doesn't get always updated (in some cases graphics.DrawImage() does update the image and in some cases it doesn't)... i was trying to see what causes DrawImage to redraw image and how to "simulate" that condition...
i'll use InvalidateRect() as you said, it must work...
modified on Tuesday, January 13, 2009 4:45 PM
|
|
|
|
|
Valdyr wrote: it's a problem i cant use invalidate
Invalidate() is specific to MFC. You need to Use one of the Win32
Invalidate functions...InvalidateRect() or InvalidateRgn(). For an instant
repaint you can call UpdateWindow() right after the Invalidatexxx call.
There's also RedrawWindow(), which combines the Invalidate and UpdateWindow
into one call, with some extra flags for finer control.
Valdyr wrote: i was trying to see what causes DrawImage to redraw image
In your case, it gets called any time you get a WM_PAINT message for your window,
since you aren't calling it anywhere else. You'll get WM_PAINT messages when an area
of the window is marked invalid, as described above, or by the system when you resize
the window larger (which invalidates the newly exposed part of the window) or move
another window off of your window.
So back to your code, if you're not getting desired results, the only place left is in
your Render() code.
Mark
Mark Salsbery
Microsoft MVP - Visual C++
|
|
|
|
|
it works, thanks
thats what i needed, InvalidateRect(), i didn't know about it in gdi.
now the image gets updated "on it's own"
|
|
|
|
|