How do I put my OpenGL app into fullscreen mode? [closed] - windows
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm new to OpenGL but I've written a small application that runs fine in a window. Now i'd like to run it fullscreen.
There is this from the FAQ, but it seems to require GLUT, which is not open source. What's a good method for putting an OpenGL app into fullscreen mode? On Windows XP for now, but I'll be porting to other platforms.
Maciek's answer should work. You just need the full source from the NeHe tutorial.
There is much more source involved in taking care of all the little details like resizing the Window to fullscreen, covering up the start bar. Here's the CreateGLWindow function from one of my apps (a near-copy of NeHe's method).
inline BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat; // Holds The Results After Searching For A Match
HINSTANCE hInstance; // Holds The Instance Of The Application
WNDCLASS wc; // Windows Class Structure
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
RECT WindowRect; // Grabs Rectangle Upper Left / Lower Right Values
WindowRect.left=(long)0; // Set Left Value To 0
WindowRect.right=(long)width; // Set Right Value To Requested Width
WindowRect.top=(long)0; // Set Top Value To 0
WindowRect.bottom=(long)height; // Set Bottom Value To Requested Height
SCREENWIDTH=width;
SCREENHEIGHT=height;
fullscreen=fullscreenflag; // Set The Global Fullscreen Flag
hInstance = GetModuleHandle(NULL); // Grab An Instance For Our Window
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; // Redraw On Size, And Own DC For Window.
wc.lpfnWndProc = (WNDPROC) WndProc; // WndProc Handles Messages
wc.cbClsExtra = 0; // No Extra Window Data
wc.cbWndExtra = 0; // No Extra Window Data
wc.hInstance = hInstance; // Set The Instance
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Load The Default Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Load The Arrow Pointer
wc.hbrBackground = NULL; // No Background Required For GL
wc.lpszMenuName = NULL; // We Don't Want A Menu
wc.lpszClassName = "OpenGL"; // Set The Class Name
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL,"Failed To Register The Window Class.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (fullscreen) // Attempt Fullscreen Mode?
{
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// If The Mode Fails, Offer Two Options. Quit Or Use Windowed Mode.
if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{
fullscreen=FALSE; // Windowed Mode Selected. Fullscreen = FALSE
}
else
{
// Pop Up A Message Box Letting User Know The Program Is Closing.
MessageBox(NULL,"Program Will Now Close.","ERROR",MB_OK|MB_ICONSTOP);
return FALSE; // Return FALSE
}
}
}
if (fullscreen) // Are We Still In Fullscreen Mode?
{
dwExStyle=WS_EX_APPWINDOW; // Window Extended Style
dwStyle=WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // Windows Style
ShowCursor(FALSE); // Hide Mouse Pointer
}
else
{
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // Windows Style
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
// Create The Window
if (!(hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
"OpenGL", // Class Name
title, // Window Title
dwStyle | // Defined Window Style
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN, // Required Window Style
0, 0, // Window Position
WindowRect.right-WindowRect.left, // Calculate Window Width
WindowRect.bottom-WindowRect.top, // Calculate Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL))) // Dont Pass Anything To WM_CREATE
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Window Creation Error.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
static PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
1, // Version Number
PFD_DRAW_TO_WINDOW | // Format Must Support Window
PFD_SUPPORT_OPENGL | // Format Must Support OpenGL
PFD_DOUBLEBUFFER, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
bits, // Select Our Color Depth
0, 0, 0, 0, 0, 0, // Color Bits Ignored
0, // No Alpha Buffer
0, // Shift Bit Ignored
0, // No Accumulation Buffer
0, 0, 0, 0, // Accumulation Bits Ignored
32, // 16Bit Z-Buffer (Depth Buffer)
0, // No Stencil Buffer
0, // No Auxiliary Buffer
PFD_MAIN_PLANE, // Main Drawing Layer
0, // Reserved
0, 0, 0 // Layer Masks Ignored
};
if (!(hDC=GetDC(hWnd))) // Did We Get A Device Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) // Did Windows Find A Matching Pixel Format?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if(!SetPixelFormat(hDC,PixelFormat,&pfd)) // Are We Able To Set The Pixel Format?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if (!(hRC=wglCreateContext(hDC))) // Are We Able To Get A Rendering Context?
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
if(!wglMakeCurrent(hDC,hRC)) // Try To Activate The Rendering Context
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
ShowWindow(hWnd,SW_SHOW); // Show The Window
SetForegroundWindow(hWnd); // Slightly Higher Priority
SetFocus(hWnd); // Sets Keyboard Focus To The Window
ReSizeGLScene(width, height); // Set Up Our Perspective GL Screen
if (!InitGL()) // Initialize Our Newly Created GL Window
{
KillGLWindow(); // Reset The Display
MessageBox(NULL,"Initialization Failed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
return TRUE; // Success
}
This is all included in NeHe Lesson 1.
I'm partial to SDL for OpenGL window mangament and context wrangling.
I'm assuming you're creating the OpenGL window the "hard way" (via win32)
the code below hails from NeHe, the link points to a tutorial containing OpenGL window creation with fullscreen support :
in case your compiler doesn't define CDS_FULLSCREEN, add :
#define CDS_FULLSCREEN 4
at the top of your app.
if (fullscreen)
{
DEVMODE dmScreenSettings; // Device Mode
memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); // Makes Sure Memory's Cleared
dmScreenSettings.dmSize=sizeof(dmScreenSettings); // Size Of The Devmode Structure
dmScreenSettings.dmPelsWidth = width; // Selected Screen Width
dmScreenSettings.dmPelsHeight = height; // Selected Screen Height
dmScreenSettings.dmBitsPerPel = bits; // Selected Bits Per Pixel
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
// Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar.
if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
{
// If The Mode Fails, Offer Two Options. Quit Or Run In A Window.
if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
{(...)
Here is how SDL does it (MS Windows):
// query desktop video settings
DEVMODE SDL_desktop_mode;
EnumDisplaySettings (NULL, ENUM_CURRENT_SETTINGS, &SDL_desktop_mode);
settings.dmBitsPerPel = video->format->BitsPerPixel;
settings.dmPelsWidth = width;
settings.dmPelsHeight = height;
settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
// make sure to use monitor frequency that works in fullscreen
if (width <= (int)SDL_desktop_mode.dmPelsWidth &&
height <= (int)SDL_desktop_mode.dmPelsHeight) {
settings.dmDisplayFrequency = SDL_desktop_mode.dmDisplayFrequency;
settings.dmFields |= DM_DISPLAYFREQUENCY;
}
changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
if (! changed && (settings.dmFields & DM_DISPLAYFREQUENCY)) {
settings.dmFields &= ~DM_DISPLAYFREQUENCY;
changed = (ChangeDisplaySettings(&settings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL);
}
What SDL does when you set fullscreen mode and your target resolution is not the desktop resolution is to make sure you are using the proper monitor frequency for fullscreen mode by simply telling the driver to apply the frequency that the desktop has been using (which runs in fullscreen, so its refresh rate will work with any resolution in fullscreen mode).
Related
Strange viewbox font sizing behaviour inside Canvas
https://jsfiddle.net/diegojsrw/od12s9b4/14/ c.font = "100vh sans-serif"; c.fillStyle = "white"; c.fillText(fps.toFixed(0), w/2, 0); Initially, the text's height seems fine. However, when I resize the window, the text doesn't resize together. The text is constantly drawn on canvas (using requestAnimationFrame). The text size is only re-adjusted when I switch to another tab then switch back to this tab. Any clues?
You are facing a webkit bug. Both latests Chrome and Safari are concerned. In the Canvas2D API, relative units/values should get computed at setting and this computed value will get saved and used. This means that your relative 100vw value will get computed to its corresponding value in absolute px unit. This is one of the reasons it is advised to always use absolute units from the canvas API (among others like tweaks in roundings etc.). But if you really want to use this unit, then you have to set it everytime it has changed, so you could go blindly and inside your loop just set ctx.font again before calling fillText(), but for performances, I would advise you use a dirty flag, that would get raised in the window's resize event, and only update the ctx.font property when this flag is raised. But this is only fine for browsers that do follow the specs... I have no real clue as to when webkit browsers will compute this value, as even resetting the font property to something else won't do, and even setting it to an other value (e.g switching between 20vh and 21vh) won't do either... So the only workaround I can see for now, is to actually compute yourself this value. For viewport size, that's not so hard (innerWidth / (100 / vw_val)), but even for other relative units, you can actually set this fontSize on the canvas directly and call getComputedStyle() on the canvas. let dirtySize = true; // this is our resize flag const ctx = canvas.getContext('2d'); let fontStyle = ' Arial, sans-serif'; anim(0); // the animation loop function anim(time) { // call the drawing methods draw(Math.round(time/1e2)); // lwoer the flags dirtySize = false; // do it again next frame requestAnimationFrame(anim); } function draw(txt) { // clear ctx.clearRect(0,0,canvas.width, canvas.height); // only if needed if(dirtySize) { // get the cpmputed style from our DOM element const fontSize = getComputedStyle(canvas).fontSize; // or could be // const fontSize = (innerWidth / (100 / 20)) + 'px'; ctx.font = fontSize + fontStyle; } // draw everytime ctx.fillText(txt, 0, 100); } // on window's resize event window.addEventListener('resize', evt => dirtySize = true, // raise our flag { passive: true } ); #canvas { font-size: 20vw; } <canvas id="canvas"></canvas>
Insertion mark drawn over drag image in Tree-View control
I am implementing a Tree-View control using Win32 API where an insertion mark is displayed during drag operations. The problem is that the insertion line is drawn over the drag image as shown in the screenshot below. (Note the line going over the document icon on the right.) What can I do to prevent that from happening? This is the code handling the WM_LBUTTONUP message: void TreeviewDlg_OnMouseMove(HWND hwndParent, int x, int y, UINT keyFlags) { if(TreeViewGlobals::g_fDragging) { HWND hwndTV = (HWND)GetWindowLongPtr(hwndParent, GWLP_USERDATA); // Tree-View control handle // convert the dialog coordinates to control coordinates POINT point; point.x = x; point.y = y; ClientToScreen(hwndParent, &point); ScreenToClient(hwndTV, &point); ImageList_DragShowNolock(FALSE); // turn off the dragged image // so the background can be refreshed // Find out if the pointer is on the item. If it is, put insert mark. TVHITTESTINFO tvht; tvht.pt.x = point; HTREEITEM htiTarget; // Handle to target item. if((htiTarget = TreeView_HitTest(hwndTV, &tvht)) != NULL) { TreeView_SetInsertMark(hwndTV, htiTarget, TRUE); } ImageList_DragShowNolock(TRUE); ImageList_DragMove(point.x, point.y); } }
IWebBrowser2 control does not resize
I have created a simple Win32 application that embeds the browser control. I handle WM_SIZE on the host window as follows: case WM_SIZE: RECT rc = { 0 }; GetClientRect(hwnd, &rc); ::MoveWindow(hWndChild, 0, 0, rc.right, rc.bottom, TRUE); return 0; I also handle WM_SIZE on the control window as follows: case WM_SIZE: ... IOleInPlaceObject* pl; ax->OleObject->QueryInterface(IID_IOleInPlaceObject, (void**)&pl); RECT r; GetClientRect(ax->Site.Window, &r); pl->SetObjectRects(&r, &r); pl->Release(); return 0; If my initial navigation is set to, say, http://www.microsoft.com, things work as expected. I can resize the host window which in turn resizes the browser control. However, when I navigate to https://login.live.com, the control just does not resize as shown in the following figure: Can someone please guide me on what is it that I am missing? Regards.
How to choose the right buffer to draw and stop it from swapping continuously
Please tell me if the question's vogue, I need the answe as soon as possible for more information about the problem you can refer to this. I just didn't understand how to manage buffers properly. A red rectangle drawn on 2D texture disappears right after being drawn Being in the last stages of customizing the class COpenGLControl: I have created two instances of the class in my MFC Dialog: whenever the extent of zoom is changed in the bigger window, it is drawn as a red rectangle on the smaller window. which is always in full extent mode. In order to stablish such a relation between two instances, I have used the concept of user defined messages and send the message to the parent of the class. The main trouble based on the information above: 1- when I pan in the bigger window (mean I cause the user defined message be sent rapidly and m_oglWindow2.DrawRectangleOnTopOfTexture() be called rapidly I see a track of red rectangles shown but immediately disappeared in the smaller window 2- CPU-usage immediately get's high when panning from 3% to 25% 3- In other navigation tasks liked Fixed zoom in,Fixed zoom out,Pan and etc a red rectangle flashes and then immediately disappears, I mean it seems that the red rectangle is there just when the control is in the function m_oglWindow2.DrawRectangleOnTopOfTexture() but I want the rectangle be there until the next call off m_oglWindow2.DrawRectangleOnTopOfTexture() 4- making calls to glDrawBuffer(GL_FRONT_AND_BACK) and glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) causes the texture in the smaller window to get off and on even if the mouse is idle I know the problem is most because of the lines glClear, glDrawBuffer, SwapBuffers in the following codes. But I don't know exactly how to solve void COpenGLControl::OnTimer(UINT nIDEvent) { wglMakeCurrent(hdc,hrc); switch (nIDEvent) { case 1: { // Clear color and depth buffer bits glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Draw OpenGL scene oglDrawScene(); // Swap buffers SwapBuffers(hdc); break; } default: break; } CWnd::OnTimer(nIDEvent); wglMakeCurrent(NULL, NULL); } void COpenGLControl::DrawRectangleOnTopOfTexture() { wglMakeCurrent(hdc, hrc); //glDrawBuffer(GL_FRONT_AND_BACK); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushAttrib(GL_ENABLE_BIT|GL_CURRENT_BIT); glDisable(target); glColor3f(1.0f,0.0f,0.0f); glBegin(GL_LINE_LOOP); glVertex2f(RectangleToDraw.at(0),RectangleToDraw.at(1)); glVertex2f(RectangleToDraw.at(0),RectangleToDraw.at(3)); glVertex2f(RectangleToDraw.at(2),RectangleToDraw.at(3)); glVertex2f(RectangleToDraw.at(2),RectangleToDraw.at(1)); glEnd(); glPopAttrib(); SwapBuffers(hdc); wglMakeCurrent(NULL, NULL); } void COpenGLControl::OnDraw(CDC *pDC) { // TODO: Camera controls wglMakeCurrent(hdc,hrc); glLoadIdentity(); gluLookAt(0,0,1,0,0,0,0,1,0); glTranslatef(m_fPosX, m_fPosY, 0.0f); glScalef(m_fZoom,m_fZoom,1.0); wglMakeCurrent(NULL, NULL); } Remember: OnDraw function is just called twice in the smaller window first when initializing the window and second when calling m_oglWindow2.ZoomToFullExtent() and then for each call of OnDraw in the bigger window, there's a call to the DrawRectangleOnTopOfTexture() in the smaller one but this function DrawRectangleOnTopOfTexture() is never called in the bigger window It'll be favor of you if: you correct my code introduce me an excellent tutorial on how to use buffers in multiple drawings that can not be done in a single function or a single thread (An excellent tutorial about buffers eg.color buffers and etc in opengl ------------------------------------------------------------------------------------------ ----------------------------------------------------------------------------------------- I just added explanations below to provide further information about how's the class is working if it's needed. If you think it's bothering viewers just edit it to remove which of the parts that you feel is not required. But please do help me. the oglInitialize sets initial parameters for the scene: void COpenGLControl::oglInitialize(void) { // Initial Setup: // static PIXELFORMATDESCRIPTOR pfd = { sizeof(PIXELFORMATDESCRIPTOR), 1, PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, PFD_TYPE_RGBA, 32, // bit depth 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, // z-buffer depth 8,0,PFD_MAIN_PLANE, 0, 0, 0, 0, }; // Get device context only once. hdc = GetDC()->m_hDC; // Pixel format. m_nPixelFormat = ChoosePixelFormat(hdc, &pfd); SetPixelFormat(hdc, m_nPixelFormat, &pfd); // Create the OpenGL Rendering Context. hrc = wglCreateContext(hdc); wglMakeCurrent(hdc, hrc); // Basic Setup: // // Set color to use when clearing the background. glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearDepth(1.0f); // Turn on backface culling glFrontFace(GL_CCW); glCullFace(GL_BACK); // Turn on depth testing glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); // Send draw request OnDraw(NULL); wglMakeCurrent(NULL, NULL); } example of a navigation task: PAN: void COpenGLControl::OnMouseMove(UINT nFlags, CPoint point) { // TODO: Add your message handler code here and/or call default if (WantToPan) { if (m_fLastX < 0.0f && m_fLastY < 0.0f) { m_fLastX = (float)point.x; m_fLastY = (float)point.y; } int diffX = (int)(point.x - m_fLastX); int diffY = (int)(point.y - m_fLastY); m_fLastX = (float)point.x; m_fLastY = (float)point.y; if (nFlags & MK_MBUTTON) { m_fPosX += (float)0.05f*m_fZoomInverse*diffX; m_fPosY -= (float)0.05f*m_fZoomInverse*diffY; } if (WantToSetViewRectangle) setViewRectangle(); OnDraw(NULL); } CWnd::OnMouseMove(nFlags, point); } the most important part: before calling OnDraw in each of the navigation functions if the client-programmer has set WantToSetViewRectangle as true means that he wants the view rectangle for the window to be calculated and calls setViewRectangle() which is as follows. It sends a message to the parent in case of an update for ViewRectangle: void COpenGLControl::setViewRectangle() { CWnd *pParentOfClass = CWnd::GetParent(); ViewRectangle.at(0) = -m_fPosX - oglWindowWidth*m_fZoomInverse/2; ViewRectangle.at(1) = -m_fPosY - oglWindowHeight*m_fZoomInverse/2; ViewRectangle.at(2) = -m_fPosX + oglWindowWidth*m_fZoomInverse/2; ViewRectangle.at(3) = -m_fPosY + oglWindowHeight*m_fZoomInverse/2; bool is_equal = ViewRectangle == LastViewRectangle; if (!is_equal) pParentOfClass ->SendMessage(WM_RECTANGLECHANGED,0,0); LastViewRectangle.at(0) = ViewRectangle.at(0); LastViewRectangle.at(1) = ViewRectangle.at(1); LastViewRectangle.at(2) = ViewRectangle.at(2); LastViewRectangle.at(3) = ViewRectangle.at(3); } this is how we use the class in the client code: MyOpenGLTestDlg.h two instances of class: COpenGLControl m_oglWindow; COpenGLControl m_oglWindow2; MyOpenGLTestDlg.cpp apply texture on the windows and set both of them to full extent in the OnInitDlg m_oglWindow.pImage = m_files.pRasterData; m_oglWindow.setImageWidthHeightType(m_files.RasterXSize,m_files.RasterYSize,m_files.eType); m_oglWindow.m_unpTimer = m_oglWindow.SetTimer(1, 1, 0); m_oglWindow2.pImage = m_files.pRasterData; m_oglWindow2.setImageWidthHeightType(m_files.RasterXSize,m_files.RasterYSize,m_files.eType); m_oglWindow2.m_unpTimer = m_oglWindow2.SetTimer(1, 20, 0); m_oglWindow2.ZoomToFullExtent(); m_oglWindow.ZoomToFullExtent(); want pan, zoomtool and setViewRectangle be active for the bigger window but not for the smaller one: m_oglWindow.WantToPan = true; m_oglWindow.WantToUseZoomTool = true; m_oglWindow.WantToSetViewRectangle = true; handling the user-defined message in the parent. exchange the ViewRectangle data to the smaller window and draw the red rectangle: LRESULT CMyOpenGLTestDlg::OnRectangleChanged(WPARAM wParam,LPARAM lParam) { m_oglWindow2.RectangleToDraw = m_oglWindow.ViewRectangle; m_oglWindow2.DrawRectangleOnTopOfTexture(); return 0; } Here's the full customized class if you're interested in downloading it and fix my problem.
The problem is that you're drawing on a timer and when your application receives a WM_PAINT message. MFC invokes your OnDraw (...) callback when it needs to repaint the window, you should move ALL of your drawing functionality into OnDraw (...) and call OnDraw (...) from your timer function. void COpenGLControl::OnTimer(UINT nIDEvent) { switch (nIDEvent) { case 1: { OnDraw (NULL); break; } default: break; } CWnd::OnTimer(nIDEvent); } void COpenGLControl::OnDraw(CDC *pDC) { // TODO: Camera controls wglMakeCurrent(hdc,hrc); // Clear color and depth buffer bits glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity (); gluLookAt (0,0,1,0,0,0,0,1,0); glTranslatef (m_fPosX, m_fPosY, 0.0f); glScalef (m_fZoom,m_fZoom,1.0); // Draw OpenGL scene oglDrawScene(); // Swap buffers SwapBuffers(hdc); wglMakeCurrent(NULL, NULL); } void COpenGLControl::DrawRectangleOnTopOfTexture() { glPushAttrib(GL_ENABLE_BIT|GL_CURRENT_BIT); glDisable(target); glColor3f(1.0f,0.0f,0.0f); glBegin(GL_LINE_LOOP); glVertex2f(RectangleToDraw.at(0),RectangleToDraw.at(1)); glVertex2f(RectangleToDraw.at(0),RectangleToDraw.at(3)); glVertex2f(RectangleToDraw.at(2),RectangleToDraw.at(3)); glVertex2f(RectangleToDraw.at(2),RectangleToDraw.at(1)); glEnd(); glPopAttrib(); } And only ever make calls to wglMakeCurrent (...) within OnDraw (...). This function is really meant for situations where you're rendering into multiple render contexts, or drawing using multiple threads.
draw simple rectangle in MFC Dialog-Based
I wrote this code to draw a simple rectangle in a dialog , I also added ON_WM_PAINT() to my message map. but it didnt show anything on dialog to me ! I really appreciate it if anyone could tell my mistakes in code: void Ctest4Dlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting // TODO: Add your message handler code here SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = 2; int y = 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); //I want to draw a rectangle dc.Rectangle(10,10,50,50); } else { CDialogEx::OnPaint(); } }
Looks like your paint code only runs when the window is iconic? Why are you doing that? Put it in the else block, after the call to CDialogEx::OnPaint().
Your first and biggest mistake is trying to draw directly in a dialog. While it is possible to do so, it's almost always a bad idea. A dialog should usually be treated as a container for controls.