X11 window cuts off bottom 30 pixels of drawing (C++) - c++

This is a homework assignment. Basically, we were given some code and had to run it through Bresenham's line drawing algorithm.
Everything works fine except that the lines are cut off at the bottom (about 30 pixels). The window is big enough, but it just displays white space at the bottom.
(If I make the window 30 pixels higher, all the lines are complete so the algorithm implementation is good.)
window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0,
0, 512, 512, 5, black, white);
gc = XCreateGC(display, window, 0,0);
XClearWindow(display, window);
XMapRaised(display, window);
Am I guessing the error is somewhere in one of these lines?

Related

Image over another image in allegro5 (C++)

I have a problem with adding a background in my game. My code looks like that:
while (true)
{
al_draw_bitmap(background, 0, 0, NULL);
al_flip_display();
some code(...);
al_draw_bitmap(snake,0,0,NULL);
/*drawing my snake's tail*/
al_clear_to_color(al_map_rgb(0,0,0));
al_draw_bitmap(apple,0,0,NULL);
al_flip_display();
}
And I have visible an apple and a black screen most of the time.
I've been changing order of some lines in code and none of these combination worked (best case was when I had visible snake and background but there was no apple).
Before adding a background, my snake's tail sometimes disappered, but it wasn't very visible, and except that, everything seemed to be okay.
Anyone knows how to add a background properly?
Or maybe it's fault of my computer?
Once per draw loop, you should:
clear the display
draw your background
draw bitmaps on top of the background
flip the display
For example:
al_clear_to_color(al_map_rgb(0,0,0));
al_draw_bitmap(background, 0, 0, NULL);
al_draw_bitmap(apple,0,0,NULL);
al_draw_bitmap(snake,0,0,NULL);
al_flip_display();
Note that you should only call al_flip_display once per draw loop, after you have drawn everything for that loop. al_clear_to_color should be called first as it will wipe out everything you have drawn. In the example you gave, you are drawing your apple and snake to the same location, so I wouldn't be suprised if one is blocking part of the other.
Also, you probably don't want to stick your draw loop in a while(true) as the framerate will be unconstrained. That is, it will run as fast as it is allowed, and the framerate won't be consistent. The typical approach is to use an event-driven draw loop.

SDL : blitting on background instead of screen?

Hi i'm working on an SDL/C game , i've made a camera scrolling with a
big background (6000*1024) and (1024*768) screen,
game.screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
so if i want to blit something on the screen as a destenation :
apply_surface( xxx, yyy, map.BALL, game.screen, NULL );
it will follow the camera when moving, wich it's not the case for ennemies they should move on the background and not the screen !
so if i blit something on the background as destination i have a problèmeas following,
apply_surface( xxx, yyy, map.BALL, map.background, NULL );
the old images stays on the background when moving as the folowing pictures :
First I have to say that your way of implementing camera scrolling is quite heavy. I would recommend that you would just draw the objects directly to the screen surface taking the camera position into account.
If you want stick with your plan, you should clear your background before redrawing it. This can be done using command SDL_FillRect.
// Replace 101, 102, 103 with the background color you want
SDL_FillRect(map.background, NULL, SDL_MapRGB(map.background->format, 101, 102, 103));

Painting Text above OpenGL context in MFC

I work on an MFC app containing OpenGL context.I am new to MFC that is why I am asking it.OpenGL works fine ,but when I want to draw a text above the 3D window using this code inside WindowProc:
case WM_PAINT:
hDC=BeginPaint(window,&paintStr);
GetClientRect(window,&aRect);
SetBkMode(hDC,TRANSPARENT);
DrawText(hDC,L"He He I am a text on top of OpenGL",-1,&aRect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
EndPaint(window,&paintStr);
return 0;
it is shown beneath the OpenGL context.I can see it only when resizing the window as the OpenGL rendering pauses than.
What you're doing is wrong and also harder than doing it all in OpenGL. To solve the problem of adding text to an OpenGL-drawn window, it's better to just make OpenGL draw the text. You can even use the exact same font you were using in MFC by creating a CFont instance when you handle WM_CREATE, selecting the font into the DC, and calling wglUseFontBitmaps, which will make a series of rasterized bitmaps that you can use with glCallLists. (While you're at it, call GetCharABCWidths and GetTextMetrics to determine the width and height of each glyph, respectively.)
ABC glyphInfo[256]; // for font widths
TEXTMETRIC tm; // for font heights
// create a bitmap font
CFont myFont;
myFont.CreateFont(
16, // nHeight
0, // nWidth
0, // nEscapement
0, // nOrientation
FW_NORMAL, // nWeight
FALSE, // bItalic
FALSE, // bUnderline
0, // cStrikeOut
ANSI_CHARSET, // nCharSet
OUT_DEFAULT_PRECIS, // nOutPrecision
CLIP_DEFAULT_PRECIS, // nClipPrecision
DEFAULT_QUALITY, // nQuality
DEFAULT_PITCH | FF_SWISS, // nPitchAndFamily
_T("Arial") // lpszFacename
);
// change the current font in the DC
CDC* pDC = CDC::FromHandle(hdc);
// make the system font the device context's selected font
CFont *pOldFont = (CFont *)pDC->SelectObject (&myFont);
// the display list numbering starts at 1000, an arbitrary choice
wglUseFontBitmaps (hdc, 0, 255, 1000);
VERIFY( GetCharABCWidths (hdc, 0, 255, &glyphInfo[0]) );
pDC->GetTextMetrics(&tm);
if(pOldFont)
pDC->SelectObject(pOldFont);
myFont.DeleteObject();
Then when you handle WM_PAINT, reset your matrices and use glRasterPos2d to put the text where you need it to go. I suggest calculating the exact width of your string using code similar to the one below if you want it to be horizontally centered.
// indicate start of glyph display lists
glListBase (1000);
CRect r;
GetWindowRect(r);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(0, r.Width(), 0, r.Height());
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
CString formattedString;
formattedString.Format("Pi is about %1.2f", 3.1415);
int stringWidth=0; // pixels
for(int j=0; j < formattedString.GetLength(); ++j)
stringWidth += glyphInfo[ formattedString.GetAt(j) ].abcA + glyphInfo[ formattedString.GetAt(j) ].abcB + glyphInfo[ formattedString.GetAt(j) ].abcC;
double textXPosition, textYPosition;
textXPosition = r.Width()/2-stringWidth/2; // horizontally centered
textYPosition = r.Height()/2-tm.tmHeight/2; // vertically centered
glRasterPos2d(textXPosition,textYPosition);
// this is what actually draws the text (as a series of rasterized bitmaps)
glCallLists (formattedString.GetLength(), GL_UNSIGNED_BYTE, (LPCSTR)formattedString);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
While the setup is annoying, you only have to do it once, and I think it's less frustrating than dealing with GDI. Mixing GDI and OpenGL is really asking for trouble, and OpenGL does a very good job of displaying text -- you get sub-pixel accuracy for free, among other benefits.
Edit: In response to your request for including GUI elements, I will assume that you meant that you want to have both OpenGL-drawn windows and also standard Windows controls (edit boxes, check boxes, buttons, list controls, etc.) inside the same parent window. I will also assume that you intend OpenGL to draw only part of the window, not the background of the window.
Since you said you're using MFC, I suggest that you create a dialog window, add all of your standard Windows controls to it, and then add in a CWnd-derived class where you handle WM_PAINT. Use the resource editor to move the control to where you want it. Effectively, you're making an owner-draw custom control where OpenGL is doing the drawing. So OpenGL will draw that window, and the standard MFC classes (CEdit, CButton, etc.) will draw themselves. This works well in my experience, and it's really not much different from what GDI does in an owner-draw control.
What if instead you want OpenGL to draw the background of the window, and you want standard Windows controls to appear on top of it? I don't think this is a great idea, but you can handle WM_PAINT and WM_ERASE for your CDialog-derived class. In WM_ERASE, call OpenGL to draw your 3D content, which will be overwritten by the standard Windows controls when WM_PAINT is called. Alternatively in WM_PAINT you could call OpenGL before calling CDialog::OnDraw, which would be similar.
Please clarify your statement "I want to add some 2s graphics overlay (like labels ,gui elements)" if you want me to write more.
Looking at your code I assume the OpenGL rendering is called from a timer or as idel loop action. Naturally OpenGL execution will probably contain some clearing, thus taking anything else drawn with it.
Mixing GDI text drawing with OpenGL is not recommended, but can be done. But of course you then need to include that code into the OpenGL drawing function, too, placing all GDI operations after the buffer swap.

How to draw a part of a window into a memory device context?

I'm using simple statements to keep it, er, simple:
The screen goes from 0, 0 to 1000, 1000 (screen coordinates).
A window goes from 100, 100 to 900, 900 (screen coordinates).
I have a memory device context that goes from 0, 0 to 200, 200 (logical coordinates).
I need to send a WM_PRINT message to the window. I can pass the device context to the window via WM_PRINT, but I cannot pass which part of its window it should draw into the device context.
Is there some way to alter the device context that will result in the window drawing a specific part of itself into the device context (say, its bottom right portion from 700, 700 to 900, 900)?
(This is all under plain old GDI and in C or C++. Any solution must be too.)
Please note:
This problem is part of a larger solution in which the device context size is fixed and speed is crucial, so I cannot draw the window in full into a separate device context and blit the part I want from the resultant full bitmap into my device context.
You can call SetViewportOrgEx() to specify the device context coordinates that will be mapped to the window's origin:
SetViewportOrgEx(yourDC, -600, -600, NULL);
Since your window's size is 800x800, offsetting the DC's coordinate system by -600x-600 will result in the 200x200 bottom right area of the window being drawn, and the rest being clipped.

vertical text won't be bold in win32 GDI c++

I'm trying to draw vertical text in win32 GDI api.
I call CreateFont() with 2700 for the angle and 900 for bold.
logPxlY = ::GetDeviceCaps (c->_hdc, LOGPIXELSY);
_hfont = ::CreateFont (-::MulDiv (point, logPxlY, 72),
0, angle, weight, 0, FALSE, FALSE, FALSE, 0, 0, 0, 0,
FIXED_PITCH | FF_MODERN, face);
where face is "Courier New", point is 9, angle is 2700 and weight is 900.
The text IS rotated correctly, but it's pretty dang faint compared to normal Courier New rendering. Is this since truetype is polishing the normal text real nice and isn't bothering with wierd rotated text or something?
Thanks for any insight :)
The font mapper can be a bit strange at times. 700 is bold, 900 is supposed to be "black". However, you probably have a Courier New Bold font file, so it can be used directly, whereas you probably do not have a Courier New Black font file, so it'll be synthesized -- probably from the normal Courier New font instead of from Courier New Bold (not sure why that is, but such is life).
If you try running through the possibilities, something like this (MFC code, for the moment, but the idea applies regardless):
CFont fonts[num];
pDC->SetBkMode(TRANSPARENT);
for (int i=0; i<num; i++) {
fonts[i].CreateFont(10, 0, 2700, 0, i*100, 0, 0, 0, DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, OUT_CHARACTER_PRECIS, PROOF_QUALITY, FF_MODERN, L"Courier New");
pDC->SelectObject(fonts+i);
pDC->TextOut(20+i*14, 20, L"This is some text");
}
What you'll probably see (what I get anyway) looks like this:
The 700 weight font is noticeably bolder than the 800 or 900 weight. This is not unique to Courier New either -- for example, the same code with the font name changed to Times New Roman produces output like this:
That's a bit closer, but the 700 weight still clearly looks darker than the 800 or 900. I won't bore you with screen shots, but the same effect happens when the text is horizontal.
Edit: One other minor detail: though it probably doesn't make any difference, you're currently computing the size of the font a bit incorrectly -- you're using logpixelsy, which makes sense when the font is horizontal. For a vertical font, you should use logpixelsx instead. On a typical screen, those will be identical, but on a printer (for example) they may be substantially different.