I have following code:
void DrawGLScene(unsigned char *drawing_bytes, HDC hdc, int xWidth, int yWidth) {
if ((!xWidth) || (!yWidth)) return;
BOOL returnVal = wglMakeCurrent(hdc, hrc);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, xWidth, yWidth, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, drawing_bytes);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glViewport(0,0,xWidth,yWidth); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(25.0f,1.0f,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glDisable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-5.0f);
glBindTexture(GL_TEXTURE_2D, texture);
glColor4f(1.0, 1.0, 1.0, 1.0);
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.5f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.5f);
glEnd();
glSwapBuffers(hdc);
}
This code overwrites my buttons created earlier via
hInstallButton = CreateWindow(TEXT("button"), "",
WS_VISIBLE | WS_CHILD | BS_AUTOCHECKBOX,
137, 70, 13, 13,
hWnd, (HMENU) 1, GetModuleHandle(NULL), NULL);
The issue is the glSwapBuffers(), which hides the buttons for good.
This is generated by the PIXELFORMATDESCRIPTOR
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
0, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
24, // 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
16, // 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
};
How can I force a single buffer, or something to write the buttons to both buffers? I am at a good loss here, and don't know how to do it properly (except maybe recreate the buttons with each WM_PAINT call)?
Edit:
Tried with subwindow (see code), but it creates a second window, instead of embedding into the first window.
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd;
hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern
DWORD dwExStyle; // Window Extended Style
DWORD dwStyle; // Window Style
hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd) {
return FALSE;
}
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE | CS_OWNDC; // Window Extended Style
dwStyle=WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; // Windows Style
WNDCLASS wndClass;
wndClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wndClass.lpfnWndProc = WndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndClass.hbrBackground = CreateSolidBrush(BLACK_BRUSH);
wndClass.lpszMenuName = NULL;
wndClass.lpszClassName = "Test Window";
RegisterClass(&wndClass);
hWndOpenGL = CreateWindowEx( dwExStyle, // Extended Style For The Window
"Test Window", // Class Name
"Testy test", // Window Title
dwStyle, // Required Window Style
0, 0, // Window Position
800,
600,
hWnd, // Parent Window
NULL, // No Menu
hInstance, // Instance
NULL);
//CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
//CW_USEDEFAULT, 0, CW_USEDEFAULT-500, 0, hWnd, NULL, hInstance, NULL);
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
0, // Must Support Double Buffering
PFD_TYPE_RGBA, // Request An RGBA Format
24, // 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
16, // 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
};
hdcOpenGL=GetDC(hWndOpenGL);
GLuint PixelFormat; // Holds The Results After Searching For A Match
PixelFormat=ChoosePixelFormat(hdcOpenGL,&pfd);
SetPixelFormat(hdcOpenGL,PixelFormat,&pfd);
hrc=wglCreateContext(hdcOpenGL);
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
ShowWindow(hWndOpenGL, nCmdShow);
UpdateWindow(hWndOpenGL);
return TRUE;
}
I'm guessing that you created the buttons as childs of the OpenGL window. If you did this, well, then you actually did something, that's explicitly mentioned in the WGL and Win32 API documentation to break things .
The fix is simple: The OpenGL window should be a sibling to the buttons and have its very own DC: Create a own subwindow for OpenGL operations with the CS_OWNDC window class flag set and the WS_CLIPSIBLINGS | WS_CLIPCHILDREN window styles being set. Both the OpenGL subwindow and the buttons are created with the desired container window as parent.
That way the buttons will not get clobbered by OpenGL operations, even with a double buffered pixelformat.
Related
I was trying to create a basic window with opengl and win32 application in visual studio 2013.
Everything works fine except the window title and messages in messagebox are not showing English. My code is given below:
#include "stdafx.h"
#include "ThesisProject.h"
#define MAX_LOADSTRING 100
// ================================= Variable Region : All the global variables will be declared here with categorization =========================== //
TCHAR szTitle[MAX_LOADSTRING];
TCHAR szWindowClass[MAX_LOADSTRING];
HDC hDC = NULL; // Private GDI Device Context. GDI : http://en.wikipedia.org/wiki/Graphics_Device_Interface
HWND hWnd = NULL; // holds our window handle.
HINSTANCE hInstance; // holds the instance of the application
HGLRC hRC = NULL; // Permanent Rendering Context
bool keys[256]; // Array Used for the keyboard routine. this will help us to track multiple key press, like : "Ctrl + s"
bool active = TRUE; // window active flag. set to true by default.
bool fullscreen = TRUE; // fullscreen flag. set to true by default. indicates whether the screen should be windowed or fullscreen.
// ================================================================================================================================================== //
// ================================ Function prototype declaration region : all the function prototype declaration will go here. ====================== //
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // a call back function to process window action.
int InitGL(GLvoid); // this function is used for setting up opengl components.
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag); // creates the window.
int DrawGLScene(GLvoid); // this is where all the drawing goes.
GLvoid ReSizeGLScene(GLsizei width, GLsizei height); // this function is used to handle the properties when the window is resized when full screen mode is not used.
GLvoid KillGLWindow(GLvoid); // this function is called before closing the window.
// =================================================================================================================================================== //
// this function is the entry point of this project . what ever this program does, it starts from here.
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
MSG msg; // Windows Message Structure
BOOL done = FALSE; // Bool Variable To Exit Loop
// Create Our OpenGL Window
if (!CreateGLWindow("OpenGL Testing", 640, 480, 16, fullscreen))
{
return 0; // Quit If Window Was Not Created
}
while (!done) // Loop That Runs Until done=TRUE
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) // Is There A Message Waiting?
{
if (msg.message == WM_QUIT) // Have We Received A Quit Message?
{
done = TRUE; // If So done=TRUE
}
else // If Not, Deal With Window Messages
{
TranslateMessage(&msg); // Translate The Message
DispatchMessage(&msg); // Dispatch The Message
}
}
else // If There Are No Messages
{
// Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene()
if (active) // Program Active?
{
if (keys[VK_ESCAPE]) // Was ESC Pressed?
{
done = TRUE; // ESC Signalled A Quit
}
else // Not Time To Quit, Update Screen
{
DrawGLScene(); // Draw The Scene
SwapBuffers(hDC); // Swap Buffers (Double Buffering)
}
}
if (keys[VK_F1]) // Is F1 Being Pressed?
{
keys[VK_F1] = FALSE; // If So Make Key FALSE
KillGLWindow(); // Kill Our Current Window
fullscreen = !fullscreen; // Toggle Fullscreen / Windowed Mode
// Recreate Our OpenGL Window
if (!CreateGLWindow("Aqib", 640, 480, 16, fullscreen))
{
return 0; // Quit If Window Was Not Created
}
}
}
}
// Shutdown
KillGLWindow(); // Kill The Window
return (msg.wParam); // Exit The Program
}
// this function is used to initialize all the opengl components.
int InitGL(GLvoid){
glShadeModel(GL_SMOOTH); // enabling smooth shader
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // black background
glClearDepth(1.0f); // depth buffer setup
glEnable(GL_DEPTH_TEST); // enable depth testing
glDepthFunc(GL_LEQUAL); // the type of depth test to do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // really nice perspective calculations
return TRUE; // initialization went ok
}
// this function creates and registers the window to the OS.
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag){
GLuint PixelFormat; // Holds The Results After Searching For A Match
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
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 Move, 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 = (LPCWSTR)"OpenGLTesting"; // Set The Class Name
if (!RegisterClass(&wc)) // Attempt To Register The Window Class
{
MessageBox(NULL, (LPCWSTR)"Failed To Register The Window Class.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Exit And 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 Run In A Window.
fullscreen = FALSE;
}
}
if (fullscreen){ // Are We Still In Fullscreen Mode?
dwExStyle = WS_EX_APPWINDOW; // Window Extended Style
dwStyle = WS_POPUP; // Windows Style
ShowCursor(TRUE); // Hide Mouse Pointer
}
else{
dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle = WS_OVERLAPPEDWINDOW; // Windows Style
}
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
if (!(hWnd = CreateWindowEx(dwExStyle, // Extended Style For The Window
(LPCWSTR)"OpenGLTesting", // Class Name
(LPCWSTR)title, // Window Title
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN | // Required Window Style
dwStyle, // Selected Window Style
0, 0, // Window Position
WindowRect.right - WindowRect.left, // Calculate Adjusted Window Width
WindowRect.bottom - WindowRect.top, // Calculate Adjusted Window Height
NULL, // No Parent Window
NULL, // No Menu
hInstance, // Instance
NULL)))
{
KillGLWindow(); // Reset The Display
MessageBox(NULL, (LPCWSTR)"Window Creation Error.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
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
16, // 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, (LPCWSTR)"Can't Create A GL Device Context.", (LPCWSTR)"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, (LPCWSTR)"Can't Find A Suitable PixelFormat.", (LPCWSTR)"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, (LPCWSTR)"Can't Set The PixelFormat.", (LPCWSTR)"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, (LPCWSTR)"Can't Create A GL Rendering Context.", (LPCWSTR)"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, (LPCWSTR)"Can't Activate The GL Rendering Context.", (LPCWSTR)"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, (LPCWSTR)"Initialization Failed.", (LPCWSTR)"ERROR", MB_OK | MB_ICONEXCLAMATION);
return FALSE; // Return FALSE
}
return TRUE; // Success
}
// this function is used to draw objects in the scene.
int DrawGLScene(GLvoid){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
glTranslatef(-1.5f, 0.0f, -6.0f); // Move into space 6 units and -1.5 to the left
glColor3f(0.0f, 0.0f, 1.0f);
glBegin(GL_TRIANGLES); // Begin drawing triagle
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 1.0f, 0.0f); // Top
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glEnd(); // Finished Drawing The Triangle
glTranslatef(3.0f, 0.0f, 0.0f); // Move Right 3 Units
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS); // Draw A Quad
glColor3f(1.0f, 1.0f, 0.0f);
glVertex3f(-1.0f, 1.0f, 0.0f); // Top Left
glColor3f(0.0f, 1.0f, 1.0f);
glVertex3f(1.0f, 1.0f, 0.0f); // Top Right
glColor3f(1.0f, 0.0f, 1.0f);
glVertex3f(1.0f, -1.0f, 0.0f); // Bottom Right
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(-1.0f, -1.0f, 0.0f); // Bottom Left
glEnd(); // Done Drawing The Quad
return TRUE; // Everything Went OK
}
// this function resizes and reinitializes the property of the opengl window when window is resized.
GLvoid ReSizeGLScene(GLsizei width, GLsizei height){
if (height == 0){ // prevent a divide by zero
height = 1; // Making height equal one
}
glViewport(0, 0, width, height); // Resize the current viewport
glMatrixMode(GL_PROJECTION); // select the projection matrix
glLoadIdentity(); // reset the projection matrix
// Calculate theaspect ratio of the window
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW); // select the model view matrix
glLoadIdentity(); // reset the modelview matrix
}
// this function is called before closing the application to properly close the window.
GLvoid KillGLWindow(GLvoid)
{
if (fullscreen)
{
ChangeDisplaySettings(NULL, 0); // If so Switch back to the Desktop.
ShowCursor(TRUE); // Show the mouse pointer.
}
if (hRC)
{
if (!wglMakeCurrent(NULL, NULL))
{
MessageBox(NULL, (LPCWSTR)"Release of DC and RC Failed", (LPCWSTR)"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC)) // Are we able to delete the rendering context?
{
MessageBox(NULL, (LPCWSTR)"Release of Rendering Context Failed", (LPCWSTR)"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
}
hRC = NULL; // set rendering context to null.
}
if (hDC && !ReleaseDC(hWnd, hDC)) // Are We Able To Release The DC
{
MessageBox(NULL, (LPCWSTR)"Release Device Context Failed.", (LPCWSTR)"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
hDC = NULL; // Set DC To NULL
}
if (hWnd && !DestroyWindow(hWnd)) // Are We Able To Destroy The Window?
{
MessageBox(NULL, (LPCWSTR)"Could Not Release hWnd.", (LPCWSTR)"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
hWnd = NULL; // Set hWnd To NULL
}
if (!UnregisterClass((LPCWSTR)"OpenGL", hInstance)) // Are We Able To Unregister Class
{
MessageBox(NULL, (LPCWSTR)"Could Not Unregister Class.", (LPCWSTR)"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
hInstance = NULL; // Set hInstance To NULL
}
}
LRESULT CALLBACK WndProc(HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
switch (uMsg) // Check For Windows Messages
{
case WM_ACTIVATE: // Watch For Window Activate Message
{
if (!HIWORD(wParam)) // Check Minimization State
{
active = TRUE; // Program Is Active
}
else
{
active = FALSE; // Program Is No Longer Active
}
return 0; // Return To The Message Loop
}
case WM_SYSCOMMAND: // Intercept System Commands
{
switch (wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start?
case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
return 0; // Prevent From Happening
}
break; // Exit
}
case WM_CLOSE: // Did We Receive A Close Message?
{
PostQuitMessage(0); // Send A Quit Message
return 0; // Jump Back
}
case WM_KEYDOWN: // Is A Key Being Held Down?
{
keys[wParam] = TRUE; // If So, Mark It As TRUE
return 0; // Jump Back
}
case WM_KEYUP: // Has A Key Been Released?
{
keys[wParam] = FALSE; // If So, Mark It As FALSE
return 0; // Jump Back
}
case WM_SIZE: // Resize The OpenGL Window
{
ReSizeGLScene(LOWORD(lParam), HIWORD(lParam)); // LoWord=Width, HiWord=Height
return 0; // Jump Back
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
The problem you're most likely running into is, that the Windows APIs you use expect wide character strings, but the string literals you have in your source code are standard (narrow) characters. So for every 2 consecutive characters in your strings, Windows interprets it as a single wide character; which will very likely end up in some asian script if every two bytes of a wchar are nonzero.
Solution: Use the _TEXT(…) macro to surround your string literals, turning them into wide character strings.
I have a simple red rectangle rendered in a window, and I created an arcball in order to rotate it in any direction. I was following the code from NeHe's Arcball Rotation tutorial.
The problem is that once the rectangle is rendered and the left mouse button is clicked, it spins like a top in the window. The mouse click-drag-stop update happens every time the mouse is moved, which is the reason why it spins that way. I am not able to figure out a way to restrict the rotation only for the duration of the click-drag-stop. How do I restrict the rotation? I have been trying to debug this for about 4-5 days now with no luck.
I added the original Arcball.h and Arcball.cpp files to my project, with one change to to the header file; I simply created a default constructor for the Arcball_t class with this line -
ArcBall_t() {};
The only other changes from the original project are that I threw the Update() function call into my code:
// ==========================================================================================
// function declarations
#define GET_PROC_ADDRESS( str ) wglGetProcAddress( str )
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
void DrawOpenGLScene(HDC hDC);
void Update();
HGLRC SetUpOpenGLContext(HWND hWnd);
// ==========================================================================================
// Trackball declarations
const float PI2 = 2.0*3.1415926535f; // PI Squared
GLUquadricObj *quadratic;
Point2fT MousePt; // NEW: Current Mouse Point
bool isClicked = false; // NEW: Clicking The Mouse?
bool isRClicked = false; // NEW: Clicking The Right Mouse Button?
bool isDragging = false; // NEW: Dragging The Mouse?
Matrix4fT Transform = { 1.0f, 0.0f, 0.0f, 0.0f, // NEW: Final Transform
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f };
Matrix3fT LastRot = { 1.0f, 0.0f, 0.0f, // NEW: Last Rotation
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f };
Matrix3fT ThisRot = { 1.0f, 0.0f, 0.0f, // NEW: This Rotation
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f };
// ==========================================================================================
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
static char szClassName[] = "Myclass";
static char szTitle[]="A Simple Win32 API OpenGL Program";
WNDCLASS wc;
MSG msg;
HWND hWnd;
wc.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)GetStockObject (BLACK_BRUSH);
wc.lpszMenuName = NULL;
wc.lpszClassName = szClassName;
if (!RegisterClass (&wc))
return 0;
hWnd = CreateWindow(szClassName, szTitle,
WS_OVERLAPPEDWINDOW |
// NEED THESE for OpenGL calls to work!
WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
0, 0, 1024, 256,
NULL, NULL, hInstance, NULL);
ArcBall_t ArcBall(1024.0f, 256.0f); // NEW: ArcBall Instance
ShowWindow(hWnd, nCmdShow);
UpdateWindow( hWnd );
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
return(msg.wParam);
}
// ==========================================================================================
//*******************************************************
// This is the brain of the loop
// Checks for a new key press or mouse movement
// renders when something is detected
//*******************************************************
LRESULT CALLBACK WndProc( HWND hWnd, UINT msg,
WPARAM wParam, LPARAM lParam )
{
HDC hDC;
static HGLRC hRC; // Note this is STATIC!
PAINTSTRUCT ps;
switch (msg)
{
case WM_CREATE:
// Select a pixel format and create a rendering context
hRC = SetUpOpenGLContext(hWnd);
break;
case WM_PAINT:
// Draw the scene
// Get a DC, make RC current & associate it with this DC
hDC = BeginPaint(hWnd, &ps);
wglMakeCurrent(hDC, hRC);
DrawOpenGLScene(hDC); // Draw
// We're done with the RC, so deselect it
wglMakeCurrent(NULL, NULL);
EndPaint(hWnd, &ps);
break;
//*NEW* Mouse based messages for arcball
case WM_LBUTTONUP:
isClicked = false;
break;
case WM_RBUTTONUP:
isRClicked = false;
break;
case WM_LBUTTONDOWN:
isClicked = true;
break;
case WM_RBUTTONDOWN:
isRClicked = true;
break;
case WM_MOUSEMOVE:
MousePt.s.X = (GLfloat)LOWORD(lParam);
MousePt.s.Y = (GLfloat)HIWORD(lParam);
isClicked = (LOWORD(wParam) & MK_LBUTTON) ? true : false;
isRClicked = (LOWORD(wParam) & MK_RBUTTON) ? true : false;
Update();
RedrawWindow(hWnd, NULL, NULL, RDW_INTERNALPAINT);
break;
case WM_DESTROY:
// Clean up and terminate
wglDeleteContext(hRC);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, msg, wParam, lParam);
}
return (0);
}
// ==========================================================================================
//*******************************************************
// SetUpOpenGL sets the pixel format and a rendering
// context then returns the RC
//*******************************************************
HGLRC SetUpOpenGLContext(HWND hWnd)
{
static PIXELFORMATDESCRIPTOR pfd = {
sizeof (PIXELFORMATDESCRIPTOR), // strcut size
1, // Version number
PFD_DRAW_TO_WINDOW | // Flags, draw to a window,
PFD_SUPPORT_OPENGL | // use OpenGL
PFD_DOUBLEBUFFER, // Use a double buffer
PFD_TYPE_RGBA, // RGBA pixel values
32, // 24-bit color
0, 0, 0, // RGB bits & shift sizes.
0, 0, 0, // Don't care about them
0, 0, // No alpha buffer info
0, 0, 0, 0, 0, // No accumulation buffer
32, // 32-bit depth buffer
8, // No stencil buffer
0, // No auxiliary buffers
PFD_MAIN_PLANE, // Layer type
0, // Reserved (must be 0)
0, // No layer mask
0, // No visible mask
0 // No damage mask
};
int nMyPixelFormatID;
HDC hDC;
HGLRC hRC;
hDC = GetDC(hWnd);
nMyPixelFormatID = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, nMyPixelFormatID, &pfd);
hRC = wglCreateContext(hDC);
ReleaseDC(hWnd, hDC);
quadratic=gluNewQuadric(); // Create A Pointer To The Quadric Object
gluQuadricNormals(quadratic, GLU_SMOOTH); // Create Smooth Normals
gluQuadricTexture(quadratic, GL_TRUE); // Create Texture Coords
return hRC;
}
// ==========================================================================================
// simple test code - rectangle/triangle
void DrawOpenGLScene(HDC hDC)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_MODELVIEW );
glTranslatef(0.0f, 0.0f, 0.0f);
glColor3f(1.0, 0.0, 0.0); // drawing color
glBegin(GL_POLYGON); // define the rectangle
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
glMultMatrixf(Transform.M);
glFlush(); // force execution
SwapBuffers(hDC);
}
// ==========================================================================================
void Update () // Perform Motion Updates Here
{
ArcBall_t ArcBall;
if (isRClicked) // If Right Mouse Clicked, Reset All Rotations
{
Matrix3fSetIdentity(&LastRot); // Reset Rotation
Matrix3fSetIdentity(&ThisRot); // Reset Rotation
Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot); // Reset Rotation
}
if (!isDragging) // Not Dragging
{
if (isClicked) // First Click
{
isDragging = true; // Prepare For Dragging
LastRot = ThisRot; // Set Last Static Rotation To Last Dynamic One
ArcBall.click(&MousePt); // Update Start Vector And Prepare For Dragging
}
}
else
{
if (isClicked) // Still Clicked, So Still Dragging
{
Quat4fT ThisQuat;
ArcBall.drag(&MousePt, &ThisQuat); // Update End Vector And Get Rotation As Quaternion
Matrix3fSetRotationFromQuat4f(&ThisRot, &ThisQuat); // Convert Quaternion Into Matrix3fT
Matrix3fMulMatrix3f(&ThisRot, &LastRot); // Accumulate Last Rotation Into This One
Matrix4fSetRotationFromMatrix3f(&Transform, &ThisRot); // Set Our Final Transform's Rotation From This One
}
else // No Longer Dragging
isDragging = false;
}
}
EDIT: I fixed the issue with the uncontrollable scene rotation by inserting a check within the case WM_MOUSEMOVE: handler of the WndProc() routine. The check was: if(isClicked == true) { //code }, and that seemed to do the trick. It no longer spins like a top. However, I still do not have fine control over the rotation; it still spins like a top within the click-drag-release duration.
Assuming your arcball.drag and arcball.click functions are correct, the only problem with your code is that you are applying the rotation after you draw and your need to do it before.
Your Code:
glTranslatef(0.0f, 0.0f, 0.0f);
glColor3f(1.0, 0.0, 0.0); // drawing color
glBegin(GL_POLYGON); // define the rectangle
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
glMultMatrixf(Transform.M);
Try changing it to:
glTranslatef(0.0f, 0.0f, 0.0f);
glMultMatrixf(Transform.M);
glColor3f(1.0, 0.0, 0.0); // drawing color
glBegin(GL_POLYGON); // define the rectangle
glVertex2f(-0.5,-0.5);
glVertex2f(-0.5,0.5);
glVertex2f(0.5,0.5);
glVertex2f(0.5,-0.5);
glEnd();
Although, based on the code you have provided, I dont think your image should rotate at all BECAUSE you are applying the rotation after. I think more code might be needed to find your issue.
I'm trying to create a window that uses directx to draw opaque content on top of a transparent view (i.e. the desktop shows through). With DirectX11 I'm trying to do the following, but it's not making the background transparent. In fact, any opacity value I put in gives me the exact same results.
What I'm doing:
float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
deviceContext->ClearRenderTargetView(backBuffer, color);
Working repro code (main.cpp):
#include <Windows.h>
#include <windowsx.h>
#pragma comment (lib, "Winmm.lib")
#include <d3d11.h>
#pragma comment (lib, "d3d11.lib")
#include <d3dcompiler.h>
#pragma comment(lib, "D3DCompiler.lib")
#include <dwmapi.h>
#pragma comment (lib, "Dwmapi.lib")
// Globals
IDXGISwapChain *swapChain;
ID3D11Device *device;
ID3D11DeviceContext *deviceContext;
ID3D11RenderTargetView *backBuffer;
ID3D11InputLayout *inputLayout; // the pointer to the input layout
ID3D11VertexShader *vertexShader; // the pointer to the vertex shader
ID3D11PixelShader *pixelShader; // the pointer to the pixel shader
ID3D11Buffer *vertexBuffer; // the pointer to the vertex buffer
void InitializeDirectX(HWND hWnd);
void LoadTriangle();
struct Vertex {
float x, y, z;
float color[4];
};
// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
{
// close the application entirely
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
// Globals
const LPCWSTR ClassName = L"className";
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// the handle for the window, filled by a function
HWND hWnd;
// this struct holds information for the window class
WNDCLASSEX wc;
// Pick out window size
int windowHeight = 400;
int windowWidth = 400;
// clear out the window class for use
ZeroMemory(&wc, sizeof(WNDCLASSEX));
// fill in the struct with the needed information
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = ClassName;
// register the window class
RegisterClassEx(&wc);
// Window style
DWORD exStyle = WS_EX_LAYERED | WS_EX_TOPMOST;
DWORD style = WS_POPUP;
// create the window and use the result as the handle
hWnd = CreateWindowEx(
exStyle, // extended styles
ClassName, // name of the window class
L"TestOverlay", // title of the window
style, // window style
0, // x-position of the window
0, // y-position of the window
400, // width of the window
400, // height of the window
NULL, // we have no parent window, NULL
NULL, // we aren't using menus, NULL
hInstance, // application handle
NULL); // used with multiple windows, NULL
// display the window on the screen
ShowWindow(hWnd, nCmdShow);
SetWindowPos(hWnd,
HWND_TOPMOST,
0, 0,
windowWidth, windowHeight,
SWP_SHOWWINDOW);
// Show the window
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
// Make the window transparent
SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_LAYERED);
SetLayeredWindowAttributes(hWnd, RGB(0, 0, 0), 255, LWA_ALPHA | LWA_COLORKEY);
// NOTE: If I uncomment DwmExtendFrameIntoClientArea then it becomes transparent, otherwise its a black screen
MARGINS dwmMargin = { -1 };
//DwmExtendFrameIntoClientArea(hWnd, &dwmMargin);
// DirectX
InitializeDirectX(hWnd);
LoadTriangle();
// enter the main loop:
MSG msg;
BOOL gotMessage;
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT)
break;
// DirectX stuff
float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
deviceContext->ClearRenderTargetView(backBuffer, color);
// Draw triangle
UINT stride = sizeof(Vertex);
UINT offset = 0;
deviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &stride, &offset);
deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
deviceContext->Draw(3, 0);
swapChain->Present(0, 0);
}
}
return msg.wParam;
}
void InitializeDirectX(HWND hWnd)
{
// create a struct to hold information about the swap chain
DXGI_SWAP_CHAIN_DESC scd;
// clear out the struct for use
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
// fill the swap chain description struct
scd.BufferCount = 1; // one back buffer
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
scd.OutputWindow = hWnd; // the window to be used
scd.SampleDesc.Count = 4; // how many multisamples
scd.Windowed = TRUE; // windowed/full-screen mode
// create a device, device context and swap chain using the information in the scd struct
D3D11CreateDeviceAndSwapChain(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&scd,
&swapChain,
&device,
NULL,
&deviceContext);
// get the address of the back buffer
ID3D11Texture2D *pBackBuffer;
swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
// use the back buffer address to create the render target
device->CreateRenderTargetView(pBackBuffer, NULL, &backBuffer);
pBackBuffer->Release();
// set the render target as the back buffer
deviceContext->OMSetRenderTargets(1, &backBuffer, NULL);
// Set the viewport size
RECT cRect;
GetClientRect(hWnd, &cRect);
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = cRect.right - cRect.left;
viewport.Height = cRect.bottom - cRect.top;
deviceContext->RSSetViewports(1, &viewport);
// Initialize pipeline stuff
ID3D10Blob *VS, *PS;
// compile shader
D3DCompileFromFile(L"shaders.shader", 0, 0, "VShader", "vs_4_0", 0, 0, &VS, 0);
D3DCompileFromFile(L"shaders.shader", 0, 0, "PShader", "ps_4_0", 0, 0, &PS, 0);
// encapsulate both shaders into shader objects
device->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &vertexShader);
device->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pixelShader);
deviceContext->VSSetShader(vertexShader, 0, 0);
deviceContext->PSSetShader(pixelShader, 0, 0);
// create input layout object
D3D11_INPUT_ELEMENT_DESC ied[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
device->CreateInputLayout(ied, 2, VS->GetBufferPointer(), VS->GetBufferSize(), &inputLayout);
deviceContext->IASetInputLayout(inputLayout);
}
void LoadTriangle()
{
// create a triangle using the VERTEX struct
Vertex OurVertices[] =
{
{ 0.0f, 0.5f, 0.0f, { 1.0f, 0.0f, 0.0f, 1.0f } },
{ 0.45f, -0.5, 0.0f, { 0.0f, 1.0f, 0.0f, 1.0f } },
{ -0.45f, -0.5f, 0.0f, { 0.0f, 0.0f, 1.0f, 1.0f } }
};
// create the vertex buffer
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC; // write access access by CPU and GPU
bd.ByteWidth = sizeof(Vertex)* 3; // size is the VERTEX struct * 3
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; // use as a vertex buffer
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // allow CPU to write in buffer
device->CreateBuffer(&bd, NULL, &vertexBuffer); // create the buffer
// copy the vertices into the buffer
D3D11_MAPPED_SUBRESOURCE ms;
deviceContext->Map(vertexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer
memcpy(ms.pData, OurVertices, sizeof(OurVertices)); // copy the data
deviceContext->Unmap(vertexBuffer, NULL); // unmap the buffer
}
Shader file (shaders.shader):
struct VOut
{
float4 position : SV_POSITION;
float4 color : COLOR;
};
VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
VOut output;
output.position = position;
output.color = color;
return output;
}
float4 PShader(float4 position : SV_POSITION, float4 color : COLOR) : SV_TARGET
{
return color;
}
If you uncomment the DwmExtendFrameIntoClientArea call on line 119ish, then it gets the effect I'm looking for. I'm wondering if there's a way to get the same effect without the use of dwm (for reasons I won't go into).
Any ideas?
Edit: Added full source code of working example. Found out that if I make a call to DwmExtendFrameIntoClientArea, then I get the effect I want. But I'd still like to know if its possible to do it without using dwm apis.
You can't make a Window transparent with DirectX only, The following code only clear the background color to black.
float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
To achieve transparent effect of your window, you need to involve some win32 stuff, SetLayeredWindowAttributes is your choice.
// Show the window
ShowWindow( hWnd, SW_SHOWDEFAULT );
UpdateWindow( hWnd );
SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_LAYERED) ;
SetLayeredWindowAttributes(hWnd, RGB(0, 0, 0), 100, LWA_ALPHA);
UPDATE:
Workable code draw nothing but make the window transparent in green color.
#include <Windows.h>
#include <windowsx.h>
#pragma comment (lib, "Winmm.lib")
#include <d3d11.h>
#pragma comment (lib, "d3d11.lib")
#include <d3dcompiler.h>
#pragma comment(lib, "D3DCompiler.lib")
#include <dwmapi.h>
#pragma comment (lib, "Dwmapi.lib")
// Globals
IDXGISwapChain *swapChain;
ID3D11Device *device;
ID3D11DeviceContext *deviceContext;
ID3D11RenderTargetView *backBuffer;
void InitializeDirectX(HWND hWnd);
// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
{
// close the application entirely
PostQuitMessage(0);
return 0;
}
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
// Globals
const LPCWSTR ClassName = L"className";
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
// fill in the struct with the needed information
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = ClassName;
// register the window class
RegisterClassEx(&wc);
// create the window and use the result as the handle
HWND hWnd = CreateWindowEx(
NULL, // extended styles
ClassName, // name of the window class
L"TestOverlay", // title of the window
WS_OVERLAPPEDWINDOW, // window style
0, // x-position of the window
0, // y-position of the window
400, // width of the window
400, // height of the window
NULL, // we have no parent window, NULL
NULL, // we aren't using menus, NULL
hInstance, // application handle
NULL); // used with multiple windows, NULL
// display the window on the screen
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Make the window transparent
SetWindowLong(hWnd, GWL_EXSTYLE, WS_EX_LAYERED) ;
SetLayeredWindowAttributes(hWnd, RGB(0, 0, 0), 128, LWA_ALPHA);
// DirectX
InitializeDirectX(hWnd);
// enter the main loop:
MSG msg;
BOOL gotMessage;
while (TRUE)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
if (msg.message == WM_QUIT)
break;
// DirectX stuff
float color[4] = { 0.0f, 1.0f, 0.0f, 0.0f };
deviceContext->ClearRenderTargetView(backBuffer, color);
swapChain->Present(0, 0);
}
}
return msg.wParam;
}
void InitializeDirectX(HWND hWnd)
{
// create a struct to hold information about the swap chain
DXGI_SWAP_CHAIN_DESC scd;
// clear out the struct for use
ZeroMemory(&scd, sizeof(DXGI_SWAP_CHAIN_DESC));
// fill the swap chain description struct
scd.BufferCount = 1; // one back buffer
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // use 32-bit color
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; // how swap chain is to be used
scd.OutputWindow = hWnd; // the window to be used
scd.SampleDesc.Count = 4; // how many multisamples
scd.Windowed = TRUE; // windowed/full-screen mode
// create a device, device context and swap chain using the information in the scd struct
D3D11CreateDeviceAndSwapChain(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&scd,
&swapChain,
&device,
NULL,
&deviceContext);
// get the address of the back buffer
ID3D11Texture2D *pBackBuffer;
swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
// use the back buffer address to create the render target
device->CreateRenderTargetView(pBackBuffer, NULL, &backBuffer);
pBackBuffer->Release();
// set the render target as the back buffer
deviceContext->OMSetRenderTargets(1, &backBuffer, NULL);
// Set the viewport size
RECT cRect;
GetClientRect(hWnd, &cRect);
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = cRect.right - cRect.left;
viewport.Height = cRect.bottom - cRect.top;
deviceContext->RSSetViewports(1, &viewport);
}
I have a small framework which displays a texture in borderless screen window, but when I start it, the application is showing a busy mouse icon when I activate the OpenGL window, and I cannot seem to understand where it is coming from.
The following code is the complete solution (Visual Studio 2010) and should compile as is.
Unfortunately I don't even know where to start looking, thus I copied the complete code here.
BasicProject creates a random texture, and pipes that into the OpenGL window.
Can anyone see why the code is stuck into a busy window?
The OpenGL Callbacks are never reached, but I do not see why not.
BasicProject.cpp (entry point):
/** Sample Project for OpenGL-Display functionality
*
* Anton Roth, 2013
*/
#include "stdafx.h"
#include <conio.h>
#include <process.h>
#include <vector>
#include <Windows.h>
#include <cstdlib>
#include <ctime>
#include "OpenGL-Display.h"
void RunOpenGL(void* pParams);
bool applicationRunning = true;
HANDLE threadOGL;
int _tmain(int argc, _TCHAR* argv[]) {
OGD::OpenGLDisplay_Init(640, 480, 200, 200, 0, "First Display");
threadOGL = (HANDLE)_beginthread(RunOpenGL, 0, NULL);
while(!_kbhit()) {
Sleep(500);
}
applicationRunning = false;
WaitForSingleObject( threadOGL, 500 );
return 0;
}
void RunOpenGL(void* pParams) {
std::vector<char> texture;
texture.resize(640 * 480 * 3);
std::srand(time(0));
while(applicationRunning) {
for(int i = 0; i < 640 * 480 * 3; ++i) {
texture.at(i) = std::rand() % 255;
}
OGD::OpenGLDisplay_Wrapper(&texture.at(0), 640, 480, false, 24, 0);
int x, y;
OGD::OpenGLDisplay_MousePos(x, y, 0);
Sleep(300);
}
}
OpenGL-Display.h:
#ifndef __OPENGLDISPLAY
#define __OPENGLDISPLAY
#include <windows.h> // Header File For Windows
#include <stdio.h> // Header File For Standard Input/Output
#include <gl\gl.h> // Header File For The OpenGL32 Library
#include <gl\glu.h> // Header File For The GLu32 Library
#include <vector>
namespace OGD
{
class OpenGL_Display
{
public:
OpenGL_Display(int newId);
~OpenGL_Display();
void Init_Display(int width, int height, int posX, int posY, LPCSTR className);
void DrawNewImage(int width, int height, char* imageData, bool flip, int bpp);
void GetMouseCords(int& x, int& y);
int ID;
protected:
bool CreateGLWindow(char* title, int bits, int posX, int posY, LPCSTR className);
GLvoid ReSizeGLScene(GLsizei width, GLsizei height);
int LoadGLTextures();
int InitGL(GLvoid);
void UpdateGLBuffers(int width, int height, char* imageData, int bpp);
int DrawGLScene(bool flip);
GLvoid KillGLWindow(GLvoid);
HDC hDC; // Private GDI Device Context
static LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
HGLRC hRC; // Permanent Rendering Context
HWND hWnd; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
bool keys[256]; // Array Used For The Keyboard Routine
bool active; // Window Active Flag Set To TRUE By Default
bool fullscreen; // Fullscreen Flag Set To Fullscreen Mode By Default
bool g_bExitThread; // end thread
GLuint texture; // Bitmap image buffer
int g_iCounter; // Current buffer being grabbed to
bool g_GLdone; // Counter to make sure no unnecessary updates are made which cause CPU load
int xPos;
int yPos;
int xPos_right;
int yPos_right;
int width;
int height;
};
static std::vector<OGD::OpenGL_Display*> oglDisp;
void OpenGLDisplay_Wrapper(char* image, int width, int height, bool flip, int bpp, int ID);
void OpenGLDisplay_Init(int width, int height, int posX, int posY, int ID, LPCSTR className);
void OpenGLDisplay_MousePos(int&x, int&y, int ID);
};
#endif
OpenGL-Display.cpp:
/** Based on code by NeHe tutorials
Adapted to display live camera display with OpenGL
*/
#include "OpenGL-Display.h"
using namespace OGD;
OpenGL_Display::OpenGL_Display(int newId)
{
xPos = -1;
yPos = -1;
ID = newId;
width = 1;
height = 1;
}
OpenGL_Display::~OpenGL_Display()
{
KillGLWindow();
}
void OpenGL_Display::Init_Display(int newWidth, int newHeight, int posX, int posY, LPCSTR inputName)
{
width = newWidth;
height = newHeight;
className = inputName;
if (!CreateGLWindow((char*)className, 24, posX, posY, className))
{
throw;
}
}
LRESULT CALLBACK OpenGL_Display::WndProc( HWND hWnd, // Handle For This Window
UINT uMsg, // Message For This Window
WPARAM wParam, // Additional Message Information
LPARAM lParam) // Additional Message Information
{
switch (uMsg) // Check For Windows Messages
{
case WM_SYSCOMMAND: // Intercept System Commands
{
switch (wParam) // Check System Calls
{
case SC_SCREENSAVE: // Screensaver Trying To Start?
case SC_MONITORPOWER: // Monitor Trying To Enter Powersave?
return 0; // Prevent From Happening
}
break; // Exit
}
case WM_CLOSE: // Did We Receive A Close Message?
{
PostQuitMessage(0); // Send A Quit Message
return 0; // Jump Back
}
case WM_SIZE: // Resize The OpenGL Window
{
oglDisp.at(0)->ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); // LoWord=Width, HiWord=Height
return 0; // Jump Back
}
}
// Pass All Unhandled Messages To DefWindowProc
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}
bool OpenGL_Display::CreateGLWindow(char* title, int bits, int posX, int posY, LPCSTR className)
{
GLuint PixelFormat; // Holds The Results After Searching For A Match
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
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 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 = className; // Set The Class Name
RegisterClass(&wc); // Return FALSE
dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; // Window Extended Style
dwStyle=WS_VISIBLE | WS_POPUP | WS_CLIPSIBLINGS | WS_CLIPCHILDREN;; // Windows Style
AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle); // Adjust Window To True Requested Size
//HWND hwndC = GetConsoleWindow();
// Create The Window
hWnd=CreateWindowEx( dwExStyle, // Extended Style For The Window
className, // Class Name
title, // Window Title
//WS_OVERLAPPEDWINDOW,
dwStyle | // Defined Window Style
WS_CLIPSIBLINGS | // Required Window Style
WS_CLIPCHILDREN, // Required Window Style
posX, posY, // 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);
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
16, // 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
};
hDC=GetDC(hWnd);
PixelFormat=ChoosePixelFormat(hDC,&pfd);
SetPixelFormat(hDC,PixelFormat,&pfd);
hRC=wglCreateContext(hDC);
wglMakeCurrent(hDC,hRC);
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
InitGL();
return TRUE; // Success
}
int OpenGL_Display::LoadGLTextures() // Load Bitmaps And Convert To Textures
{
// Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit
glGenTextures(1, &texture); // Create The Texture
// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); // Minimizing filter, in case display is smaller image size
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); // Magnifying filter, in case display is smaller image size
return 1; // Return The Status
}
GLvoid OpenGL_Display::ReSizeGLScene(GLsizei newWidth, GLsizei newHeight) // Resize And Initialize The GL Window
{
width = newWidth;
height = newHeight;
}
int OpenGL_Display::InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
if (!LoadGLTextures()) // Jump To Texture Loading Routine
{
return FALSE; // If Texture Didn't Load Return FALSE
}
return TRUE; // Initialization Went OK
}
void OpenGL_Display::GetMouseCords(int& x, int& y) // All Setup For OpenGL Goes Here
{
x = xPos;
y = yPos;
}
void OpenGL_Display::UpdateGLBuffers(int width, int height, char* imageData, int bpp) {
glBindTexture(GL_TEXTURE_2D, texture);
switch(bpp) {
case 8: glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, imageData); break;
case 16: glTexImage2D(GL_TEXTURE_2D, 0, GL_INTENSITY, width, height, 0, GL_RED, GL_UNSIGNED_SHORT, imageData); break;
case 24: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData); break;
default: return;
}
GLenum mError = glGetError();
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
int OpenGL_Display::DrawGLScene(bool flip) // Here's Where We Do All The Drawing
{
if (height==0) // Prevent A Divide By Zero
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(25.0f,1.0f,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glDisable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
GLenum mError = glGetError();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View
glTranslatef(0.0f,0.0f,-5.0f);
mError = glGetError();
glBindTexture(GL_TEXTURE_2D, texture);
mError = glGetError();
glColor4f(1.0, 1.0, 1.0, 1.0);
mError = glGetError();
if(flip)
{
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.5f);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.5f);
glEnd();
mError = glGetError();
}
else
{
glBegin(GL_QUADS);
// Front Face
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 0.5f);
glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, -1.0f, 0.5f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 0.5f);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.5f);
glEnd();
mError = glGetError();
}
mError = glGetError();
return TRUE; // Keep Going
}
GLvoid OpenGL_Display::KillGLWindow(GLvoid) // Properly Kill The Window
{
if (fullscreen) // Are We In Fullscreen Mode?
{
ChangeDisplaySettings(NULL,0); // If So Switch Back To The Desktop
ShowCursor(TRUE); // Show Mouse Pointer
}
if (hRC) // Do We Have A Rendering Context?
{
wglMakeCurrent(NULL,NULL);
wglDeleteContext(hRC);
hRC=NULL; // Set RC To NULL
}
ReleaseDC(hWnd,hDC);
DestroyWindow(hWnd);
UnregisterClass("OpenGL_Display",hInstance);
}
void OpenGL_Display::DrawNewImage(int width, int height, char* imageData, bool flip, int bpp)
{
BOOL returnVal = wglMakeCurrent(hDC, hRC);
UpdateGLBuffers(width, height, imageData, bpp);
DrawGLScene(flip);
SwapBuffers(hDC);
wglMakeCurrent(NULL, NULL);
}
void OGD::OpenGLDisplay_Init(int width, int height, int posX, int posY, int ID, LPCSTR className)
{
for(unsigned int i = 0; i < oglDisp.size(); ++i) {
if(oglDisp.at(i)->ID == ID) {
return;
}
}
oglDisp.push_back(new OGD::OpenGL_Display(ID));
oglDisp.at(oglDisp.size()-1)->Init_Display(width, height, posX, posY, className); //by default this ID is latest
wglMakeCurrent(NULL, NULL);
GLenum mError = glGetError();
}
void OGD::OpenGLDisplay_Wrapper(char* image, int width, int height, bool flip, int bpp, int ID)
{
for(unsigned int i = 0; i < oglDisp.size(); ++i) {
if(oglDisp.at(i)->ID == ID) {
oglDisp.at(i)->DrawNewImage(width, height, image, flip, bpp);
return;
}
}
}
Even though your window is OpenGL-based, you should create a message loop and repeatedly call GetMessage, TranslateMessage and DispatchMessage. Handle WM_PAINT even though it doesn't need to draw anything. If you don't do this, Windows will think your application doesn't respond, and shows the busy cursor (or worse, shows the 'Application not responding' dialogue.)
Im trying to create a popup window with half transparency that renders stuff on itself with DirectX.
The problem is that background does not redraw itself only if rendering is enabled. Redraw happens only when updating (ie when I select a line in a text editor behind my popup window).
Magic begins when my window gets moved to the secondary monitor. Its all ok there. Transparency works perfectly, background redraws constantly. Also if popup steps out of display borders transparency begins to work. (Screenshots below.)
The OS is windows xp SP3 with DirectX 9.0c and NVIDIA graphics card with lastest drivers.
I also tested the program on Win Vista and Win 7 with several different videocards. Works perfectly.
Creating window
m_popup = new popup(__("pew!"), wxPoint(600, 330), wxSize(250, 250));
m_popup->Show(true);
m_popup->SetWindowStyle(wxSTAY_ON_TOP);
m_popup->SetTransparent(150);
SetTopWindow(m_popup);
Transparency code from wxWidgets (2.8.12)
bool wxTopLevelWindowMSW::SetTransparent(wxByte alpha)
{
typedef DWORD (WINAPI *PSETLAYEREDWINDOWATTR)(HWND, DWORD, BYTE, DWORD);
static PSETLAYEREDWINDOWATTR pSetLayeredWindowAttributes = NULL;
if ( pSetLayeredWindowAttributes == NULL )
{
wxDynamicLibrary dllUser32(_T("user32.dll"));
pSetLayeredWindowAttributes = (PSETLAYEREDWINDOWATTR)
dllUser32.GetSymbol(wxT("SetLayeredWindowAttributes"));
}
if ( pSetLayeredWindowAttributes == NULL )
return false;
LONG exstyle = GetWindowLong(GetHwnd(), GWL_EXSTYLE);
// if setting alpha to fully opaque then turn off the layered style
if (alpha == 255)
{
SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyle & ~WS_EX_LAYERED);
Refresh();
return true;
}
// Otherwise, set the layered style if needed and set the alpha value
if ((exstyle & WS_EX_LAYERED) == 0 )
SetWindowLong(GetHwnd(), GWL_EXSTYLE, exstyle | WS_EX_LAYERED);
// ^ this line seems to cause the problem
// (tried to make the window transparent manually without wxWidgets' help)
return pSetLayeredWindowAttributes(GetHwnd(), 0, (BYTE)alpha, LWA_ALPHA) != 0;
}
DirectX Init
m_d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8;
d3dpp.BackBufferWidth = g_size;
d3dpp.BackBufferHeight = g_size;
m_d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &m_d3ddev);
CUSTOMVERTEX vertices[] =
{
{ 320.0f, 50.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(150, 255, 150, 150), },
{ 520.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(150, 150, 255, 150), },
{ 120.0f, 400.0f, 0.5f, 1.0f, D3DCOLOR_ARGB(150, 150, 150, 255), },
};
m_d3ddev->CreateVertexBuffer(3*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
VOID* pVoid;
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
Rendering
if (m_render)
{
m_d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_ARGB(150, 150, 150, 200), 1.0f, 0);
m_d3ddev->BeginScene();
m_d3ddev->SetFVF(CUSTOMFVF);
m_d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
m_d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
m_d3ddev->EndScene();
m_d3ddev->Present(NULL, NULL, NULL, NULL);
}
Screenshots
Transparency fail: http://clip2net.com/s/5IHAyQ
Transparency is ok when popup is out of display borders: http://clip2net.com/s/5IHCI3
I also wanted to post a screenshot of how it works on the secondary monitor but I cant neither I can post images directly to SO because of rep. Just imagine that its just ok on it like it is on the secondary screenshot.
Thank you.
PARTIALLY SOLVED, see comments.