SFML community forums
Help => Window => Topic started by: vurentjie on June 25, 2008, 02:13:40 am
-
hi, i tried to simplify my code as much as possible and extract exactly where my problem is occuring, so the code below if copied and pasted wil compile, i have just included the neccessary pieces from multiple files where i have found a problem,
the problem, i set my window as a desktop_mode, then i draw a 2dpanel at the bottom of the viewport that overlays the 3d viewport, if the mouse cursor is over the black 'drag-line' and left mouse is held down, the panel can be resized/dragged up and down,
there could be a problem in my code, but from tests i am guessing something else, if i load the program up and without resizing i try to drag the panel, it misses the mark by about 20px, as soon as i resize by any amount it behaves as it should, the code shouldn't be wrong as i have used it before, but i might be wrong,please check for me,you can just copy paste code....
sorry if it is a bit long but i have tried to preserve exactly how i use it,not usually in one file though
#include <SFML/Window.h>
#include<SFML/System.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct GUI{
int high, wide;
}GUI;
GUI *mygui;
int init_gui_panel(int w, int h, GUI *gui);
void guidraw();
sfEvent Event;
sfWindow* mywin;
enum actions {DRAGS, NONE};
static int action = NONE;
void guidraw(){
glColor3f(0.1,0.1,0.1);
glBegin(GL_QUADS);
glVertex2i(mygui->wide, (mygui->high-5));
glVertex2i(0,(mygui->high-5));
glVertex2i(0, mygui->high);
glVertex2i(mygui->wide, mygui->high);
glColor3f(0.7,0.7,0.7);
glVertex2i(mygui->wide, 0);
glVertex2i(0,0);
glVertex2i(0, (mygui->high-5));
glVertex2i(mygui->wide, (mygui->high-5));
glEnd();
}
int init_gui_panel(int w, int h, GUI *gui){
//this function should encapsulate more than this later!!
gui->high = (h/4);
gui->wide = w;
return gui;
}
int main(){
sfWindow* mywin;
sfWindowSettings Settings = {24,8,4};
mywin = sfWindow_Create(sfVideoMode_GetDesktopMode(), "Quirk", sfResize | sfClose, Settings);
GUI initgui;
mygui = init_gui_panel(sfWindow_GetWidth(mywin), sfWindow_GetHeight(mywin),&initgui);
while(sfWindow_IsOpened(mywin)){
const sfInput* input = sfWindow_GetInput(mywin);
if(sfWindow_GetEvent(mywin, &Event)){
switch(Event.Type)
{
case sfEvtClosed:
sfWindow_Close(mywin);
break;
case sfEvtMouseButtonPressed:
switch(Event.MouseButton.Button){
case sfButtonLeft:
if( (sfInput_GetMouseY(input) > sfWindow_GetHeight(mywin)-mygui->high) && ( sfInput_GetMouseY(input) < sfWindow_GetHeight(mywin)-mygui->high+5) ){
action=DRAGS;
}
break;
}
break;
case sfEvtMouseButtonReleased:
if( Event.MouseButton.Button == sfButtonLeft)
{
action = NONE;
}
break;
case sfEvtMouseMoved:
switch(action){
case DRAGS:
mygui->high = (sfWindow_GetHeight(mywin)-(Event.MouseMove.Y));
if( ((sfWindow_GetHeight(mywin)-Event.MouseMove.Y) > (sfWindow_GetHeight(mywin)-30)) )
{
mygui->high = (sfWindow_GetHeight(mywin)-30);
}
if( Event.MouseMove.Y > (sfWindow_GetHeight(mywin)-30))
{
mygui->high = 30;
}
break;
}
break;
}
}
sfWindow_SetActive(mywin, 1);
glClearColor(0.5,0.5,0.5,1.0);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//3d
float aspect;
aspect = ((float)sfWindow_GetWidth(mywin))/((float)sfWindow_GetHeight(mywin));
glViewport(0,0,sfWindow_GetWidth(mywin), sfWindow_GetHeight(mywin));
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(45.0, aspect, 0.1, 200.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//2d
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluOrtho2D(0, sfWindow_GetWidth(mywin), 0, sfWindow_GetHeight(mywin));
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
guidraw();
sfWindow_Display(mywin);
}
return 0;
}
help appreciated
-
ok, no reply??mmm....maybe i shouldnt have pasted all that code, well i am not asking it to be fixed if it is wrong on my part. but later today i will try post an even simpler example of what i mean,
oh and by resize i mean resize the window,
if i load the window with getdesktop and i try adjust the panel (that i draw in opengl) it wont work, if i just adjust the window size by even 1px i can now adjust the panel by click-and-hold on it's drag-line...
this is on windowsxp, sfml 1.3, i am going to test it on 1.2 and check if it does same thing..
but as i say i have used this code before....except for the getdesktopmode part.
-
ok after double checking this,
if instead of
sfWindow* mywin;
sfWindowSettings Settings = {24,8,4};
mywin = sfWindow_Create(sfVideoMode_GetDesktopMode(), "Quirk", sfResize | sfClose, Settings);
i use say,
sfWindow* mywin;
sfVideoMode Mode = {800, 600, 32};
sfWindowSettings Settings = {24,8,4};
mywin = sfWindow_Create(Mode, "Quirk", sfResize | sfClose, Settings);
then my mouse input records just fine without having to resize the window,
which leads me to ask, is there something wrong how i am calling sfVideoMode_GetDesktopMode()?? or is it something else??
-
I can't see any relation between the video mode and the inputs, I'll try this code and see if I can reproduce the problem.
-
cool thanks, sorry for the hassle, if you notice anything blatantly wrong in my code just let me know, i don't need a full solution, maybe just a tip,
i don't think this should matter, but i build in code::blocks...
-
earlier you said you don't see relation between video mode and input, i think there might be,you know this but just to recap
mouse-y starts at top=(0)
opengl-y starts at bottom=(0)
if i draw a simple line across the screen in opengl using orthographic 192px from bottom,
and i everytime i click mouse on the line and print out -> window-height, mouse-ypos (from top), line-height(from bottom),
these are results:
open as desktop mode, no resize just one click on line,
window height 768
mouse y from top 556
line height from bottom 192
windowheight minus mousey gives 212 (20px out - possibly taskbar)
open as desktop mode, maximize, just one click on line,
window height 708
mouse y from top 508
line height from bottom 192
windowheight minus mousey gives 202 (10px out ?)
open as desktop mode, drag windows left edge slightly inward, just one click on line,
window height 742
mouse y from top 548 (-edit:550)
line height from bottom 192
windowheight minus mousey gives 192 -----CORRECT
open as 800X600, no resize, just one click on line,
window height 600
mouse y from top 408
line height from bottom 192
windowheight minus mousey gives 192 -----CORRECT
have you tried this?
-
hi,
i dont know if you had time to look at this, if you did could you pls inform me if you encountered same thing.
it is not a serious issue for me at the moment in any case,
later
-
Yes of course, I'll check this as soon as possible and let you know if I can find something ;)
-
hi,
i had a look through the svn and downloaded some of the source for window and video, i think i am going to have to download the c++ source, and i am going to see if i can try help debug this - or at least find out if it is a code bug or my display or something, at least to teach myself a bit more about what is going on behind the scenes,
I had a look at the msdn DEVMODE docs, and will start from there and then go through the window creation, even if i dont come up with a solution I will definitely gain from trying, later.....
-
ok i got a build workspace up and running, can compile the c++ and c libs, i am going to try check this out,
i have been thinkin though, i understand that you use dmPelsHeight to detect the height of the screen, is this connect in anyway to anything else,
would it not be possible to use GetSystemMetrics( SM_CYFULLSCREEN ), but i am not actually sure if that is where the problem lies in any case but it is where i am first going to start.
-
i just want to ask a quick question,
this is the first time i am trying something like this so kinda in the deep end here,
if i want to make changes that are reflected in the csfml libs,
i first make changes to the c++ source, compile those libs,
and then compile the c libs, correct?
-
okay i managed to get things going and want to discuss,
i changed return value of getdesktopmode to this:
return VideoMode(GetSystemMetrics( SM_CXFULLSCREEN ), GetSystemMetrics( SM_CYFULLSCREEN ), Win32Mode.dmBitsPerPel);
what this does is give the correct input from mouse, however the screenposition is now 20px lower.
I think dmPelsHeight was getting stuck somewhere on my system, and don't know exactly why, I was guessing my display drivers or monitor (HP 7540) doesnt agree with the DEVMODE stuff
i am going to try SM_CYSCREEN, as SM_CYFULLSCREEN, takes into account the bottom taskbar on windows, I think this will resolve the issue, but not sure how it affects videomode, although I pretty sure nothing bad will come of it.
-
i tried CYSCREEN instead, now this is exactly where mouse input becomes 20px out, as the screen size is perfectly set as a fullscreen desktop but mouse input is out by 20px (repeating myself here)....which means i am wrong about the DEVMODE stuff, that is all fine, the problem possibly lies either in the positioning on the screen, or in the actual input capture, not quite sure, going to go check that out now.
-
Hey, thanks a lot for trying to solve it by yourself :)
I'm sorry I don't have much time to help you right now, but I'll try to check it this week-end.
Let me know if you find more :)
-
You could try getting the dimensions of the viewport rather than the window. I have no clue if this'll give you the results you want, but it's worth a try.
-
cool, no luck yet, i am going to look at it this weekend too, i havent made a win32 window in a long time so having to relearn a whole bunch in the process, but i guess it will give me some hair on my chest,
i am actually enjoying the challenge, and hope to solve it, i got a nifty program called source navigator which is helping me stacks to jump around in your code...till anon
-
Hi,
I think i found the problem.
When SFML trying to create a window with a client area egal to screen resolution (or highest), then, resulting client area is smallest than the requested VideoMode (maybe title bar size). ATM, SFML width and height are initialized before any window creation, and not updated after that :
// LoC 145 (WindowImplWin32.cpp)
int Width = myWidth = Mode.Width;
int Height = myHeight = Mode.Height;
If the client area of the windows is smaller than the requested video mode (if you pass GetDesktopMode(), it will be) window GetHeigth and GetWidth will be false until a WM_SIZE notif (which will call GetClientRect).
This could be fix with a GetClientRect call after the window creation :
LoC 171 WindowImplWin32.cpp
// Create the window
if (HasUnicodeSupport())
{
wchar_t WTitle[256];
int NbChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Title.c_str(), static_cast<int>(Title.size()), WTitle, sizeof(WTitle) / sizeof(*WTitle));
WTitle[NbChars] = L'\0';
myHandle = CreateWindowW(ourClassNameW, WTitle, Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
}
else
{
myHandle = CreateWindowA(ourClassNameA, Title.c_str(), Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
}
// ==== NEW ====
if (!Fullscreen)
{
RECT clientRect = {0, 0, 0, 0};
if (!GetClientRect(myHandle, &clientRect))
{
// ...
}
myWidth = clientRect.right - clientRect.left;
myHeight = clientRect.bottom - clientRect.top;
}
// ==== /NEW ====
I don't know how openGL context creation is influenced by this modification, but the OP code works perfectly with it (in all resolution, fulscreen etc).
-
The client area always matches the requested mode :
WindowImplWin32.cpp
163 if (!Fullscreen)
164 {
165 RECT Rect = {0, 0, Width, Height};
166 AdjustWindowRect(&Rect, Win32Style, false);
167 Width = Rect.right - Rect.left;
168 Height = Rect.bottom - Rect.top;
169 }
So it shouldn't be necessary to get the client size after creation :|
-
Yeap you're right, it shouldn't =p
e.g. i use 1280x1024, with getDesktopMode VideoMode is at 1280x1024, and Rect from AdjustRect is at 1288x1058 (window area) but the final window size (include border and title) is 1288x1036. That's why your final client area is shrinked (requested : 1280x1024 real : 1280x1002).
Some tests with differents window size :
// Create the window
if (HasUnicodeSupport())
{
wchar_t WTitle[256];
int NbChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Title.c_str(), static_cast<int>(Title.size()), WTitle, sizeof(WTitle) / sizeof(*WTitle));
WTitle[NbChars] = L'\0';
myHandle = CreateWindowW(ourClassNameW, WTitle, Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
}
else
{
myHandle = CreateWindowA(ourClassNameA, Title.c_str(), Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
}
{
if (!Fullscreen)
{
RECT clientRect , windowRect = {0, 0, 0, 0};
GetClientRect(myHandle, &clientRect);
GetWindowRect(myHandle, &windowRect);
myWidth = clientRect.right - clientRect.left;
myHeight = clientRect.bottom - clientRect.top;
int realWidth = windowRect.right - windowRect.left;
int realHeight = windowRect.bottom - windowRect.top;
std::cout << "Requested client : " << Mode.Width << "x" << Mode.Height << " Real client : " << myWidth << "x" << myHeight << std::endl;
std::cout << "Requested window : " << Width << "x" << Height << " Real client : " << realWidth << "x" << realHeight << std::endl;
}
}
800x600 (OK) :
Requested client : 800x600 Real client : 800x600
Requested window : 808x634 Real client : 808x634
1024x768 (OK) :
Requested client : 1024x768 Real client : 1024x768
Requested window : 1032x802 Real client : 1032x802
1280x1024 (desktop resolution) :
Requested client : 1280x1024 Real client : 1280x1002
Requested window : 1288x1058 Real client : 1288x1036
1280x1024 (with sfNone instead of sfResize | sfClose)
Requested client : 1280x1024 Real client : 1280x1024
Requested window : 1280x1024 Real client : 1280x1024
I don't know why CreateWindow reduce your window size (maybe there is a maximum window size ?) but it does. =)
-
Damn, I have to find out what's going on. Probably some OS internal magic... :|
-
yeah i also noticed that, that the screen dimension that i print out shrinks when i resize, even though the height has not changed at all, but been at work the whole day, going to look more at it this weekend, one of us is going to solve this soon as it is not many files to deal with.
edit-->add
also thanks SirJulio, that definitely seems to be where the problem lies, at first i thought it might be something just with getdesktop, but if i do something like the following
sfVideoMode Mode = {GetSystemMetrics( SM_CXSCREEN )-x, GetSystemMetrics( SM_CYSCREEN )-x, 32};
and i start x at 0, and increment, only when x reaches 25 will my screen and input behave.
-
Yeap, i think we have our problems too.
I made some tests with wininspector and apparently on my comp, 1292x1036 seems to be the larger size I can use for any window (notepad for the test). This values is exactly what GetSystemMetricsSM_C[X|Y]MAXTRACK) returns. After some querying, Caption bar vertical size of sizable window is 26 (SM_CYCAPTION), and border of the window is 4 (SM_CYBORDER), so we found our magical number. Window cannot be higher than 1036 (always on my res : 1024) and for sizable window we must count caption and border size (26 + 2 * 4 = 34), so we cannot have a client area higher than 1002 (1036 - 34), which is equivalent to prior results. If your window is created with sfNone (noborder no caption), you don't have the problem because resulting window will be at the correct size (no need to count border and caption).
According to MSDN, you can override this behavior by processing WM_GETMINMAXINFO (http://msdn.microsoft.com/en-us/library/ms632626(VS.85).aspx) notif.
But, IMHO, creating a window higher than the screen vertical resolution (which seems possible) is not a good thing, dev request a VideoMode, but uses GetWidth and GetHeight to keep all calculs relative. If GetDesketopMode, create a client area smaller than the requested one, this is not a problem but GetWidth and GetHeigth return by Window must be correct.
So, i think that "post-calculate" the real Width and Height would be the best methods for this kind of situation. =)
-
ok i have come up with a solution will post it now, actually very very simple!
just need to add check for fullscreen mode.as the problem was just calculate interior render window.
-
ok here we go this was the only part i needed to change,
////////////////////////////////////////////////////////////
/// Create the window implementation
////////////////////////////////////////////////////////////
WindowImplWin32::WindowImplWin32(VideoMode Mode, const std::string& Title, unsigned long WindowStyle, WindowSettings& Params) :
myHandle (NULL),
myCallback (0),
myCursor (NULL),
myKeyRepeatEnabled(true)
{
// Register the window class at first call
if (ourWindowCount == 0)
RegisterWindowClass();
// changes here
int Left = (GetDeviceCaps(GetDC(NULL), HORZRES) - Mode.Width) / 2;
int Top = (GetDeviceCaps(GetDC(NULL), VERTRES) - Mode.Height) / 2;
//first calculate outer dimension
int Width = Mode.Width;
int Height = Mode.Height;
//
//then calculate dimensions of render view
myWidth = Width - (2*GetSystemMetrics( SM_CXSIZEFRAME ));
myHeight = Height - (2*GetSystemMetrics( SM_CYSIZEFRAME )) - GetSystemMetrics( SM_CYCAPTION );
// Choose the window style according to the Style parameter
DWORD Win32Style = WS_VISIBLE;
if (WindowStyle == Style::None)
{
Win32Style |= WS_POPUP;
}
else
{
if (WindowStyle & Style::Titlebar) Win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
if (WindowStyle & Style::Resize) Win32Style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
if (WindowStyle & Style::Close) Win32Style |= WS_SYSMENU;
}
// In windowed mode, adjust width and height so that window will have the requested client area
bool Fullscreen = (WindowStyle & Style::Fullscreen) != 0;
/* if (!Fullscreen)
REMOVED THIS AND OPTED FOR TOP AS IT WAS THROWING OUT, I THINK,EITHER WAY NOT NEEDED
*/
// Create the window
if (HasUnicodeSupport())
{
wchar_t WTitle[256];
int NbChars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Title.c_str(), static_cast<int>(Title.size()), WTitle, sizeof(WTitle) / sizeof(*WTitle));
WTitle[NbChars] = L'\0';
myHandle = CreateWindowW(ourClassNameW, WTitle, Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
}
else
{
myHandle = CreateWindowA(ourClassNameA, Title.c_str(), Win32Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
}
i checked the resize event and that is fine, and is the only other place that i could see that myWidth/myHeight was being changed,
also checked fullscreen mode and seemed to work just fine,
later.
-
Ok I see. I've changed the code so that now the window's client size is calculated again after its creation.
vurentjie, I don't think your idea of calculating manually the window's external size was the way to go, especially if you don't take the style in account. Anyway it was also more complicated than just recomputing the size after creation ;)
Thank you guys for your help, let me know if everything's fine now or not :)
-
cool no worry, i will grab the updates, was merely what i came up with in the situation, and worked, but thanks.