kamac
|
|
« on: May 08, 2013, 07:47:27 AM » |
|
Hey there. What I would like is not an ordinary win32 window which we can get by making a new project with template set properly in MSVC++. I can't seem to find the solution Say, I have a console application, #include <windows>
int main(int argc, char* argv[]) { return 0; } Now, how can I create a new window handle from main function? (Bonus points for OpenGL context) Cheers!
|
|
|
Logged
|
|
|
|
zacaj
|
|
« Reply #1 on: May 08, 2013, 07:51:14 AM » |
|
struct VideoProperties//todo multiple window support { uint x,y; uint w; ///< The width (in pixels) of the current display uint h; ///< The height (in pixels) of the current display uint bpp; ///< The Bits Per Pixel (NOT bytes) of the current display \warning IT IS NOT BYTES float aspect; ///< The Aspect Ratio of the current display (w/h) float inverseAspect; ///< Inverse of \a asoect (h/w) bool fullscreen; ///< Signifies whether the current display is fullscreen bool vsync; ///< Signifies whether the current display has V-Sync #ifdef USE_WIN HGLRC hrc; // Rendering context HDC hdc; // Device context HWND hwnd; // Window identifier HINSTANCE hInstance; #endif } videoProperties; int main(int argc,char **argv) { videoProperties.x=640; videoProperties.y=220; videoProperties.w=800; videoProperties.h=600; videoProperties.bpp=32; videoProperties.fullscreen=0; videoProperties.vsync=0; videoProperties.aspect=-1; videoProperties.inverseAspect=-1; vec2i originalSize(videoProperties.w,videoProperties.h); if(videoProperties.aspect==-1) videoProperties.aspect=(float)videoProperties.w/(float)videoProperties.h; if(videoProperties.inverseAspect==-1) videoProperties.inverseAspect=(float)videoProperties.h/(float)videoProperties.w;
VideoProperties &vp=videoProperties; vp.hInstance=GetModuleHandle(NULL); WNDCLASS windowClass; windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; windowClass.lpfnWndProc = (WNDPROC) WndProc; windowClass.cbClsExtra = 0; windowClass.cbWndExtra = 0; windowClass.hInstance = vp.hInstance; windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); windowClass.hbrBackground = NULL; windowClass.lpszMenuName = NULL; #ifdef MSVC windowClass.lpszClassName = L"Engine"; #else windowClass.lpszClassName = "Engine"; #endif
if (!RegisterClass(&windowClass)) { error("Could not register WNDCLASS!",0); return 1; } vp.hwnd = CreateWindowExW(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, L"Engine", L"Engine", WS_OVERLAPPEDWINDOW, vp.x, vp.y,vp.w, vp.h, NULL, NULL, vp.hInstance, NULL);
vp.hdc=GetDC(vp.hwnd); PIXELFORMATDESCRIPTOR pfd; // Create a new PIXELFORMATDESCRIPTOR (PFD) int depthBits=32; formatTry: memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our PFD pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the PFD to the size of the class pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels pfd.cColorBits = vp.bpp; // Give us 32 bits of color information (the higher, the more colors) pfd.cDepthBits = depthBits; // Give us 32 bits of depth information (the higher, the more depth levels) pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD
int nPixelFormat = ChoosePixelFormat(vp.hdc, &pfd); // Check if our PFD is valid and get a pixel format back if (nPixelFormat == 0) // If it fails { if(depthBits==8) { error("Could not create pixel format : %ix%i\n",vp.bpp,32); return 1; } warn("Could not create pixel format with %i depth bits\n",depthBits); depthBits-=8; goto formatTry;//OMG, a goto! } if(!SetPixelFormat(vp.hdc, nPixelFormat, &pfd)) // Try and set the pixel format based on our PFD { error("Could not set pixel format (%i bpp)\n",vp.bpp); return 1; } print("Created %ix%i pixel format\n",vp.bpp,depthBits); HGLRC OpenGLContext = wglCreateContext(vp.hdc); // Create an OpenGL 2.1 context for our device context wglMakeCurrent(vp.hdc, OpenGLContext); // Make the OpenGL 2.1 context current and active
ShowWindow(vp.hwnd,5); UpdateWindow(vp.hwnd); Just torn out of my engine without testing, but hopefully should help you out
|
|
|
Logged
|
My twitter: @zacaj_Well let's just take a look at this "getting started" page and see-- Download and install cmake
Noooooooo
|
|
|
kamac
|
|
« Reply #2 on: May 08, 2013, 12:09:30 PM » |
|
Hmm, seems like I can't see that window. Not sure where the error might lay. The code: #if defined(_WIN32) hInstance=GetModuleHandle(NULL); WNDCLASS windowClass; windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; windowClass.lpfnWndProc = (WNDPROC)WndProc; windowClass.cbClsExtra = 0; windowClass.cbWndExtra = 0; windowClass.hInstance = hInstance; windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); windowClass.hCursor = LoadCursor(NULL, IDC_ARROW); windowClass.hbrBackground = NULL; windowClass.lpszMenuName = NULL; #ifdef MSVC windowClass.lpszClassName = L"BlueKit"; #else windowClass.lpszClassName = "BlueKit"; #endif
if (!RegisterClass(&windowClass)) { MessageBox(NULL,L"Could not register WNDCLASS",L"ERROR",MB_OK); return; } hwnd = CreateWindow(L"BlueKit", s2ws(title).c_str(), WS_OVERLAPPEDWINDOW, x, y, width, height, NULL, NULL, hInstance, NULL);
hdc=GetDC(hwnd); PIXELFORMATDESCRIPTOR pfd; // Create a new PIXELFORMATDESCRIPTOR (PFD) int depthBits=32; formatTry: memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our PFD pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the PFD to the size of the class pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors) pfd.cDepthBits = depthBits; // Give us 32 bits of depth information (the higher, the more depth levels) pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD
int nPixelFormat = ChoosePixelFormat(hdc, &pfd); // Check if our PFD is valid and get a pixel format back if (nPixelFormat == 0) // If it fails { if(depthBits==8) { MessageBox(NULL,L"Could not create pixel format 32x32",L"ERROR",MB_OK); return; } fprintf(stderr,"Could not create pixel format with %i depth bits\n",depthBits); depthBits-=8; goto formatTry;//OMG, a goto! } if(!SetPixelFormat(hdc, nPixelFormat, &pfd)) // Try and set the pixel format based on our PFD { MessageBox(NULL,L"Could not set pixel format (32 bpp)",L"ERROR",MB_OK); return; } HGLRC OpenGLContext = wglCreateContext(hdc); // Create an OpenGL 2.1 context for our device context wglMakeCurrent(hdc, OpenGLContext); // Make the OpenGL 2.1 context current and active ShowWindow(hwnd,SW_SHOW); UpdateWindow(hwnd); #endif
|
|
|
Logged
|
|
|
|
zacaj
|
|
« Reply #3 on: May 08, 2013, 12:19:23 PM » |
|
Can I see your WndProc and main loop? I don't see anything wrong with the code you posted (although maybe I'm just missing it too)
|
|
|
Logged
|
My twitter: @zacaj_Well let's just take a look at this "getting started" page and see-- Download and install cmake
Noooooooo
|
|
|
kamac
|
|
« Reply #4 on: May 08, 2013, 12:23:59 PM » |
|
Sure. WndProc: LRESULT CALLBACK Window::WndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_DESTROY: PostQuitMessage(0); Window::isRunning = false; break;
default: return DefWindowProc(hwnd, msg, wParam, lParam); break; } return 0; } Main loop: int main(int argc, char* argv[]) { BlueKit::Window::Init(800,600,"BlueKit tests",0,BlueKit::Window::POS_CENTERED,0,0); while(BlueKit::Window::isRunning) { BlueKit::Window::SwapBuffers(); } return 0; }
|
|
|
Logged
|
|
|
|
zacaj
|
|
« Reply #5 on: May 08, 2013, 02:49:58 PM » |
|
I assume in SwapBuffers you're calling SwapBuffers(hdc)? Do you do this anywhere in the loop? MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { { TranslateMessage(&msg); DispatchMessage(&msg); } }
|
|
|
Logged
|
My twitter: @zacaj_Well let's just take a look at this "getting started" page and see-- Download and install cmake
Noooooooo
|
|
|
kamac
|
|
« Reply #6 on: May 08, 2013, 03:28:35 PM » |
|
I assume in SwapBuffers you're calling SwapBuffers(hdc)? Yes. Do you do this anywhere in the loop? [..] Aw, forgot to add that one. Now BlueKit::Window::SwapBuffers(); looks like this: MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } SwapBuffers(hdc); And the above is basically my main loop right now. Yet cannot see the window for some reason.
|
|
|
Logged
|
|
|
|
zacaj
|
|
« Reply #7 on: May 08, 2013, 04:01:39 PM » |
|
I'm stumped
|
|
|
Logged
|
My twitter: @zacaj_Well let's just take a look at this "getting started" page and see-- Download and install cmake
Noooooooo
|
|
|
Average Software
|
|
« Reply #8 on: May 08, 2013, 04:31:10 PM » |
|
If it helps, the source code to my project contains code to do all this. I will answer questions if you like.
|
|
|
Logged
|
What would John Carmack do?
|
|
|
powly
|
|
« Reply #9 on: May 08, 2013, 05:24:11 PM » |
|
pfd.nVersion = 1;
Else I'd just start dropping stuff, you seem to define everything in there and most of it isn't necessary.
Also, do you set that isRunning as true somewhere?
|
|
« Last Edit: May 08, 2013, 05:30:43 PM by powly »
|
Logged
|
|
|
|
kamac
|
|
« Reply #10 on: May 09, 2013, 12:04:23 AM » |
|
If it helps, the source code to my project contains code to do all this. I will answer questions if you like. I have read through window_main.h and window_main.c (or something similar) from under windows folder, but didn't spot any differences between what you do, and what zacaj does. (since I am using his code at the moment) pfd.nVersion = 1;
Else I'd just start dropping stuff, you seem to define everything in there and most of it isn't necessary.
Also, do you set that isRunning as true somewhere?
Adding pfd.nVersion didn't help either. Yep, isRunning is set to true on the end of window creation. I have also put a breakpoint inside my main loop to see if it's executed, and it is. I might just try dropping stuff as you mentioned, though, I am not sure if it can help here
|
|
|
Logged
|
|
|
|
Xienen
|
|
« Reply #11 on: May 09, 2013, 03:07:40 AM » |
|
Just read this on the bottom of the Microsoft page for the RegisterClass function: This function seems to rearrange the WndClass structure to a WndClassEx structure and eventually calls RegisterClassEx().
Missing to zero-out some unused structure members may lead to CreateWindowEx(), not RegisterClass(), to fail with some unexpected GetLastError() code. Try changing to WNDCLASSEX and RegisterClassEx. The only thing you actually need to add after you memset it is windowclass.cbSize = sizeof(WNDCLASSEX);
|
|
|
Logged
|
|
|
|
kamac
|
|
« Reply #12 on: May 09, 2013, 03:30:16 AM » |
|
That doesn't actually work.
Maybe I should've mentioned that window creation function is inside a static library? Because, when I copy that code and paste it into int main(..), it works. Weird?
|
|
|
Logged
|
|
|
|
soryy708
|
|
« Reply #13 on: May 09, 2013, 06:00:06 AM » |
|
Why not use SDL?
|
|
|
Logged
|
|
|
|
kamac
|
|
« Reply #14 on: May 09, 2013, 06:15:03 AM » |
|
Because when I'd want to port my library to something else than decent platforms, it starts to be much of a trouble.
|
|
|
Logged
|
|
|
|
Xienen
|
|
« Reply #15 on: May 09, 2013, 06:16:37 AM » |
|
That doesn't actually work.
Maybe I should've mentioned that window creation function is inside a static library? Because, when I copy that code and paste it into int main(..), it works. Weird?
I've run into that issue before. I believe it has something to do with the WinProc needing to be built in the executable rather than in a library...maybe? I can't remember
|
|
|
Logged
|
|
|
|
soryy708
|
|
« Reply #16 on: May 09, 2013, 06:31:59 AM » |
|
Uh... You're talking about portability but using win32? Hmm... Does not compute.
|
|
|
Logged
|
|
|
|
kamac
|
|
« Reply #17 on: May 09, 2013, 06:45:09 AM » |
|
Uh... You're talking about portability but using win32? Hmm... Does not compute.
Please, why does there always have to be one person who enters a thread and wants to know why I don't want to use something they'd prefer? And that happens to almost any technical thread on tigsource, but I have already made my choice, I considered alternatives like glfw, SFML, SDL and so forth, but I have picked this way for a reason. If you want to know so badly what that reason is, then I am happy to say that I want to: A) Get more comfortable with Win32 API B) Be less dependant on 3rd party libraries C) Create a framework on my own Also, You're talking about portability but using win32? Yes? #if defined(_WIN32) //.. win32 code #endif #if defined(__linux) //.. linux code #endif #if defined(__APPLE__) //.. apple code #endif That's what I am using. Seems quite portable to me. Alternatively, I could've make separate libraries for platforms of choice, but instead I prefer to have that all in once place, so I don't end up surrounded with libraries.
|
|
|
Logged
|
|
|
|
Xienen
|
|
« Reply #18 on: May 09, 2013, 08:42:44 AM » |
|
If you want to know so badly what that reason is, then I am happy to say that I want to: A) Get more comfortable with Win32 API B) Be less dependant on 3rd party libraries C) Create a framework on my own
...
That's what I am using. Seems quite portable to me. Alternatively, I could've make separate libraries for platforms of choice, but instead I prefer to have that all in once place, so I don't end up surrounded with libraries.
Hear hear! If you could be so kind, soryy, just let this one go. Some of us just prefer to build things ourselves to learn more about them even if it doesn't "make sense" to others.
|
|
|
Logged
|
|
|
|
Crimsontide
|
|
« Reply #19 on: May 09, 2013, 12:18:21 PM » |
|
I've run into that issue before. I believe it has something to do with the WinProc needing to be built in the executable rather than in a library...maybe? I can't remember
I've been able to put the WinProc function in a library and statically link it. Never tried with a dll and dynamic linkage though. Perhaps the library has different compiler options that don't mesh with the main program?
|
|
|
Logged
|
|
|
|
|