Transparent OpenGL Window draws weird - c++

So i have a transparent window with OpenGL 3.3 Context (Windows 8). Whenever I try to draw something it some why draws semi-transparent like this, but I want it opaque:
The fragment shader is
#version 330 core
uniform sampler2D Texture;
uniform sampler2D Texture2;
in vec2 fragTexcoord;
out vec4 color;
void main(void)
{
color = vec4(0.0, 1.0, 0.0, 1.0);
}
So it just HAS to be green, but it's not;
I've also tried to achieve transparency two ways: with MARGINS and DWM_BLURBEHIND:
DWM_BLURBEHIND bb = {0};
bb.dwFlags = DWM_BB_ENABLE;
bb.fEnable = true;
bb.fTransitionOnMaximized = 1;
bb.hRgnBlur = CreateRectRgn(-0, -0, 1000, 1000);
DwmEnableBlurBehindWindow(_hWnd, &bb);
SendMessage(_hWnd, WM_PAINT, NULL, NULL);
UpdateWindow(_hWnd);
// The second way
MARGINS margins;
margins.cxLeftWidth = 0;
margins.cyTopHeight = 0;
margins.cxRightWidth = _Options.width;
margins.cyBottomHeight = _Options.height;
DwmExtendFrameIntoClientArea(_hWnd, &margins);
But both ways act the same way.
Here I set pixel format:
PIXELFORMATDESCRIPTOR pfd;
int format;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_SUPPORT_COMPOSITION;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 24;
pfd.iLayerType = PFD_MAIN_PLANE;
The window has WS_EX_COMPOSITED and WS_POPUP styles. glClearColor is set to 0.0f, 0.0f, 0.0f, 0.0f.
Any ideas how can I fix this?

For those who may care: I finally found an answer.
So basically, I did those steps:
1) set the pixel format like this
int format;
memset(&pfd, 0, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_SUPPORT_COMPOSITION;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 32;
pfd.cDepthBits = 24;
pfd.cAlphaBits = 8;
pfd.cGreenBits = 8;
pfd.cRedBits = 8;
pfd.cStencilBits = 8;
pfd.cBlueBits = 8;
pfd.iLayerType = PFD_MAIN_PLANE;
2) then i set blurbehind like this:
DWM_BLURBEHIND bb = {0};
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
bb.fEnable = true;
bb.fTransitionOnMaximized = 1;
bb.hRgnBlur = CreateRectRgn(0, 0, -1, -1);
I think this tricked the blur 'cause the region is simply wrong.
So then it all looked just like I wanted
Hope this might help someone.

Just come to the same problem today. I was trying to make a transparent window by using DwmExtendFrameIntoClientArea then set window border to hidden. When doing that all color except pure white are rendered semi-transparent.
The cause was: I was using a 24-bit color format (red: 8, green: 8, blue: 8, alpha: 0)
DwmEnableBlurBehindWindow function
...
Remarks
The alpha values in the window are honored and the rendering atop the blur will use these alpha values. It is the application's responsibility to ensure that the alpha values of all pixels in the window are correct. ...
source (doc.microsoft.com)
It seems when using 24-bit color mode, the alpha value is treated as 0 (transparent) instead of 255 (opaque). So, just change to 32-bit color mode solves the problem.

Related

Activating Multisample on OpenGL Win32

I want to set up MSAA on an OpenGL context in win32 API. Everything is working fine, but the MSAA just doesn't want to activate. Here is my code for building the context:
void Display::CreateGLContext(HWND hWND) {
mHDC = GetDC(hWND); //get current windows device context
int nPixelFormat;
PIXELFORMATDESCRIPTOR pfd; // Create a new PIXELFORMATDESCRIPTOR (PFD)
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our PFD
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the PFD to the size of the class
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window
pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels
pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors)
pfd.cDepthBits = 16; // Give us 32 bits of depth information (the higher, the more depth levels)
pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD
/* Choose best matching format*/
nPixelFormat = ChoosePixelFormat(mHDC, &pfd);
/* Set the pixel format to the device context*/
SetPixelFormat(mHDC, nPixelFormat, &pfd);
HGLRC tempRC = wglCreateContext(mHDC);
wglMakeCurrent(mHDC, tempRC);
if (glewInit() != GLEW_OK) {
MessageBox(mHWND, "Eroare", "glew", MB_OK);
}
int nPixelFormat2;
BOOL bValidPixFormat;
UINT nMaxFormats = 1;
UINT nNumFormats;
float pfAttribFList[] = { 0, 0 };
int piAttribIList[] = {
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
WGL_COLOR_BITS_ARB, 32,
WGL_RED_BITS_ARB, 8,
WGL_GREEN_BITS_ARB, 8,
WGL_BLUE_BITS_ARB, 8,
WGL_ALPHA_BITS_ARB, 8,
WGL_DEPTH_BITS_ARB, 16,
WGL_STENCIL_BITS_ARB, 0,
WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
WGL_SAMPLES_ARB, 16,
0, 0 };
bValidPixFormat = wglChoosePixelFormatARB(mHDC, piAttribIList, pfAttribFList, nMaxFormats, &nPixelFormat2, &nNumFormats);
if (!bValidPixFormat)
{
MessageBox(NULL, "Invalid Pixel Format", "Error! (SetupWGLPixelFormat)", MB_OK);
}
SetPixelFormat(mHDC, nPixelFormat2, &pfd);
mGLRenderContext = wglCreateContext(mHDC);
wglMakeCurrent(mHDC, NULL);
wglDeleteContext(tempRC);
wglMakeCurrent(mHDC, mGLRenderContext);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
The code works fine, it is called after creating hWnd in the main class, not in WndProc on the WM_CREATE case... What can be wrong?
I see the part where you asked for 16 samples. But I don't see the part where you enabled GL_MULTISAMPLE. Without which, rendering to a multisampled buffer will act no differently from rendering to a single sampled one.
Also, I would advise you to use a framebuffer object for your multisample render target instead of the default framebuffer. Yes, it's nice that the default framebuffer can be resized by the window. But by using a framebuffer object, you can control when multisampling is resolved.
Also, it allows you to keep the driver's pesky control panel options from messing with your sample counts ;)
I have found the problem. Basically you can't call SetPixelFormat on the same window as this article mentions: https://www.khronos.org/opengl/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation
The solution is basically to create a dummy window(not visible) enable opengl and delete it. I have copied the code from here and it worked for me Create Modern OpenGL context using WGL?

Should I use Direct3D or just Windows GDI for a fancy/high-perf Win32 app UI? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Looking for the right general approach for making a UI really snappy.
I'm thinking of developing a UI tool that might go beyond just some "in house" tool. It would involve elaborate and custom 2d elements and would need to support fast scrolling of a big virtual surface, which would likely entail redrawing tons of custom things really quickly.
I've done some GDI programming back when XP was new, and I ran into some perf issues with lots of full screen blitting (it was a slow computer anyway). I understand GDI has some degree of acceleration, but I have difficulty ascertaining what exactly I can expect to be accelerated here.
I've only used Direct3D in games. Is it reasonable to make D3D to power a windowed GUI application? Also, if I use D3D, do I have to do everything from scratch, or can I make some kind of GDI/D3D hybrid, for example, using Direct3D calls inside WM_PAINT or something, in order to leverage some Win32 stuff like menu bars or listboxes side-by-side with a panel full of D3D rendered stuff? Does anyone have an example of mixing D3D with Win32 gui junk? Or is this not really the right approach?
What do programs like AutoCad or 3ds Max or Photoshop, or other major Win32 applications with similarly elaborate UI's do?
If your GUI involves 3D manipulation of 3D scenes, Direct3D or OpenGL would probably be a win. If you are just trying to give your GUI a "non-boring" look where the controls are stylized and drawn with alpha blended bitmaps and so-on, then you're best sticking to the traditional windowing system (i.e. GDI) as the bottom-most rendering layer. However, the easiest way to achieve such a "look and feel" is to use a higher-level toolkit like wxWidgets or Qt in order to achieve the theming and customization that will make your GUI look "modern" and not like a boring corporate application.
Another option is to use XAML/WPF from a native application and use the tools that are available for creating XAML-based GUIs like Microsoft's Expression. I haven't explored that myself, but it should be feasible using the technique from this article in the March, 2013 issue of MSDN Magazine.
Simple C style D3D9 app code (display mesh).
////////////////////////////////////////////////////////////////
// Defines main Direct3D rendering funcions
#include <windows.h>
#include <mmsystem.h>
#include <d3d9.h>
#include "d3dx9.h"
#include "cube_prim.h"
#ifndef __D3D_RENDERER_H__
#define __D3D_RENDERER_H__
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9.lib")
#pragma comment(lib,"winmm.lib")
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
LPDIRECT3D9 pDirect3D = NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL;
LPDIRECT3DVERTEXBUFFER9 pDirect3DVertexBuffer = NULL;
LPDIRECT3DINDEXBUFFER9 pDirect3DIndexBuffer = NULL;
LPDIRECT3DTEXTURE9 pDirect3DTexture01 = NULL;
LPDIRECT3DTEXTURE9 pDirect3DTexture02 = NULL;
LPD3DXMESH pD3DXMesh = NULL;
D3DMATERIAL9* pDirect3DMaterial = NULL;
LPDIRECT3DTEXTURE9* pDirect3DTexture = NULL;
DWORD Subsets = 0;
FLOAT XRot = 0.0f;
FLOAT YRot = 0.0f;
HRESULT InitializeD3D(HWND hWnd)
{
D3DDISPLAYMODE dispMode;
D3DPRESENT_PARAMETERS parameters;
pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
if (pDirect3D == NULL)
return E_FAIL;
if (FAILED(pDirect3D->GetAdapterDisplayMode(
D3DADAPTER_DEFAULT,&dispMode)))
return E_FAIL;
ZeroMemory(&parameters,sizeof(D3DPRESENT_PARAMETERS));
parameters.Windowed = FALSE;
parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
parameters.BackBufferFormat = dispMode.Format;
parameters.BackBufferWidth = dispMode.Width;
parameters.BackBufferHeight = dispMode.Height;
parameters.BackBufferCount = 2;
parameters.EnableAutoDepthStencil = TRUE;
parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
if (FAILED(pDirect3D->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,
&parameters,&pDirect3DDevice)))
return E_FAIL;
pDirect3DDevice->SetRenderState(D3DRS_LIGHTING,TRUE);
pDirect3DDevice->SetRenderState(D3DRS_AMBIENT,RGB(180,180,180));
pDirect3DDevice->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW);
pDirect3DDevice->SetRenderState(D3DRS_ZENABLE,TRUE);
//pDirect3DDevice->SetRenderState(D3DRS_AMBIENTMATERIALSOURCE,D3DMCS_COLOR2);
//pDirect3DDevice->SetRenderState(D3DRS_DIFFUSEMATERIALSOURCE,D3DMCS_COLOR2);
pDirect3DDevice->SetRenderState(D3DRS_SPECULARENABLE,TRUE);
return S_OK;
}
HRESULT InitializeD3DBufferObject(void)
{
VOID* pVertices = NULL;
VOID* pIndicies = NULL;
if (pDirect3DDevice != NULL)
{
if (FAILED(pDirect3DDevice->CreateVertexBuffer(
sizeof(vertices),0,D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT,&pDirect3DVertexBuffer,NULL)))
return E_FAIL;
if (FAILED(pDirect3DVertexBuffer->Lock(0,
sizeof(vertices),(void**)&pVertices,NULL)))
return E_FAIL;
memcpy(pVertices,vertices,sizeof(vertices));
pDirect3DVertexBuffer->Unlock();
if (FAILED(pDirect3DDevice->CreateIndexBuffer(
sizeof(indices),0,D3DFMT_INDEX32,D3DPOOL_DEFAULT,
&pDirect3DIndexBuffer,NULL)))
return E_FAIL;
if (FAILED(pDirect3DIndexBuffer->Lock(0,
sizeof(indices),(void**)&pIndicies,NULL)))
return E_FAIL;
memcpy(pIndicies,indices,sizeof(indices));
pDirect3DIndexBuffer->Unlock();
if (FAILED(D3DXCreateTextureFromFile(pDirect3DDevice,
_T("wood.tga"),&pDirect3DTexture01)))
return E_FAIL;
if (FAILED(D3DXCreateTextureFromFile(pDirect3DDevice,
_T("stripes.tga"),&pDirect3DTexture02)))
return E_FAIL;
return S_OK;
}
else
return E_FAIL;
}
HRESULT InitialMesh(void)
{
LPD3DXBUFFER pMeshObj = NULL;
LPD3DXMATERIAL pMaterial = NULL;
char buffer[255];
if (pDirect3DDevice != NULL)
{
if (FAILED(D3DXLoadMeshFromX(_T("Dwarf\\Dwarf.x"),
D3DXMESH_SYSTEMMEM,
pDirect3DDevice,
NULL,
&pMeshObj,
NULL,
&Subsets,
&pD3DXMesh)))
return E_FAIL;
pMaterial = (D3DXMATERIAL*)pMeshObj->GetBufferPointer();
pDirect3DMaterial = new D3DMATERIAL9[Subsets];
pDirect3DTexture = new LPDIRECT3DTEXTURE9[Subsets];
for (INT i = 0; i < Subsets; i++)
{
pDirect3DMaterial[i] = pMaterial[i].MatD3D;
sprintf(buffer,"Dwarf\\");
strcat(buffer,pMaterial[i].pTextureFilename);
if (FAILED(D3DXCreateTextureFromFileA(
pDirect3DDevice,buffer,&pDirect3DTexture[i])))
return E_FAIL;
}
pMeshObj->Release();
return S_OK;
}
else
return E_FAIL;
}
VOID ChangeSize(INT cx,INT cy)
{
D3DXMATRIX projMatrix;
if (pDirect3DDevice != NULL)
{
if (cy == 0)
cy = 1;
FLOAT aspectRatio = static_cast<FLOAT>(cx) /
static_cast<FLOAT>(cy);
D3DXMatrixPerspectiveFovLH(&projMatrix,45.0f,
aspectRatio,1.0f,150.0f);
pDirect3DDevice->SetTransform(D3DTS_PROJECTION,&projMatrix);
}
}
VOID RotateScene(void)
{
if (GetAsyncKeyState(VK_ESCAPE))
exit(0);
if (GetAsyncKeyState(VK_UP))
XRot -= 0.1f;
if (GetAsyncKeyState(VK_DOWN))
XRot += 0.1f;
if (GetAsyncKeyState(VK_LEFT))
YRot -= 0.1f;
if (GetAsyncKeyState(VK_RIGHT))
YRot += 0.1f;
}
VOID RenderScene(void)
{
D3DXMATRIX worldMatrix;
D3DMATERIAL9 material;
D3DLIGHT9 light;
D3DCAPS9 caps;
D3DCOLORVALUE ambientLight = { 0.0f, 0.0f, 0.0f, 1.0f };
D3DCOLORVALUE diffuseLight = { 0.7f, 0.7f, 0.7f, 1.0f };
D3DCOLORVALUE specularLight = { 1.0f, 1.0f, 1.0f, 1.0f };
D3DCOLORVALUE materialColor = { 1.0f, 1.0f, 1.0f, 1.0f };
ZeroMemory(&material,sizeof(D3DMATERIAL9));
material.Ambient = materialColor;
material.Diffuse = materialColor;
material.Specular = specularLight;
material.Power = 20.0f;
ZeroMemory(&light,sizeof(D3DLIGHT9));
light.Ambient = ambientLight;
light.Diffuse = diffuseLight;
light.Specular = specularLight;
light.Range = 300.0f;
light.Position = D3DXVECTOR3(-30,150,-10);
light.Type = D3DLIGHT_POINT;
light.Attenuation0 = 1.0f;
if (pDirect3DDevice != NULL)
{
D3DXMatrixIdentity(&worldMatrix);
pDirect3DDevice->SetTransform(D3DTS_WORLD,&worldMatrix);
D3DXMatrixTranslation(&worldMatrix,0.0f,0.0f,4.0f);
pDirect3DDevice->MultiplyTransform(D3DTS_WORLD,&worldMatrix);
D3DXMatrixRotationX(&worldMatrix,XRot);
pDirect3DDevice->MultiplyTransform(D3DTS_WORLD,&worldMatrix);
D3DXMatrixRotationY(&worldMatrix,YRot);
pDirect3DDevice->MultiplyTransform(D3DTS_WORLD,&worldMatrix);
pDirect3DDevice->Clear(0,0,D3DCLEAR_TARGET |
D3DCLEAR_ZBUFFER,D3DCOLOR_ARGB(255,0,0,0),1.0f,0);
pDirect3DDevice->SetMaterial(&material);
pDirect3DDevice->SetLight(0,&light);
pDirect3DDevice->LightEnable(0,TRUE);
pDirect3DDevice->SetTexture(0,pDirect3DTexture01);
//pDirect3DDevice->SetTexture(1,pDirect3DTexture02);
pDirect3DDevice->SetTextureStageState(0,
D3DTSS_COLORARG1,D3DTA_TEXTURE);
pDirect3DDevice->SetTextureStageState(0,
D3DTSS_COLORARG2,D3DTA_DIFFUSE);
pDirect3DDevice->SetTextureStageState(0,
D3DTSS_COLOROP,D3DTOP_MODULATE);
pDirect3DDevice->SetTextureStageState(1,
D3DTSS_TEXCOORDINDEX,0);
pDirect3DDevice->SetTextureStageState(1,
D3DTSS_COLORARG1,D3DTA_TEXTURE);
pDirect3DDevice->SetTextureStageState(1,
D3DTSS_COLORARG1,D3DTA_TEXTURE);
pDirect3DDevice->SetTextureStageState(1,
D3DTSS_COLOROP,D3DTOP_MODULATE);
pDirect3DDevice->GetDeviceCaps(&caps);
pDirect3DDevice->SetSamplerState(0,D3DSAMP_MAXANISOTROPY,caps.MaxAnisotropy);
pDirect3DDevice->SetSamplerState(0,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->SetSamplerState(0,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->SetSamplerState(0,D3DSAMP_MIPFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->SetSamplerState(1,D3DSAMP_MAXANISOTROPY,caps.MaxAnisotropy);
pDirect3DDevice->SetSamplerState(1,D3DSAMP_MINFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->SetSamplerState(1,D3DSAMP_MAGFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->SetSamplerState(1,D3DSAMP_MIPFILTER,D3DTEXF_ANISOTROPIC);
pDirect3DDevice->BeginScene();
{
pDirect3DDevice->SetStreamSource(0,pDirect3DVertexBuffer,0,
sizeof(CUSTOMVERTEX));
pDirect3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
pDirect3DDevice->SetIndices(pDirect3DIndexBuffer);
/*pDirect3DDevice->DrawIndexedPrimitive(
D3DPT_TRIANGLELIST,0,0,36,0,12);*/
for (int i = 0; i < Subsets; i++)
{
pDirect3DDevice->SetMaterial(&pDirect3DMaterial[i]);
pDirect3DDevice->SetTexture(0,pDirect3DTexture[i]);
pD3DXMesh->DrawSubset(i);
}
}
pDirect3DDevice->EndScene();
pDirect3DDevice->Present(NULL,NULL,NULL,NULL);
}
}
VOID ReleaseD3D(void)
{
if (pDirect3DTexture)
{
for (int i = 0; i < 0; i++)
pDirect3DTexture[i]->Release();
}
if (pDirect3DMaterial)
{
delete [] pDirect3DMaterial;
}
if (pD3DXMesh)
pD3DXMesh->Release();
if (pDirect3DTexture02)
pDirect3DTexture02->Release();
if (pDirect3DTexture01)
pDirect3DTexture01->Release();
if (pDirect3DIndexBuffer)
pDirect3DIndexBuffer->Release();
if (pDirect3DVertexBuffer)
pDirect3DVertexBuffer->Release();
if (pDirect3DDevice)
pDirect3DDevice->Release();
if (pDirect3D)
pDirect3D->Release();
}
#endif
App use simple Win32 framework with WinMain etc...
Sample code in MFC classes
#include "MainWnd.h"
#include "d3d_renderer.h"
CMainWnd::CMainWnd(void)
{
}
CMainWnd::~CMainWnd(void)
{
}
BEGIN_MESSAGE_MAP(CMainWnd, CWnd)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_SIZE()
ON_WM_TIMER()
ON_WM_PAINT()
END_MESSAGE_MAP()
// WM_CREATE
int CMainWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (FAILED(InitializeD3D(m_hWnd)))
exit(0);
if (FAILED(InitializeD3DBufferObject()))
exit(0);
if (FAILED(InitialMesh()))
exit(0);
SetTimer(33,1,NULL);
return 0;
}
// WM_DESTROY
void CMainWnd::OnDestroy()
{
CWnd::OnDestroy();
KillTimer(101);
ReleaseD3D();
}
// WM_SIZE
void CMainWnd::OnSize(UINT nType, int cx, int cy)
{
CWnd::OnSize(nType, cx, cy);
ChangeSize(cx,cy);
}
// WM_TIMER
void CMainWnd::OnTimer(UINT_PTR nIDEvent)
{
InvalidateRect(NULL,FALSE);
CWnd::OnTimer(nIDEvent);
}
// WM_PAINT
void CMainWnd::OnPaint()
{
RotateScene();
RenderScene();
ValidateRect(NULL);
}
so decide what you want to use (D3D is significaly faster than GDI)
you can also use OpenGL to draw accelerated graphics (little bit slower than D3D) with less code amount.
Displaying 3D text with OpenGL and pure Win32 UI
#include <windows.h>
#include <gl\gl.h>
#include <gl\glu.h>
// Palette Handle
HPALETTE hPalette = NULL;
static LPCTSTR lpszAppName = "Text3D";
GLint nFontList;
// Light values and coordinates
GLfloat whiteLight[] = { 0.4f, 0.4f, 0.4f, 1.0f };
GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat specular[] = { 0.9f, 0.9f, 0.9f, 1.0f};
GLfloat lightPos[] = { -100.0f, 200.0f, 50.0f, 1.0f };
// Declaration for Window procedure
LRESULT CALLBACK WndProc( HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
// Set Pixel Format function - forward declaration
void SetDCPixelFormat(HDC hDC);
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat nRange = 100.0f;
GLfloat fAspect;
// Prevent a divide by zero
if(h == 0)
h = 1;
fAspect = (GLfloat)w/(GLfloat)h;
// Set Viewport to window dimensions
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
// Reset coordinate system
glLoadIdentity();
// Setup perspective for viewing
gluPerspective(17.5f,fAspect,1,300);
// Viewing transformation
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(-1.8f, 0.0f, -15.0f);
glRotatef(-20.0f, 0.0f, 1.0f,0.0f);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
}
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Blue 3D Text
glColor3ub(0, 0, 255);
glPushMatrix();
glListBase(nFontList);
glCallLists (6, GL_UNSIGNED_BYTE, "OpenGL");
glPopMatrix();
}
void SetupRC(HDC hDC)
{
// Setup the Font characteristics
HFONT hFont;
GLYPHMETRICSFLOAT agmf[128]; // Throw away
LOGFONT logfont;
logfont.lfHeight = -10;
logfont.lfWidth = 0;
logfont.lfEscapement = 0;
logfont.lfOrientation = 0;
logfont.lfWeight = FW_BOLD;
logfont.lfItalic = FALSE;
logfont.lfUnderline = FALSE;
logfont.lfStrikeOut = FALSE;
logfont.lfCharSet = ANSI_CHARSET;
logfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
logfont.lfQuality = DEFAULT_QUALITY;
logfont.lfPitchAndFamily = DEFAULT_PITCH;
strcpy(logfont.lfFaceName,"Arial");
// Create the font and display list
hFont = CreateFontIndirect(&logfont);
SelectObject (hDC, hFont);
//create display lists for glyphs 0 through 128 with 0.1 extrusion
// and default deviation.
nFontList = glGenLists(128);
wglUseFontOutlines(hDC, 0, 128, nFontList, 0.0f, 0.5f,
WGL_FONT_POLYGONS, agmf);
DeleteObject(hFont);
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glEnable(GL_COLOR_MATERIAL);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f );
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT0,GL_AMBIENT,whiteLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight);
glLightfv(GL_LIGHT0,GL_SPECULAR,specular);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
glMaterialfv(GL_FRONT, GL_SPECULAR,specular);
glMateriali(GL_FRONT,GL_SHININESS,128);
}
// If necessary, creates a 3-3-2 palette for the device context listed.
HPALETTE GetOpenGLPalette(HDC hDC)
{
HPALETTE hRetPal = NULL; // Handle to palette to be created
PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor
LOGPALETTE *pPal; // Pointer to memory for logical palette
int nPixelFormat; // Pixel format index
int nColors; // Number of entries in palette
int i; // Counting variable
BYTE RedRange,GreenRange,BlueRange;
// Range for each color entry (7,7,and 3)
// Get the pixel format index and retrieve the pixel format description
nPixelFormat = GetPixelFormat(hDC);
DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
// Does this pixel format require a palette? If not, do not create a
// palette and just return NULL
if(!(pfd.dwFlags & PFD_NEED_PALETTE))
return NULL;
// Number of entries in palette. 8 bits yeilds 256 entries
nColors = 1 << pfd.cColorBits;
// Allocate space for a logical palette structure plus all the palette entries
pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY));
// Fill in palette header
pPal->palVersion = 0x300; // Windows 3.0
pPal->palNumEntries = nColors; // table size
// Build mask of all 1's. This creates a number represented by having
// the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and
// pfd.cBlueBits.
RedRange = (1 << pfd.cRedBits) -1;
GreenRange = (1 << pfd.cGreenBits) - 1;
BlueRange = (1 << pfd.cBlueBits) -1;
// Loop through all the palette entries
for(i = 0; i < nColors; i++)
{
// Fill in the 8-bit equivalents for each component
pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
pPal->palPalEntry[i].peRed = (unsigned char)(
(double) pPal->palPalEntry[i].peRed * 255.0 / RedRange);
pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
pPal->palPalEntry[i].peGreen = (unsigned char)(
(double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);
pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
pPal->palPalEntry[i].peBlue = (unsigned char)(
(double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);
pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
}
// Create the palette
hRetPal = CreatePalette(pPal);
// Go ahead and select and realize the palette for this device context
SelectPalette(hDC,hRetPal,FALSE);
RealizePalette(hDC);
// Free the memory used for the logical palette structure
free(pPal);
// Return the handle to the new palette
return hRetPal;
}
// Select the pixel format for a given device context
void SetDCPixelFormat(HDC hDC)
{
int nPixelFormat;
static PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // Size of this structure
1, // Version of this structure
PFD_DRAW_TO_WINDOW | // Draw to Window (not to bitmap)
PFD_SUPPORT_OPENGL | // Support OpenGL calls in window
PFD_DOUBLEBUFFER, // Double buffered mode
PFD_TYPE_RGBA, // RGBA Color mode
32, // Want 32 bit color
0,0,0,0,0,0, // Not used to select mode
0,0, // Not used to select mode
0,0,0,0,0, // Not used to select mode
16, // Size of depth buffer
0, // Not used to select mode
0, // Not used to select mode
0, // Draw in main plane
0, // Not used to select mode
0,0,0 }; // Not used to select mode
// Choose a pixel format that best matches that described in pfd
nPixelFormat = ChoosePixelFormat(hDC, &pfd);
// Set the pixel format for the device context
SetPixelFormat(hDC, nPixelFormat, &pfd);
}
// Entry point of all Windows programs
int APIENTRY WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg; // Windows message structure
WNDCLASS wc; // Windows class structure
HWND hWnd; // Storeage for window handle
// Register Window style
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// No need for background brush for OpenGL window
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = lpszAppName;
// Register the window class
if(RegisterClass(&wc) == 0)
return FALSE;
// Create the main application window
hWnd = CreateWindow(
lpszAppName,
lpszAppName,
// OpenGL requires WS_CLIPCHILDREN and WS_CLIPSIBLINGS
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
// Window position and size
100, 100,
250, 250,
NULL,
NULL,
hInstance,
NULL);
// If window was not created, quit
if(hWnd == NULL)
return FALSE;
// Display the window
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
// Process application messages until the application closes
while( GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
// Window procedure, handles all messages for this program
LRESULT CALLBACK WndProc( HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
static HGLRC hRC; // Permenant Rendering context
static HDC hDC; // Private GDI Device context
switch (message)
{
// Window creation, setup for OpenGL
case WM_CREATE:
// Store the device context
hDC = GetDC(hWnd);
// Select the pixel format
SetDCPixelFormat(hDC);
// Create the rendering context and make it current
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
// Create the palette
hPalette = GetOpenGLPalette(hDC);
SetupRC(hDC);
break;
// Window is being destroyed, cleanup
case WM_DESTROY:
// Kill the timer that we created
KillTimer(hWnd,101);
glDeleteLists(nFontList, 128);
// Deselect the current rendering context and delete it
wglMakeCurrent(hDC,NULL);
wglDeleteContext(hRC);
// Delete the palette
if(hPalette != NULL)
DeleteObject(hPalette);
// Tell the application to terminate after the window
// is gone.
PostQuitMessage(0);
break;
// Window is resized.
case WM_SIZE:
// Call our function which modifies the clipping
// volume and viewport
ChangeSize(LOWORD(lParam), HIWORD(lParam));
break;
// The painting function. This message sent by Windows
// whenever the screen needs updating.
case WM_PAINT:
{
// Call OpenGL drawing code
RenderScene();
// Call function to swap the buffers
SwapBuffers(hDC);
ValidateRect(hWnd,NULL);
}
break;
// Windows is telling the application that it may modify
// the system palette. This message in essance asks the
// application for a new palette.
case WM_QUERYNEWPALETTE:
// If the palette was created.
if(hPalette)
{
int nRet;
// Selects the palette into the current device context
SelectPalette(hDC, hPalette, FALSE);
// Map entries from the currently selected palette to
// the system palette. The return value is the number
// of palette entries modified.
nRet = RealizePalette(hDC);
// Repaint, forces remap of palette in current window
InvalidateRect(hWnd,NULL,FALSE);
return nRet;
}
break;
// This window may set the palette, even though it is not the
// currently active window.
case WM_PALETTECHANGED:
// Don't do anything if the palette does not exist, or if
// this is the window that changed the palette.
if((hPalette != NULL) && ((HWND)wParam != hWnd))
{
// Select the palette into the device context
SelectPalette(hDC,hPalette,FALSE);
// Map entries to system palette
RealizePalette(hDC);
// Remap the current colors to the newly realized palette
UpdateColors(hDC);
return 0;
}
break;
default: // Passes it on if unproccessed
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return (0L);
}
can work without reseting palette
AS window handle you may use every legal window handles (panel, listbox, buttons etc...) so you can display 3d content almost everywhere
Photoshop use OpenGL, 3DS Max optional (OpenGL, Direct3D), AutoCad it is hard to say: GDI older versions, newest using .NET too.

DirectX Toolkit C++ SpriteBatch Draw Rectangle

I am using DirectX 11, DirectX Toolkit and C++. How can I create a rectangle with a blue border for spritebatch ? I'm guessing I need to create a texture in memory perhaps with a 1 pixel blue border ?
ComPtr<ID3D11ShaderResourceView> spriteSheet_;
ComPtr<ID3D11Resource> resource;
CreateDDSTextureFromFile(d3dDevice_, L"mytex.dds", resource.GetAddressOf(),
spriteSheet_.ReleaseAndGetAddressOf());
batch->Draw(spriteSheet_.Get(), position, &sourceRect, DirectX::Colors::White,
rotation_, spriteOrigin_, scale_, DirectX::SpriteEffects_None, depth_);
You can use SpriteBatch to draw a single-pixel texture as you described--you could use a white texture and use the SpriteBatch tinting to make it Blue.
Here is some simple code for programmatically creating a 1x1 white texture in Direct3D 11:
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> pWhiteTexture;
static const uint32_t s_pixel = 0xffffffff;
D3D11_SUBRESOURCE_DATA initData = { &s_pixel, sizeof(uint32_t), 0 };
D3D11_TEXTURE2D_DESC desc;
memset( &desc, 0, sizeof(desc) );
desc.Width = desc.Height = desc.MipLevels = desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_IMMUTABLE;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
Microsoft::WRL::ComPtr<ID3D11Texture2D> tex;
HRESULT hr = mDevice->CreateTexture2D( &desc, &initData, &tex );
DX::ThrowIfFailed(hr);
D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc;
memset( &SRVDesc, 0, sizeof( SRVDesc ) );
SRVDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
SRVDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
SRVDesc.Texture2D.MipLevels = 1;
hr = mDevice->CreateShaderResourceView( tex.Get(), &SRVDesc, &pWhiteTexture );
DX::ThrowIfFailed(hr);
A more efficient solution would be to use PrimitiveBatch to draw a blue quad where you want it located.
See the DirectX Tool Kit tutorial Simple rendering

How to properly initialize OpenGL in ActiveX controls?

I am trying to create a simple ActiveX control using OpenGL. I add some styles in PreCreateWindow:
BOOL CMFCActiveXControl1Ctrl::PreCreateWindow(CREATESTRUCT& cs) {
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
cs.lpszClass = _T("STATIC");
return COleControl::PreCreateWindow(cs);
}
Initialization of OpenGL:
int CMFCActiveXControl1Ctrl::OnCreate(LPCREATESTRUCT lpCreateStruct) {
PIXELFORMATDESCRIPTOR pfd = { 0 };
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
hDC = ::GetDC(m_hWnd);
int format = ChoosePixelFormat(hDC, &pfd);
SetPixelFormat(hDC, format, &pfd);
hRC = wglCreateContext(hDC);
wglMakeCurrent(hDC, hRC);
return 0;
}
And then I try to clear color buffer with red color, but all I see is just a black square:
void CMFCActiveXControl1Ctrl::OnDraw(
CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
if (!pdc)
return;
glClearColor(1, 0, 0, 0);
SwapBuffers(wglGetCurrentDC());
}
glClearColor (...) does not actually clear the color buffer, it just sets the color that will be used when you call glClear (...).
There is a new function in GL3: glClearBuffer (...) that can be used to clear a buffer to an explicit value all in a single call, but ordinarily you are going to need to call glClear (GL_COLOR_BUFFER_BIT) after setting the clear color instead.

Directx 11 depth test not working

I cannot get my program to correctly choose which models to place in front. I have followed the MSDN code exactly. My code appears to correctly draw all polygons in a particular call of DrawIndexed, but each subsequent call seems to cause models to be drawn in the order they are drawn, not based on whether they are closer to the screen.
Here is my code for initializing Direct3d:
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory( &sd, sizeof( sd ) );
sd.BufferCount = 1;
sd.BufferDesc.Width = width;
sd.BufferDesc.Height = height;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.RefreshRate.Numerator = 60;
sd.BufferDesc.RefreshRate.Denominator = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = hWnd;
sd.SampleDesc.Count = 4;
sd.SampleDesc.Quality = 0;
sd.Windowed = !fullScreen;
sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
D3D_FEATURE_LEVEL FeatureLevelsRequested = D3D_FEATURE_LEVEL_11_0;
UINT numFeatureLevelsRequested = 1;
D3D_FEATURE_LEVEL FeatureLevelsSupported;
HRESULT hr;
if( FAILED (hr = D3D11CreateDeviceAndSwapChain( adapters[0],
D3D_DRIVER_TYPE_UNKNOWN,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&sd,
&swapchain,
&dev,
&FeatureLevelsSupported,
&devcon )))
{
//return;
}
ID3D11Texture2D *pBack = NULL;
swapchain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBack);
// use the back buffer address to create the render target
dev->CreateRenderTargetView(pBack, NULL, &backbuffer);
pBack->Release();
// set the render target as the back buffer
// Create depth stencil texture
D3D11_TEXTURE2D_DESC descDepth;
ZeroMemory(&descDepth, sizeof(descDepth));
descDepth.Width = width;
descDepth.Height = height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format =DXGI_FORMAT_D24_UNORM_S8_UINT;
descDepth.SampleDesc.Count = 4;
descDepth.SampleDesc.Quality = 0;
descDepth.Usage = D3D11_USAGE_DEFAULT;
descDepth.BindFlags = D3D11_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
hr = dev->CreateTexture2D( &descDepth, NULL, &g_pDepthStencil);
if(FAILED(hr))
exit(hr);
// Create the depth stencil view
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
ZeroMemory(&descDSV, sizeof(descDSV));
descDSV.Format = descDepth.Format;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
descDSV.Texture2D.MipSlice = 0;;
//descDSV.Texture2DMS.UnusedField_NothingToDefine = 0;
hr = dev->CreateDepthStencilView( g_pDepthStencil, &descDSV, &g_pDepthStencilView);
if(FAILED(hr))
exit(hr);
devcon->OMSetRenderTargets(1, &backbuffer, g_pDepthStencilView);
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = width;
viewport.Height = height;
devcon->RSSetViewports(1, &viewport);
This is my code for rendering:
void Direct3DRenderer::Render()
{
devcon->ClearRenderTargetView(backbuffer, D3DXCOLOR(0.0f, 0.2f, 0.4f, 1.0f));
devcon->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0 );
camera.location = simulation->GetWorld()->GetCameraCoordinates();
camera.direction = simulation->GetWorld()->GetCameraLookAt();
//camera.up = simulation->GetWorld()->GetCameraOrientation();
Vec3d lookAt = camera.location + camera.direction;
XMVECTOR eye = XMVectorSet((float)camera.location[0], (float)camera.location[1], (float)camera.location[2], 0.f);
XMVECTOR look = XMVectorSet(lookAt[0], lookAt[1], lookAt[2], 0);
XMVECTOR up = XMVectorSet(camera.up[0], camera.up[1], camera.up[2], 0);
g_View = XMMatrixLookAtLH(eye, look, up);
ConstantBuffer oncePerFrame;
oncePerFrame.matrix = XMMatrixTranspose(g_View);
devcon->UpdateSubresource(oncePerFrameBuffer, 0, NULL, &oncePerFrame, 0, 0);
UINT stride = sizeof(VERTEX);
UINT offset = 0;
const std::vector<Graphical*> graphicalList = simulation->GetWorld()->GetGraphicalList();
for(int ind = 0; ind < graphicalList.size(); ++ind)
{
switch(graphicalList[ind]->GetModelType())
{
case 1: //Sphere
{
ConstantBuffer oncePerModel2;
oncePerModel2.matrix = XMMatrixTranspose(XMMatrixScalingFromVector(graphicalList[ind]->GetScaleX()) * XMMatrixTranslationFromVector(graphicalList[ind]->GetTranslationX()));
devcon->UpdateSubresource(oncePerModelBuffer, 0, NULL, &oncePerModel2, 0, 0);
devcon->IASetVertexBuffers(0, 1, &(sphereModel.vertexBuffer), &stride, &offset);
devcon->IASetIndexBuffer(sphereModel.indexBuffer, DXGI_FORMAT_R32_UINT, 0);
devcon->DrawIndexed(sphereModel.indexCount, 0, 0);
}
break;
}
}
ConstantBuffer oncePerModel;
oncePerModel.matrix = XMMatrixTranspose(g_World);
devcon->UpdateSubresource(oncePerModelBuffer, 0, NULL, &oncePerModel, 0, 0);
devcon->IASetVertexBuffers(0, 1, &terrainModel.vertexBuffer, &stride, &offset);
devcon->IASetIndexBuffer(terrainModel.indexBuffer, DXGI_FORMAT_R32_UINT, 0);
devcon->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
devcon->DrawIndexed(terrainModel.indexCount, 0, 0);
swapchain->Present(0, 0);
}
I have tried searching extensively, and have followed every tutorial I could find. Nothing fixes it.
In the case of the spheres, depth appears to be correct if viewing from one side, but not the other.
Any help would be appreciated. Thanks.
From OP comment:
The problem ended up being much simpler. I did not set the minimum and
max depth for the viewport object. It worked once I did so.
I had the same problem, it works now:
D3D11_VIEWPORT screenViewport;
/* ... */
screenViewport.MinDepth = 0;
screenViewport.MaxDepth = 1;
/* ... */
context->RSSetViewports(1, &screenViewport);
There are three key steps to Z-Buffering.
Setting the Appropriate Presentation Parameters
Turning On Z-Buffering
Clearing the Z-Buffer
1) Setting the Appropriate Presentation Parameters
D3DPRESENT_PARAMETERS d3dpp;
//...
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
EnableAutoDepthStencil
In truth, z-buffering can be complex. Setting this value to TRUE tells Direct3D to automatically create the z-buffer and set it up in a way used most often. There are, of course, uses for the complex method, but we'll stick to simple for now. We'll cover ways the complex method can be useful later in the tutorial.
AutoDepthStencilFormat
This is the format for each pixel in the z-buffer. We don't use the regular pixel format defined in the Presentation Parameters. Instead, we use a special format for z-buffers. This format is D3DFMT_D16. This means that each pixel is 16-bit. There are other formats, but we will not need them for the extent of this tutorial.
2) Turning On Z-Buffering
// d3ddev is your Direct3D device - a variable of type LPDIRECT3DDEVICE9
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
3) Clearing the Z-Buffer
d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
By the way this works in DirectX 9.0c. Im not sure if it is compatible with DirectX 11.
Had a similar problem in DirectX10, seems it was initialisation code, I am not sure about the CreateDevice and SwapChain against UNKNOWN driver type, as I have not used that before.
There are a few differences I can see, the Stencil buffer does not specify the operations to perform depth stencil tests against. (Unless this has been specified in the HLSL which is not visible here)
eg:
// Stencil test parameters
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0xFF;
// Stencil operations if pixel is front-facing
dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
dsDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
// Stencil operations if pixel is back-facing
dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
dsDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
In any event, here is a working DirectX10 example, I am pretty sure you can adapt it quickly for DirectX11.
logger->debug("initD3D: Calling D3D10CreateDeviceAndSwapChain.\n");
SYSTEMTIME sysTime;
GetSystemTime(&sysTime);
srand((unsigned int)sysTime.wMilliseconds);
logger->debug("in initD3D.\n");
shutdownXX = false;
count = 1;
quality = 0;
//Create the back buffer desc.
ZeroMemory(&swapDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapDesc.BufferCount = 1;
swapDesc.BufferDesc.Width = width;
swapDesc.BufferDesc.Height = height;
swapDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapDesc.BufferDesc.RefreshRate.Numerator = 60;
swapDesc.BufferDesc.RefreshRate.Denominator = 1;
swapDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapDesc.OutputWindow = hwnd;
swapDesc.SampleDesc.Count = count;
swapDesc.SampleDesc.Quality = quality;
swapDesc.Windowed = FALSE;
swapDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
//Create the device.
HRESULT hr = D3D10CreateDeviceAndSwapChain(
NULL,
D3D10_DRIVER_TYPE_HARDWARE,
NULL,
0,
D3D10_SDK_VERSION,
&swapDesc,
&swapChain,
&device);
if (!chk(hr, TEXT("Could not create D3D Device D3D10CreateDeviceAndSwapChain failed.")))
return false;
ID3D10Texture2D *buffer;
logger->debug("initD3D: Calling swapChain->GetBuffer.\n");
hr = swapChain->GetBuffer(0, __uuidof(ID3D10Texture2D), (LPVOID*) &buffer);
if (!chk(hr, TEXT("Could not create D3D Device: swapChain->GetBuffer failed.")))
return false;
D3D10_TEXTURE2D_DESC BBDesc;
ZeroMemory(&BBDesc, sizeof(D3D10_TEXTURE2D_DESC));
buffer->GetDesc( &BBDesc );
D3D10_RENDER_TARGET_VIEW_DESC RTVDesc;
ZeroMemory(&RTVDesc, sizeof(D3D10_RENDER_TARGET_VIEW_DESC));
RTVDesc.Format = BBDesc.Format;
//RTVDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2D;
RTVDesc.ViewDimension = D3D10_RTV_DIMENSION_TEXTURE2DMS;
RTVDesc.Texture2D.MipSlice = 0;
logger->debug("initD3D: Calling device->CreateRenderTargetView.\n");
hr = device->CreateRenderTargetView(buffer, &RTVDesc, &renderTView);
buffer->Release();
if (!chk(hr, TEXT("Could not create D3D Device: device->CreateRenderTargetView failed.")))
return false;
ZeroMemory(&descDepth, sizeof(D3D10_TEXTURE2D_DESC));
descDepth.Width = width;
descDepth.Height = height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
//descDepth.Format = DXGI_FORMAT_D32_FLOAT;
descDepth.SampleDesc.Count = count;
descDepth.SampleDesc.Quality = quality;
descDepth.Usage = D3D10_USAGE_DEFAULT;
descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL;
descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
hr = device->CreateTexture2D(&descDepth, NULL, &stencil);
if (!chk(hr, TEXT("device->device->CreateTexture2D Failed\n")))
return false;
// Depth test parameters
dsDesc.DepthEnable = true;
dsDesc.DepthWriteMask = D3D10_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D10_COMPARISON_LESS;
// Stencil test parameters
dsDesc.StencilEnable = true;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0xFF;
// Stencil operations if pixel is front-facing
dsDesc.FrontFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D10_STENCIL_OP_INCR;
dsDesc.FrontFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
// Stencil operations if pixel is back-facing
dsDesc.BackFace.StencilFailOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D10_STENCIL_OP_DECR;
dsDesc.BackFace.StencilPassOp = D3D10_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilFunc = D3D10_COMPARISON_ALWAYS;
hr = device->CreateDepthStencilState(&dsDesc, &pDSState);
if (!chk(hr, TEXT("device->device->CreateDepthStencilState Failed\n")))
return false;
device->OMSetDepthStencilState(pDSState, 1);
ZeroMemory(&descDSV, sizeof(D3D10_DEPTH_STENCIL_VIEW_DESC));
descDSV.Format = descDepth.Format;
//descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2D;
descDSV.ViewDimension = D3D10_DSV_DIMENSION_TEXTURE2DMS;
descDSV.Texture2D.MipSlice = 0;
hr = device->CreateDepthStencilView(stencil, &descDSV, &depthStencil);
if (!chk(hr, TEXT("device->device->CreateDepthStencilView Failed\n")))
return false;
device->OMSetRenderTargets(1, &renderTView, depthStencil);
resizeD3D10Window(width, height);
return true;