Opengl es 2.0 without egl on desktop (windows) - c

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.

Related

How can I access a graphics card's output directly?

Do graphics cards typically write their output to some place in memory which I can access? Do I have to use the driver? If so, can I use OpenGL?
I want to know if it's possible to "capture" the output of a VM on Linux which has direct access to a GPU, and is running Windows. Ideally, I could access the output from memory directly, without touching the GPU, since this code would be able to run on the Linux host.
The other option is to maybe write a Windows driver which reads the output of the GPU and writes it to some place in memory. Then, on the Linux side, a program can read this memory. This seems somewhat impossible, since I'm not really sure how to get a process on the host to share memory with a process on the guest.
Is it possible to do option 1 and simply read the output from memory?
I do not code under Linux but in Windows (you are running it in emulator anyway) you can use WinAPI to directly access canvas of any window or even desktop from 3th party App. Some GPU overlays could be problematic to catch (especially DirectX based) but I had no problems with mine GL/GLSL for now.
If you got access to App source you can use glReadPixels for image extraction from GL directly (but that works only for current GL based rendering).
Using glReadPixels
As mentioned this must be implemented directly in the targeted app so you need to have it source code or inject your code in the right place/time. I use for screenshoting this code:
void OpenGLscreen::screenshot(Graphics::TBitmap *bmp)
{
if (bmp==NULL) return;
int *dat=new int[xs*ys],x,y,a,*p;
if (dat==NULL) return;
bmp->HandleType=bmDIB;
bmp->PixelFormat=pf32bit;
if ((bmp->Width!=xs)||(bmp->Height!=ys)) bmp->SetSize(xs,ys);
if ((bmp->Width==xs)&&(bmp->Height==ys))
{
glReadPixels(0,0,xs,ys,GL_BGRA,GL_UNSIGNED_BYTE,dat);
glFinish();
for (a=0,y=ys-1;y>=0;y--)
for (p=(int*)bmp->ScanLine[y],x=0;x<xs;x++,a++)
p[x]=dat[a];
}
delete[] dat;
}
where xs,ys is OpenGL window resolution, you can ignore the whole bmp stuff (it is VCL bitmap I use to store screenshot) and also can ignore the for it just copy the image from buffer to bitmap. So the important stuff is just this:
int *dat=new int[xs*ys]; // each pixel is 32bit int
glReadPixels(0,0,xs,ys,GL_BGRA,GL_UNSIGNED_BYTE,dat);
glFinish();
You need to execute this code after the rendering is done otherwise you will obtain unfinished or empty buffer. I use it after redraw/repaint events. As mentioned before this will obtain only the GL rendered stuff so if your App combines GDI+OpenGL it is better to use the next approach.
WinAPI approach
To obtain Canvas image of any window I wrote this class:
//---------------------------------------------------------------------------
//--- screen capture ver: 1.00 ----------------------------------------------
//---------------------------------------------------------------------------
class scrcap
{
public:
HWND hnd,hnda;
TCanvas *scr;
Graphics::TBitmap *bmp;
int x0,y0,xs,ys;
scrcap()
{
hnd=NULL;
hnda=NULL;
scr=new TCanvas();
bmp=new Graphics::TBitmap;
#ifdef _mmap_h
mmap_new('scrc',scr,sizeof(TCanvas() ));
mmap_new('scrc',bmp,sizeof(Graphics::TBitmap));
#endif
if (bmp)
{
bmp->HandleType=bmDIB;
bmp->PixelFormat=pf32bit;
}
x0=0; y0=0; xs=1; ys=1;
hnd=GetDesktopWindow();
}
~scrcap()
{
#ifdef _mmap_h
mmap_del('scrc',scr);
mmap_del('scrc',bmp);
#endif
if (scr) delete scr; scr=NULL;
if (bmp) delete bmp; bmp=NULL;
}
void init(HWND _hnd=NULL)
{
RECT r;
if (scr==NULL) return;
if (bmp==NULL) return;
bmp->SetSize(1,1);
if (!IsWindow(_hnd)) _hnd=hnd;
scr->Handle=GetDC(_hnd);
hnda=_hnd;
resize();
}
void resize()
{
if (!IsWindow(hnda)) return;
RECT r;
// GetWindowRect(hnda,&r);
GetClientRect(hnda,&r);
x0=r.left; xs=r.right-x0;
y0=r.top; ys=r.bottom-y0;
bmp->SetSize(xs,ys);
xs=bmp->Width;
ys=bmp->Height;
}
void capture()
{
if (scr==NULL) return;
if (bmp==NULL) return;
bmp->Canvas->CopyRect(Rect(0,0,xs,ys),scr,TRect(x0,y0,x0+xs,y0+ys));
}
};
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
Again it uses VCL so rewrite bitmap bmp and canvas scr to your programing environment style. Also igneore the _mmap_h chunks of code they are just for debugging/tracing of memory pointers related to some nasty compiler bug I was facing at that time I wrote this.
The usage is simple:
// globals
scrcap cap;
// init
cap.init();
// on screenshot
cap.capture();
// here use cap.bmp
If you call cap.init() it will lock on the whole windows desktop. If you call cap.init(window_handle) it will lock on specific visual window/component instead. To obtain window handle from 3th app side see:
is ther a way an app can display a message without the use of messagebox API?
Sorry it is on SE/RE instead of here on SE/SO but My answer here covering this topic was deleted. I use this for video capture ... all of the animated GIFs in my answers where created by this code. Another example could be seen on the bottom of this answer of mine:
Image to ASCII art conversion
As you can see it works also for DirectX overlay with media player classic (even Windows PrintScreen function cant do it right). As I wrote I got no problems with this yet.
Beware visual stuff WinAPI calls MUST BE CALLED FROM APP MAIN THREAD (WNDPROC) otherwise serious problems could occur leading to random unrelated WinAPI calls exceptions anywhere in the App.

DirectX 11 Win7 versus Win8 difference in brightness/shader ambient lighting

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 )

What is the most performant way to render unmanaged video frames in WPF?

I'm using FFmpeg library to receive and decode H.264/MPEG-TS over UDP with minimal latency (something MediaElement can't handle).
On a dedicated FFmpeg thread, I'm pulling PixelFormats.Bgr32 video frames for display. I've already tried InteropBitmap:
_section = CreateFileMapping(INVALID_HANDLE_VALUE, IntPtr.Zero, PAGE_READWRITE, 0, size, null);
_buffer = MapViewOfFile(_section, FILE_MAP_ALL_ACCESS, 0, 0, size);
Dispatcher.Invoke((Action)delegate()
{
_interopBitmap = (InteropBitmap)Imaging.CreateBitmapSourceFromMemorySection(_section, width, height, PixelFormats.Bgr32, (int)size / height, 0);
this.Source = _interopBitmap;
});
And then per frame update:
Dispatcher.Invoke((Action)delegate()
{
_interopBitmap.Invalidate();
});
But performance is quite bad (skipping frames, high CPU usage etc).
I've also tried WriteableBitmap: FFmpeg is placing frames in _writeableBitmap.BackBuffer and per frame update:
Dispatcher.Invoke((Action)delegate()
{
_writeableBitmap.Lock();
});
try
{
ret = FFmpegInvoke.sws_scale(...);
}
finally
{
Dispatcher.Invoke((Action)delegate()
{
_writeableBitmap.AddDirtyRect(_rect);
_writeableBitmap.Unlock();
});
}
Experiencing almost the same performance issues (tested with various DispatcherPriority).
Any help will be greatly appreciated.
I know it is too late, but I write this answer for those folks who are struggling to solve this problem.
Recently, I have done a rendering project using InteropBitmap in which I was able to run about 16 media player components in a WPF window at the same time on a core i7 1.6 Ghz CPU +8Gb RAM Laptop, with 25fps.
Here are the tips I took for performance tweaking:
First of all, I did not let GC handle my video packets. I Allocated memory using Marshal.AllocateHGlobal wherever I needed to instantiate a video frame and Disposed using Marshal.FreeHGlobal as soon as I did the rendering.
Secondly, I created a dispatcher thread for each individual media player. For more information, read "https://blogs.msdn.microsoft.com/dwayneneed/2007/04/26/multithreaded-ui-hostvisual/".
Thirdly, for aspect ratio, and generally the resizing purposes, I used native EmguCV library. This library helped me a lot on performance rather than using bitmaps and overlays and etc.
I think these steps help everyone that needs to render manually using InteropBitmap or etc.

OpenCV Capture from external camera

I'm currently writing an real time application using OpenCV and in the following case:
I'm trying to capture an image from a HDV camera plugged in firewire 800.
I have tried to loop on index used on cvCaptureFromCam,
but no camera can't be found (except the webcam).
there is my code sample, it loop on index (escaping 0 cause it's the webcam's index) :
CvCapture* camera;
int index;
for (index = 1; index < 100; ++index) {
camera = cvCaptureFromCAM(index);
if (camera)
break;
}
if (!camera)
abort();
On any time it stops on the abort.
I'm compiling on OSX 10.7 and I have tested :
OpenCV 1.2 private framework
OpenCV 2.0 private framework (found here : OpenCV2.0.dmg)
OpenCV compiled by myself (ver. 2)
I know that the problem is knowned and there is a lot of discussion about this,
but I'm not able ti find any solution.
Does anyone have been in the same case ?
Regards.
To explicitly select firewire, perhaps you can try to add 300 to your index? At least in OpenCV 2.4, each type of camera is given a specific domain. For example, Video4Linux are given domain 200, so 200 is the first V4L camera, 201 is the second, etc. For Firewire, the domain is 300. If you specify an index less than 100, OpenCV just iterates through each of its domains in order, which may not be the order you expect. For example, it might find your webcam first, and never find the firewire camera. If this is not the issue, please accept my appologies.
index should start at 0 instead of 1.
If that doesn't work, maybe your camera is not supported by OpenCV. I suggest you check if it is in the compatibility list.

Capture window pixels regardless of its z-order

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.

Resources