I use GLFW and GLEW; the problem is vsync is enabled by default, how can I shut it down?
Windows 10
Visual C++ 2019
OpenGL 3.0
Once you've made your GL context current via glfwMakeContextCurrent() you can use glfwSwapInterval(0) to request that vsync be disabled:
int main( int, char** )
{
GLFWwindow* window;
glfwInit();
window = glfwCreateWindow( 640, 480, "GLFW", NULL, NULL );
glfwMakeContextCurrent( window );
glfwSwapInterval( 0 );
...
Note that this is only a request, since your GL implementation may not support the underlying swap interval extension or vsync may be forced 'on' at the driver/OS level.
Related
I'm following a direct2d tutorial and when I compile the code I get an error that a function is obsolete and that I should replace it, I look for ways to replace the function with the solutions that visual studio gives me (before publishing in stackoverflow) but it doesn't work, or I don't know how to call them.
main.cpp
// Because the CreateWindow function takes its size in pixels,
// obtain the system DPI and use it to scale the window size.
FLOAT dpiX, dpiY;
// The factory returns the current system DPI. This is also the value it will use
// to create its own windows.
m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
// Create the window.
m_hwnd = CreateWindow(
L"D2DDemoApp",
L"Direct2D Demo App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<UINT>(ceil(640.f * dpiX / 96.f)),
static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
NULL,
NULL,
HINST_THISCOMPONENT,
this
);
error
1>------ Build started: Project: entt, Configuration: Debug x64 ------
1>Using triplet "x64-windows-static" from "C:\Users\Jule\vcpkg\installed\x64-windows-static\"
1>main.cpp
1>C:\Users\Jule\source\repos\entt\entt\main.cpp(154,27): error C4996: 'ID2D1Factory::GetDesktopDpi': Deprecated. Use DisplayInformation::LogicalDpi for Windows Store Apps or GetDpiForWindow for desktop apps.
1>Done building project "entt.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
tutorial: https://learn.microsoft.com/en-us/windows/win32/direct2d/direct2d-quickstart
I just went through this tutorial myself and ran into the same issue. The solution provided by #Julio Enrique in the comments is correct. However, I didn't realize at first he replaced both dpiX and dpiY with x, so it didn't work for me. As a result, I found an even simpler drop and replacement fix for this example tutorial. For others experiencing this issue, try the following fix:
// obtain the system DPI and use it to scale the window size.
FLOAT dpiX, dpiY;
// The following will return the current system DPI. This is the value used
// to create a window with the correct dimensions.
dpiX = (FLOAT) GetDpiForWindow (GetDesktopWindow ());
dpiY = dpiX;
// Create the window.
m_hwnd = CreateWindow(
L"D2DDemoApp",
L"Direct2D Demo App",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
static_cast<UINT>(ceil(640.f * dpiX / 96.f)),
static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
NULL,
NULL,
HINST_THISCOMPONENT,
this
);
hr = m_hwnd ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
ShowWindow(m_hwnd, SW_SHOWNORMAL);
UpdateWindow(m_hwnd);
}
Also pointed out by #Julio Enrique, make sure to link the required Direct2D library (i.e. d2d1.lib) either in the Visual Studio linker options or via the following pragma:
#pragma comment(lib, "d2d1.lib")
Going forward, in order to prevent others from experiencing this issue in the future when reading the posted tutorial documentation, I have submitted a Pull Request to fix the documentation on the Microsoft website.
I'm trying to embed video in desktop application using Linphone C API.
By default, if to use samples from tutorial during call video window appears in separate window.
Could you please tell me, how to insert this video in my desktop application?
All I found seems helpful in Linphone C API reference, function:
linphone_core_set_native_video_window_id
Description:
Set the native video window id where the video is to be displayed.
For MacOS, Linux, Windows: if not set or zero the core will create
its own window, unless the special id -1 is given.
Could it be helpful? How to use it?
Here is the function from linphone SDK to get window handle:
void *get_native_handle(GdkWindow *gdkw){
#ifdef GDK_WINDOWING_X11
return (void *)GDK_WINDOW_XID(gdkw);
#elif defined(WIN32)
return (void *)GDK_WINDOW_HWND(gdkw);
#elif defined(__APPLE__)
return (void *)gdk_quartz_window_get_nsview(gdkw);
#endif
g_warning("No way to get the native handle from gdk window");
return 0;
}
Here is few lines of code:
GtkWidget *video_window, *window;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
video_window = gtk_drawing_area_new();
unsigned long *videoID;
videoID = malloc(sizeof(unsigned long));
*videoID = get_native_handle(gtk_widget_get_window(video_window));
linphone_core_set_native_video_window_id(lc, *videoID);
Worked for me!
The problem shows on all Win8 systems, all brands, all types of desktop, laptop, all-in-one, and tablets (tested on nearly every system at BestBuy which there's a ton of them so I can't be the first person to see this.)
What is happening is shown in below image (note captions below each surface), where the rendering on Win8 is brighter than Win7 for native code and WinForm which is based off a windowed ID3D11Device/Context; and to make things worse; the rendering is darker via WPF and WPFs shared surface/texture features though using similar device/context. The actual rendering loop and shaders are identical. Win7/Vista render the same/ideal brightness via native type render target or WPF shared surface.
The DirectX 11 code was developed on Win7. It's very basic DX stuff and the shader is as simple a shader as possible; very similar to the most basic DirectX SDK examples.
Why is DX11 Win8 brightness not consistent with Win7? Gradients seem different too.
Why would Win8 WPF shared surface/texture create even more difference?
What is the best strategy to solve such rendering brightness differences?
I did end up answering, but welcome improvements or expand with related answers to brightness/lighting problems between win7 and win8 as searching the net for such topic shows little results.
After much work between me and MS, (MS wanted a repro without using DXUT even though I told them PNTriangles11 caused the issue and it was a wild goose chase.) I found it was related to EnumOutputs failing on Win8 (MS still to provide an official reason, I will update) and DXUT portions that call EnumOutputs fail resulting in the problematic section of code DXUTApplyDefaultDeviceSettings(DXUTDeviceSettings *modifySettings)
where...
modifySettings->d3d11.sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
should be changed to...
modifySettings->d3d11.sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
which resolves the issue and color is consistent between Win7 and Win8. MS pointed this out. Though I'd like to know why EnumOutputs is failing on Win8 and MS is likely the only one possible to answer this. EnumOutputs failed on every Win8 system at BestBuy, all types of systems.
As for another DXUT modification needed for Win8 compatibility, within DXUTChangeDevice, adding a test for nonzero hAdapterMonitor is likely wanted...
bool bNeedToResize = false;
if(hAdapterMonitor && DXUTGetIsWindowedFromDS( pNewDeviceSettings ) && !bKeepCurrentWindowSize )
{
UINT nClientWidth;
UINT nClientHeight;
if( ::IsIconic( DXUTGetHWNDDeviceWindowed() ) )
For completeness as relates to topic title, gamma correction information can be found at directx gamma correction and new windows 8 brightness control features for integrated displays win8 brightness control
I'm currently testing my C++,DX10 program (based on DXUT June 2010) on Windows 8,
And I'm having the same problems.
Here are additional changes/advice that I advice to do on DXUT:
1) do NOT use the arguments /width, /height, /windowed, /fullscreen in the strExtraCommandLineParams of DXUTInit
2) in DXUTGetMonitorInfo, s_pFnGetMonitorInfo( hMonitor, lpMonitorInfo ); returns FAIL on my system.
So I have replaced this line by something like:
BOOL success = s_pFnGetMonitorInfo( hMonitor, lpMonitorInfo );
//try to return the less wrong result
if ( !success )
{
RECT rcWork;
if ( lpMonitorInfo &&
( lpMonitorInfo->cbSize >= sizeof( MONITORINFO ) ) &&
SystemParametersInfoA( SPI_GETWORKAREA, 0, &rcWork, 0 )
)
{
lpMonitorInfo->rcMonitor.left = 0;
lpMonitorInfo->rcMonitor.top = 0;
lpMonitorInfo->rcMonitor.right = GetSystemMetrics( SM_CXSCREEN );
lpMonitorInfo->rcMonitor.bottom = GetSystemMetrics( SM_CYSCREEN );
lpMonitorInfo->rcWork = rcWork;
lpMonitorInfo->dwFlags = MONITORINFOF_PRIMARY;
return TRUE;
}
return FALSE;
}
else
{
return TRUE;
}
3) Concerning the brightness (gamma correction),
if have added:
if ( BackBufferFormat == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB )
{
return false;
}
in my callback IsD3D10DeviceAcceptable, so I ban every gamma correction device.
And now everything seems to work
(BTW, I'm not sure to understand your "hAdapterMonitor &&" modification, because it doesn't use directly this pointer, but maybe we don't have the same DXUT version )
I have a simple program on windows using visual studios 2008.
In my code i use gl functions i.e #include GLES2/gl2.h and also #include EGL/egl.h
In the code i use EGL for initialization for context. which is shown below.
It creates a window and CreateEGLContext.
I am not displaying my result on the screen. but storing in memory so i am not swapping display and surface buffer.
My issues you i want to remove egl.h from this code how is it possible.
Can anyone give me any idea. Thank you in advance
GLboolean CreateWindow1 ( ESContext *esContext, const char* title, GLint width, GLint height, GLuint flags )
{
GLuint attribList[] =
{
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_ALPHA_SIZE, (flags & ES_WINDOW_ALPHA) ? 8 : EGL_DONT_CARE,
EGL_DEPTH_SIZE, (flags & ES_WINDOW_DEPTH) ? 8 : EGL_DONT_CARE,
EGL_STENCIL_SIZE, (flags & ES_WINDOW_STENCIL) ? 8 : EGL_DONT_CARE,
EGL_SAMPLE_BUFFERS, (flags & ES_WINDOW_MULTISAMPLE) ? 1 : 0,
EGL_NONE
};
if ( esContext == NULL )
{
return GL_FALSE;
}
esContext->width = width;
esContext->height = height;
if ( !WinCreate ( esContext, title) )
{
return GL_FALSE;
}
if ( !CreateEGLContext ( esContext->hWnd, &esContext->eglDisplay, &esContext->eglContext, &esContext->eglSurface,
attribList) )
{
return GL_FALSE;
}
return GL_TRUE;
}
My answer is the solution i assume. or we can make our own framework if we want to or use any other framework :)
#Nicol Bolas: Thank you very much for your edits. I add OpenGL to my questions because someone doing OpenGL understand OpenGL ES as its a sub APL of OpenGL. I suggest you do better edits which would help. I lost ability to post question before of your multiple edits
EGL provides a “glue” layer between OpenGL ES 2.0 (and other Khronos graphics
APIs) and the native windowing system running on your computer, like the
X Window System common on GNU/Linux systems, Microsoft Windows, or
Mac OS X’s Quartz. Before EGL can determine what types of drawing surfaces,
or any other characteristics of the underlying system for that matter, it needs
to open a communications channel with the windowing system.
Because every windowing system has different semantics, EGL provides a
basic opaque type—the EGLDisplay—that encapsulates all of the system
dependencies for interfacing with the native windowing system. The first
operation that any application using EGL will need to do is create and initialize
a connection with the local EGL display.
I'm actually trying to read a specific pixel on a window which is hidden by others. I want to use the GetPixel function from GDI library but it seems it only works with the global device context. I can't read pixel from a specific window and I don't understand why..
I found this article which uses the PrintWindow function to copy a specific window content to a temporary device context which can be read. But I can't reproduce it.
EDIT
Thank you all my problem is solved :)
This script give you the RGB color of the pointer on the choosen window, even though the window is hidden. Remind that this program must be launch with admin privileges to get the pixels of processes launched with admin privileges.
#define STRICT
#define WINVER 0x0501
#define _WIN32_WINNT 0x0501
// 0x0501 for PrintWindow function
// You must be at least running Windows XP
// See http://msdn.microsoft.com/en-us/library/6sehtctf.aspx
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define WINDOW_LIST_LIMIT 32
#define WINDOW_NAME_LIMIT 1024
void FatalError(char* error)
{
printf("%s", error);
exit(-1);
}
HWND window_list[WINDOW_LIST_LIMIT];
unsigned int window_list_index = 0;
BOOL EnumWindowsProc(HWND window_handle, LPARAM param)
{
char window_title[WINDOW_NAME_LIMIT];
if(!IsWindowVisible(window_handle)) return TRUE;
RECT rectangle = {0};
GetWindowRect(window_handle, &rectangle);
if (IsRectEmpty(&rectangle)) return TRUE;
GetWindowText(window_handle, window_title, sizeof(window_title));
if(strlen(window_title) == 0) return TRUE;
if(!strcmp(window_title, "Program Manager")) return TRUE;
window_list[window_list_index] = window_handle;
window_list_index++;
printf("%u - %s\n", window_list_index, window_title);
if(window_list_index == WINDOW_LIST_LIMIT) return FALSE;
return TRUE;
}
int main(int argc, char** argv)
{
unsigned int i, input;
EnumWindows((WNDENUMPROC) EnumWindowsProc, (LPARAM) NULL);
printf("\nChoose a window: ");
scanf("%u", &input);
printf("\n");
if(input > window_list_index) FatalError("Bad choice..\n");
HDC window_dc = GetWindowDC(window_list[input - 1]), global_dc = GetDC(0), temp_dc;
if(!window_dc && !global_dc) FatalError("Fatal Error - Cannot get device context.\n");
POINT cursor, previous_cursor;
while(1)
{
temp_dc = CreateCompatibleDC(window_dc);
if(!temp_dc) FatalError("Fatal Error - Cannot create compatible device context.\n");
RECT window_rectangle;
GetWindowRect(window_list[input - 1], &window_rectangle);
HBITMAP bitmap = CreateCompatibleBitmap(window_dc,
window_rectangle.right - window_rectangle.left,
window_rectangle.bottom - window_rectangle.top);
if (bitmap)
{
SelectObject(temp_dc, bitmap);
PrintWindow(window_list[input - 1], temp_dc, 0);
DeleteObject(bitmap);
}
GetCursorPos(&cursor);
if(cursor.x != previous_cursor.x && cursor.y != previous_cursor.y)
{
COLORREF color = GetPixel(temp_dc, cursor.x - window_rectangle.left, cursor.y - window_rectangle.top);
int red = GetRValue(color);
int green = GetGValue(color);
int blue = GetBValue(color);
printf("\rRGB %02X%02X%02X", red, green, blue);
cursor = previous_cursor;
}
DeleteDC(temp_dc);
Sleep(50); // for lags
}
ReleaseDC(window_list[input - 1], window_dc);
return 0;
}
I've changed some things, now User32 isn't dynamically loaded.
It compiles with
gcc main.c -o main.exe -lGid32 -lUser32
Have a great day !
You are passing a process handle to GetDC. That's not right. Processes don't have device contexts, windows do. Remember a process can have many windows, or even none at all.
You need to get hold of the window handle, the HWND, for the window in question, and pass that to GetDC. I'd look to using FindWindow or EnumWindows to find your target top-level window.
Of course, there may be other problems with your code, but that's the one that jumps out at me.
HDC process_dc = GetDC(process_handle)
Well that's all kinds of wrong. GetDC accepts a window handle, not a process handle.
In order to find such errors, recompile with
#define STRICT
placed before your includes.
This is a bit of a confusing topic, so let's see if I can clarify a few things.
First things first: as both David and Ben have already answered, you're passing a process handle to the GetDC function, which is wrong. GetDC accepts a handle to a window (the HWND type), and it returns a device context (DC, the HDC type) corresponding to that window. You need to get that fixed before anything else will work.
Now, as the article you've read indicates, windows (assuming they've been correctly programmed) respond to the WM_PRINT or WM_PRINTCLIENT messages by rendering an image of themselves into the specified device context (HDC). This is a simple and effective way of capturing an "image" of a window, whether an overlapping window or the window of an individual control.
The rub comes in, as Hans mentioned in a comment, because handles to device contexts have process affinity, which means that the HDC you pass to the window in a separate process, into which it is supposed to render itself, will not be valid from that other process. Handles to device contexts cannot be passed across process boundaries. That's the primary reason that your code fails (or is going to fail, once you fix the handle type problems). The MSDN entry on GDI Objects makes this explicitly clear:
Handles to GDI objects are private to a process. That is, only the process that created the GDI object can use the object handle.
Fixing or getting around that is going to be a bit of an uphill battle. The only solution that I know of is to inject code into the other application's process that first creates a DC in memory, then sends the WM_PRINT or WM_PRINTCLIENT message to a window owned by that process to draw into that in-memory device context, and then transfers the resulted bitmap back to your own application. This is going to require that you implement some type of inter-process communication mechanism.
I've seen some anecdotal evidence that passing device context handles between processes via the WM_PRINT and WM_PRINTCLIENT messages "works", but it's unclear to me whether this is an artifact of the current implementation (and therefore subject to breaking in future versions of Windows), or if this is because Windows is actually handling the marshaling between processes. I haven't seen any documentation one way or the other. If this is a one-off project you're doing for fun or for a limited use, you might try it and get away with it. For other purposes, you probably want to investigate using IPC to really do this the right way.
Don't use GetDC for the DC to pass to PrintWindow. You need to create a compatible DC as you're doing (though you can pass it NULL to get a generic screen DC), then create a compatible bitmap the size of the window you're trying to capture and select it into the DC. Then pass that DC handle to PrintWindow.
Windows aren't required to respond properly to WM_PRINT or WM_PRINTCLIENT, so there may be some glitches even when you get this to work.