I'm pretty new to this structure and the book I'm learning it from is absurdly unintuitive to me. I triple checked the code but I can't figure out why I can't get an image to pop up. The background is white and the HUD is there but the cube won't show up. It was the same when i tried to make it in colour.
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <d3dx9core.h>
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
//LPDIRECT3DTEXTURE9 quadTexture;
LPD3DXFONT m_font;
D3DCOLOR fontColor;
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
LPDIRECT3DINDEXBUFFER9 i_buffer = NULL;
struct ColorVertex{
D3DXVECTOR3 pos;
ColorVertex(FLOAT X, FLOAT Y, FLOAT Z):pos(X, Y, Z){}
static IDirect3DVertexDeclaration9* Decl;
};
IDirect3DVertexDeclaration9* ColorVertex::Decl = 0;
void initD3D(HWND hWnd);
void render_frame(void);
void cleanD3D(void);
void setVertices(void);
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
#define SCREEN_WIDTH GetSystemMetrics(SM_CXSCREEN)
#define SCREEN_HEIGHT GetSystemMetrics(SM_CYSCREEN)
HWND hWnd;
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.lpszClassName = L"WindowClass";
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL,
L"WindowClass",
L"v2",
WS_EX_TOPMOST | WS_POPUP,
0, 0,
SCREEN_WIDTH, SCREEN_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd, nCmdShow);
initD3D(hWnd);
setVertices();
D3DXCreateFont( d3ddev, 20, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &m_font );
D3DVERTEXELEMENT9 Elements[] = {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
D3DDECL_END()
};
d3ddev->CreateVertexDeclaration(Elements, &ColorVertex::Decl);
MSG msg;
while(TRUE){
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message == WM_QUIT) break;
render_frame();
}
cleanD3D();
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
switch(message){
case WM_DESTROY:{
PostQuitMessage(0);
return 0;
}break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
void initD3D(HWND hWnd){
d3d = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
d3ddev->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
}
void setVertices(void){
d3ddev->CreateVertexBuffer(8*sizeof(ColorVertex),
0,
0,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
ColorVertex* cube = 0;
v_buffer->Lock(0, 0, (void**)&cube, 0);
cube[0] = ColorVertex(-1.0f, -1.0f, -1.0f);
cube[1] = ColorVertex(-1.0f, 1.0f, -1.0f);
cube[2] = ColorVertex( 1.0f, 1.0f, -1.0f);
cube[3] = ColorVertex( 1.0f, -1.0f, -1.0f);
cube[4] = ColorVertex(-1.0f, -1.0f, 1.0f);
cube[5] = ColorVertex(-1.0f, 1.0f, 1.0f);
cube[6] = ColorVertex( 1.0f, 1.0f, 1.0f);
cube[7] = ColorVertex( 1.0f, -1.0f, 1.0f);
v_buffer->Unlock();
d3ddev->CreateIndexBuffer(12*3*sizeof(WORD),
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&i_buffer,
NULL);
WORD* k = 0;
i_buffer->Lock(0, 0, (void**)&k, 0);
k[0] = 0; k[1] = 1; k[2] = 2;
k[3] = 0; k[4] = 2; k[5] = 3;
// Back face.
k[6] = 4; k[7] = 6; k[8] = 5;
k[9] = 4; k[10] = 7; k[11] = 6;
// Left face.
k[12] = 4; k[13] = 5; k[14] = 1;
k[15] = 4; k[16] = 1; k[17] = 0;
// Right face.
k[18] = 3; k[19] = 2; k[20] = 6;
k[21] = 3; k[22] = 6; k[23] = 7;
// Top face.
k[24] = 1; k[25] = 5; k[26] = 6;
k[27] = 1; k[28] = 6; k[29] = 2;
// Bottom face.
k[30] = 4; k[31] = 0; k[32] = 3;
k[33] = 4; k[34] = 3; k[35] = 7;
i_buffer->Unlock();
}
void render_frame(void){
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(255, 255, 255), 1.0f, 0);
d3ddev->BeginScene();
d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(ColorVertex));
d3ddev->SetIndices(i_buffer);
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (0.0f, 5.0f, -5.0f),// the camera position
&D3DXVECTOR3 (0.0f, 0.0f, 0.0f), // the look-at position
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f));// the up direction
d3ddev->SetTransform(D3DTS_VIEW, &matView);
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(90),
(FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT,
1.0f,// the near view-plane
5000.0f);// the far view-plane
d3ddev->SetVertexDeclaration(ColorVertex::Decl);
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
fontColor = D3DCOLOR_ARGB(255,0,0,255);
RECT rct;
rct.left=10;
rct.right=SCREEN_WIDTH-10;
rct.top=10;
rct.bottom=rct.top+20;
//WCHAR lookAtPos [32000];
//swprintf_s(lookAtPos, 32000, L"X=%f, Z=%f, Y=%f", camDirX, camDirZ, camDirY);
m_font->DrawText(NULL, L"Hello World", -1, &rct, 0, fontColor );
d3ddev->EndScene();
d3ddev->Present(NULL, NULL, NULL, NULL);
}
void cleanD3D(void){
d3ddev->Release();
d3d->Release();
i_buffer->Release();
v_buffer->Release();
ColorVertex::Decl->Release();
}
I'm a friggin idiot. I set the world projection matrix and then didn't use it. Sorry for bothering you guys.
Related
I've made a simple OpenGL program in C that draws a triangle rotating inside a box. The triangle is supposed to be equilateral but even when the window width and height are the same the triangles vertices contract and extrude when they go along the width and length of the window. I can tell because I made a static equiangular box and the vertices of the triangle go outside of it. Here's a short clip of what it's doing: https://edwardseverinsen1717-gmail.tinytake.com/sf/NDg5NjQ0XzI2MDQzMDM Excuse the lag at some moments.
And here's my code:
#include <windows.h>
#include <gl/gl.h>
#include <gl/glu.h>
LRESULT CALLBACK WindowProc(HWND, UINT, WPARAM, LPARAM);
void EnableOpenGL(HWND hwnd, HDC*, HGLRC*);
void DisableOpenGL(HWND, HDC, HGLRC);
void DrawTriangle(float theta);
void DrawBox(void);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
WNDCLASSEX wcex;
HWND hwnd;
HDC hDC;
HGLRC hRC;
MSG msg;
BOOL bQuit = FALSE;
float theta = 0.0f;
int i;
/* register window class */
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_OWNDC;
wcex.lpfnWndProc = WindowProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = "GLSample";
wcex.hIconSm = LoadIcon(NULL, IDI_APPLICATION);;
if (!RegisterClassEx(&wcex))
return 0;
/* create main window */
hwnd = CreateWindowEx(0,
"GLSample",
"OpenGL Sample",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
500,
500,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, nCmdShow);
/* enable OpenGL for the window */
EnableOpenGL(hwnd, &hDC, &hRC);
/* program main loop */
while (!bQuit)
{
/* check for messages */
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
/* handle or dispatch messages */
if (msg.message == WM_QUIT)
{
bQuit = TRUE;
}
else
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
/* OpenGL animation code goes here */
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
DrawTriangle(theta);
DrawBox();
SwapBuffers(hDC);
theta += 1.0f;
Sleep (1);
}
}
/* shutdown OpenGL */
DisableOpenGL(hwnd, hDC, hRC);
/* destroy the window explicitly */
DestroyWindow(hwnd);
return msg.wParam;
}
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CLOSE:
PostQuitMessage(0);
break;
case WM_DESTROY:
return 0;
case WM_KEYDOWN:
{
switch (wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
}
}
break;
default:
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
return 0;
}
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
/* get the device context (DC) */
*hDC = GetDC(hwnd);
/* set the pixel format for the DC */
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat(*hDC, &pfd);
SetPixelFormat(*hDC, iFormat, &pfd);
/* create and enable the render context (RC) */
*hRC = wglCreateContext(*hDC);
wglMakeCurrent(*hDC, *hRC);
}
void DisableOpenGL (HWND hwnd, HDC hDC, HGLRC hRC)
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(hRC);
ReleaseDC(hwnd, hDC);
}
void DrawTriangle(float theta)
{
glPushMatrix();
if(theta != 0)
{
glRotatef(theta, 0.0f, 0.0f, 1.0f);
}
if(theta == 1)
{
glRotatef(89, 0.0f, 0.0f, 1.0f);
}
glBegin(GL_TRIANGLES);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(0.0f, 0.50f);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(0.45f, -0.50f);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(-0.45f, -0.50f);
glEnd();
glPopMatrix();
}
void DrawBox(void)
{
glPushMatrix();
glBegin(GL_LINE_LOOP);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(0.45f, 0.5f); /*I decremented each x value by 0.05 to compensate for the bullshit with the window throwing off scale*/
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(0.45f, -0.5f);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(-0.45f, -0.5f);
glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(-0.45f, 0.5f);
glEnd();
glPopMatrix();
}
The coordinates you use do not span a equilateral triangle. Equilateral triangles always have three sides with the same length. In your example, the bottom side has a length of 0.9, but the other two have a length of sqrt(0.45^2 + 1.0^2) = 1.097. Even when assuming that you took 0.45 instead of 0.5, this is still not equilateral. (Bottom = 1.0, Other sides = sqrt(0.5^2 + 1.0^2) = 1.12)
As you have already noted, you have to compensate for the aspect ratio of the renderable area (which is not quadratic when passing 500x500 to CreateWindowEx since titlebar and borders are included here). This is normally done by defining a projection matrix with the correct aspect ratio of the client area. Have a look at GetClientRect to query the client area size and glOrtho to specify the projection matrix.
I'm using the SpriteFont/SpriteBatch classes to render text onto my game because quite frankly, i am tired of using Direct2D and DirectWrite... But everytime I draw text using SpriteFont, I get the text written on the screen, but it is written on a black background... The black background blocks the entire scene of my game.. is there any way to remove the black background and only keep the text?
Down below is my implementation of SpriteFont..
void RenderText(int FPS)
{
std::unique_ptr<DirectX::SpriteFont> Sprite_Font(new DirectX::SpriteFont(device, L"myfile.spritefont"));
std::unique_ptr<DirectX::SpriteBatch> Sprite_Batch(new DirectX::SpriteBatch(DevContext));
Sprite_Batch->Begin();
Sprite_Font->DrawString(Sprite_Batch.get(), L"FPS: ", DirectX::XMFLOAT2(200,200));
Sprite_Batch->End();
}
It seems to me that the black background is drawn because of the values that I specified in the function ClearRenderTargetView().
float BackgroundColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
DevContext->ClearRenderTargetView(RenderTarget, BackgroundColor); //This is where the black background gets drawn over my entire scene
Everytime i change BackgroundColor[4] to different values, the background color changes as well, respectably. How can I remove the black background from my game and only include the text?
Here is my entire code.
#include <Windows.h>
#include <SpriteFont.h>
#include <SpriteBatch.h>
#include <d3dcompiler.h>
#include <SimpleMath.h>
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "D3D11.lib")
#pragma comment (lib, "d3dcompiler.lib")
LRESULT CALLBACK WindowProcedure(HWND, unsigned int, WPARAM, LPARAM);
void Create_Window(HINSTANCE&);
void Initialize_Direct3D11(HINSTANCE);
void Initialize_Rendering_Pipeline();
void Initialize_Sprites();
void Render_Frame();
void Render_Text();
void Create_Vertex_Buffer_for_triangle();
HWND MainWindow;
IDXGISwapChain * SwapChain;
ID3D11Device * device;
ID3D11DeviceContext * DevContext;
ID3D11RenderTargetView * RenderTarget;
ID3D11Buffer * VertexBuffer;
ID3D10Blob * VertexShader;
ID3D10Blob * PixelShader;
ID3D11VertexShader * VS;
ID3D11PixelShader * PS;
ID3D11InputLayout * inputLayout;
std::unique_ptr<DirectX::SpriteFont> Sprite_Font;
std::unique_ptr<DirectX::SpriteBatch> Sprite_Batch;
DirectX::SimpleMath::Vector2 m_fontPos;
const wchar_t* output = L"Hello World";
struct Vertex_Buffer
{
float Positions[3];
Vertex_Buffer(float x, float y, float z)
{
Positions[0] = x;
Positions[1] = y;
Positions[2] = z;
};
};
int WINAPI WinMain(HINSTANCE CurrentInstance, HINSTANCE PrevInstance, LPSTR ignore, int WindowShow)
{
MSG message;
HRESULT status;
Create_Window(CurrentInstance);
Initialize_Direct3D11(CurrentInstance);
Initialize_Sprites();
Initialize_Rendering_Pipeline();
Create_Vertex_Buffer_for_triangle();
while (true)
{
if (PeekMessage(&message, MainWindow, 0, 0, PM_REMOVE))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
else
{
Render_Frame();
Render_Text();
SwapChain->Present(0, 0);
}
}
}
void Initialize_Sprites()
{
Sprite_Font.reset(new DirectX::SpriteFont(device, L"myfile.spritefont"));
Sprite_Batch.reset(new DirectX::SpriteBatch(DevContext));
m_fontPos.x = 200;
m_fontPos.y = 200;
}
void Create_Window(HINSTANCE &CurrentInstance)
{
WNDCLASSEX windowclass;
ZeroMemory(&windowclass, sizeof(WNDCLASSEX));
windowclass.cbSize = sizeof(WNDCLASSEX);
windowclass.lpszClassName = L"Window Class";
windowclass.hInstance = CurrentInstance;
windowclass.lpfnWndProc = WindowProcedure;
windowclass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
windowclass.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClassEx(&windowclass);
MainWindow = CreateWindowEx(
0,
L"Window Class",
L"The Empire of Anatoria",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
800,
600,
NULL,
NULL,
CurrentInstance,
NULL
);
ShowWindow(MainWindow, SW_SHOW);
}
void Render_Text()
{
DirectX::SimpleMath::Vector2 origin = Sprite_Font->MeasureString(output);
Sprite_Batch->Begin();
Sprite_Font->DrawString(Sprite_Batch.get(), output,
m_fontPos, DirectX::Colors::White, 0.f, origin);
Sprite_Batch->End();
}
void Initialize_Direct3D11(HINSTANCE instance)
{
DXGI_MODE_DESC BackBufferDesc;
DXGI_SWAP_CHAIN_DESC SwapChainDesc;
ZeroMemory(&BackBufferDesc, sizeof(DXGI_MODE_DESC));
BackBufferDesc.Width = 400;
BackBufferDesc.Height = 400;
BackBufferDesc.RefreshRate.Numerator = 60;
BackBufferDesc.RefreshRate.Denominator = 1;
BackBufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
ZeroMemory(&SwapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
SwapChainDesc.BufferDesc = BackBufferDesc;
SwapChainDesc.BufferCount = 1;
SwapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
SwapChainDesc.SampleDesc.Count = 1;
SwapChainDesc.SampleDesc.Quality = 0;
SwapChainDesc.OutputWindow = MainWindow;
SwapChainDesc.Windowed = TRUE;
SwapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
D3D11CreateDeviceAndSwapChain(NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
NULL,
NULL,
NULL,
D3D11_SDK_VERSION,
&SwapChainDesc,
&SwapChain,
&device,
NULL,
&DevContext
);
ID3D11Texture2D * BackBuffer;
SwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&BackBuffer);
device->CreateRenderTargetView(BackBuffer, NULL, &RenderTarget);
DevContext->OMSetRenderTargets(
1,
&RenderTarget,
NULL
);
BackBuffer->Release();
DevContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
}
void Initialize_Rendering_Pipeline()
{
D3DCompileFromFile(L"VertexShader.hlsl", 0, 0, "main", "vs_5_0", 0, 0, &VertexShader, 0);
D3DCompileFromFile(L"VertexShader.hlsl", 0, 0, "Pixel_Shader", "ps_5_0", 0, 0, &PixelShader, 0);
device->CreateVertexShader(VertexShader->GetBufferPointer(), VertexShader->GetBufferSize(), NULL, &VS);
device->CreatePixelShader(PixelShader->GetBufferPointer(), PixelShader->GetBufferSize(), NULL, &PS);
DevContext->VSSetShader(VS, 0, 0);
DevContext->PSSetShader(PS, 0, 0);
D3D11_VIEWPORT Raster;
ZeroMemory(&Raster, sizeof(D3D11_VIEWPORT));
Raster.MinDepth = 0.0f;
Raster.MaxDepth = 1.0f;
Raster.Width = 400;
Raster.Height = 400;
DevContext->RSSetViewports(1, &Raster);
D3D11_INPUT_ELEMENT_DESC InputLayout[1];
ZeroMemory(&InputLayout[0], sizeof(D3D11_INPUT_ELEMENT_DESC));
InputLayout[0].SemanticName = "POSITION";
InputLayout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
InputLayout[0].InputSlot = 0;
InputLayout[0].AlignedByteOffset = 0;
InputLayout[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
device->CreateInputLayout(
InputLayout,
1,
VertexShader->GetBufferPointer(),
VertexShader->GetBufferSize(),
&inputLayout
);
DevContext->IASetInputLayout(inputLayout);
}
void Render_Frame()
{
float BackgroundColor[4] = {0.0f, 0.0f, 0.0f, 1.0f};
DevContext->ClearRenderTargetView(RenderTarget, BackgroundColor);
DevContext->Draw(3, 0);
}
void Create_Vertex_Buffer_for_triangle()
{
D3D11_BUFFER_DESC VertexBufferDesc;
D3D11_SUBRESOURCE_DATA VertexData;
UINT stride = sizeof(Vertex_Buffer);
UINT offset = 0;
ZeroMemory(&VertexBufferDesc, sizeof(D3D11_BUFFER_DESC));
VertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
VertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
VertexBufferDesc.CPUAccessFlags = 0;
VertexBufferDesc.ByteWidth = sizeof(Vertex_Buffer) * 3;
Vertex_Buffer VerticesData[] =
{
Vertex_Buffer(0.0f, 0.5f, 0.5f),
Vertex_Buffer(0.5f, -0.5f, 0.5f),
Vertex_Buffer(-0.5f, -0.5f, 0.5f)
};
ZeroMemory(&VertexData, sizeof(D3D11_SUBRESOURCE_DATA));
VertexData.pSysMem = VerticesData;
device->CreateBuffer(
&VertexBufferDesc,
&VertexData,
&VertexBuffer);
DevContext->IASetVertexBuffers(
0,
1,
&VertexBuffer,
&stride,
&offset
);
}
LRESULT CALLBACK WindowProcedure(HWND handle, unsigned int message, WPARAM ignore1, LPARAM ignore2)
{
switch (message)
{
case WM_CREATE:
return 0;
case WM_CLOSE:
DestroyWindow(handle);
return 0;
default:
return DefWindowProc(handle, message, ignore1, ignore2);
}
}
Here is the VertexShader.hlsl file
float4 main( float4 pos : POSITION ) : SV_POSITION
{
return pos;
}
float4 Pixel_Shader() : SV_TARGET
{
return float4(1.0f, 0.0f, 0.0f, 1.0f);
}
First, if your code snippet is accurate, you should not be creating the SpriteFont and SpriteBatch instance every frame. You only have to create them when the device changes.
By default, SpriteFont is drawing using pre-multiplied alpha blending modes, so if you are getting a fully "background color" image then something else is amiss in your pipeline state. It is likely that you are leaving some state in effect in the rendering between the clear and RenderText that is affecting the SpriteBatch renderer that you should reset.
It might also be the color you are using for the background clear which has the alpha set to 0 rather than 1. Try using:
float BackgroundColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
Try working through a few of the DirectX Tool Kit tutorials to make sure things are working in isolation and so you understand how the classes work, specifically Drawing text.
You and me have the same problem with SpriteFont. We forgot to reset the VertexBuffers and all other rendering states after the call to SpriteFont. See my post and the solution from Chuck Walbourn: DirectX::SpriteFont/SpriteBatch prevents 3D scene from drawing.
To quote Chuck:
You set the render state up for your scene in InitScene, but drawing anything else changes the state which is exactly what SpriteBatch does. I document which render states each object in DirectX Toolkit manipulates on the wiki. You need to set all the state your Draw requires each frame, not assume it is set forever, if you do more than a single draw.
See my question for additional links providing more information.
I have followed a tutorial (i am newbie in opengl) and for some reason the triangle didn't show... I would appreciate any suggestions:).
It compiles with no warnings, glClearColor works if I change it, but no triangle is displayed.
#include "GphEditorWindow.h"
#include "gl\GL.h"
#include "gl\GLU.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR plCmdLine, int nCmdShow)
{
POINT windowPos = { 100, 100 };
POINT windowSize = { 800, 600 };
if (!editorWindow.Init(hInstance, windowPos, windowSize))
{
MessageBox(NULL, "EditorWindow init failed", "Graphite Editor", MB_OK | MB_ICONERROR);
return ERROR_APP_INIT_FAILURE;
}
else
{
return editorWindow.Run();
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return editorWindow.WndProc(hWnd, message, wParam, lParam);
}
LRESULT EditorWindow::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_SIZE:
RECT rect;
GetClientRect(hWnd, &rect);
workspaceWth = rect.right - rect.left;
workspaceHgh = rect.bottom - rect.top;
break;
default:
return (DefWindowProc(hWnd, message, wParam, lParam));
}
return 0L;
}
LRESULT EditorWindowGL::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
long result = EditorWindow::WndProc(hWnd, message, wParam, lParam);
switch (message)
{
case WM_CREATE:
if (!InitWGL(hWnd))
{
MessageBox(NULL, "Rendering Context Creation Failed!", "Graphite Editor", MB_OK | MB_ICONERROR);
return ERROR_APP_INIT_FAILURE;
}
SceneSetup(false);
ShowTitleBarInfo(hWnd);
break;
case WM_DESTROY:
DeleteWGL();
break;
case WM_SIZE:
SceneSetup(false);
break;
case WM_PAINT:
DrawScene();
ValidateRect(hWnd, NULL);
break;
}
return result;
}
bool EditorWindow::Init(HINSTANCE editorHandler, POINT editorWindowPos, POINT editorWindowSize)
{
char editorWindowName[] = "Graphite Editor";
WNDCLASSEX wc;
wc.cbSize = sizeof(wc);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = (WNDPROC)::WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = editorHandler;
wc.hIcon = NULL;
wc.hIconSm = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = NULL;
wc.lpszMenuName = NULL;
wc.lpszClassName = editorWindowName;
if (RegisterClassExA(&wc) == 0)
{
DWORD blah = GetLastError();
return false;
}
editorWindowHandler = CreateWindow(editorWindowName, editorWindowName, WS_OVERLAPPEDWINDOW, editorWindowPos.x, editorWindowPos.y, editorWindowSize.x, editorWindowSize.y, NULL, NULL, editorHandler, NULL);
if (editorWindowHandler == NULL)
return false;
ShowWindow(editorWindowHandler, SW_SHOW);
UpdateWindow(editorWindowHandler);
return true;
}
WPARAM EditorWindow::Run()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
bool EditorWindowGL::PixelFormatSet(HDC dcHandler) const
{
PIXELFORMATDESCRIPTOR pixelFormatDesc;
ZeroMemory(&pixelFormatDesc, sizeof(pixelFormatDesc));
pixelFormatDesc.nVersion = 1;
pixelFormatDesc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
pixelFormatDesc.iPixelType = PFD_TYPE_RGBA;
pixelFormatDesc.cColorBits = 32;
pixelFormatDesc.cDepthBits = 32;
pixelFormatDesc.iLayerType = PFD_MAIN_PLANE;
int pixelFormat = ChoosePixelFormat(dcHandler, &pixelFormatDesc);
if (pixelFormat == 0)
return false;
if (!SetPixelFormat(dcHandler, pixelFormat, &pixelFormatDesc))
return false;
return true;
}
bool EditorWindowGL::InitWGL(HWND windowHandler)
{
dcHandler = ::GetDC(windowHandler);
if (!PixelFormatSet(dcHandler))
return false;
rcHandler = wglCreateContext(dcHandler);
if (rcHandler == NULL)
return false;
if (!wglMakeCurrent(dcHandler, rcHandler))
return false;
return true;
}
void EditorWindowGL::DeleteWGL()
{
wglMakeCurrent(NULL, NULL);
wglDeleteContext(rcHandler);
::ReleaseDC(editorWindowHandler, dcHandler);
}
void EditorWindowGL::ShowTitleBarInfo(HWND windowHandler)
{
char buffer[256];
GetWindowText(windowHandler, buffer, 256);
const GLubyte* version = glGetString(GL_VERSION);
strcat_s(buffer, " | OpenGL");
strcat_s(buffer, (char*)version);
const GLubyte* vendor = glGetString(GL_VENDOR);
strcat_s(buffer, " | ");
strcat_s(buffer, (char*)vendor);
const GLubyte* gpu = glGetString(GL_RENDERER);
strcat_s(buffer, " | "); strcat_s(buffer, (char*)gpu);
SetWindowText(windowHandler, buffer);
}
void EditorWindowGL::SceneSetup(bool isometric)
{
glViewport(0, 0, workspaceWth, workspaceHgh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
float aspect = workspaceHgh / (float)workspaceWth;
if (!isometric)
glFrustum(-1.0f, 1.0f, aspect * -1.0f, aspect * 1.0f, 1.0f, 10.0f);
else
glOrtho(-1.0f, 1.0f, aspect * -1.0f, aspect * 1.0f, 1.0f, 10.0f);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_DEPTH_TEST);
}
void EditorWindowGL::DrawScene()
{
const float x0 = 1.0f;
const float y0 = 1.0f;
const float z0 = 1.0f;
glClearColor(0.125f, 0.125f, 0.125f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.0f);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES);
glVertex3f(-x0, -y0, 0.0f);
glVertex3f(x0, -y0, 1.0f);
glVertex3f(x0, y0, 0.0f);
glEnd();
SwapBuffers(dcHandler);
}
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 use gluPerspective to mainly increase the draw distance, but it doesn't seem to work.
This is how it shows in my code:
gluPerspective(0, 70/70, 0, 4333);
ratio: The window Width and Height is both 700 and they are constant, in case of wondering.
fovy: I put 0 because, "they" say that using 45 is very nice to draw, but it stops drawing on the screen.
This is the full code:
#include <Windows.h>
#include <gl\GL.h>
#include <gl/glut.h>
WNDCLASSEX wclass;
MSG msg;
HWND hwnd;
HDC hdc;
HDC p_hdc;
float t;
int red, green, blue, x, y, z;
void update()
{
RECT rec;
GetClientRect(hwnd, &rec);
InvalidateRect(hwnd, &rec, false);
UpdateWindow(hwnd);
t += 0.5f;
}
void game()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0, 0, 0, 0);
float norm = 1;
float z = 0;
red = 255;
green = 255;
glPushMatrix();
glRotatef(t, 0, 1, 1);
glBegin(GL_TRIANGLES);
glColor3f(255, 0, 0);
glVertex3f(-norm, norm, z);
glVertex3f(norm, norm, z);
glColor3f(0, 110, 10);
glVertex3f(-norm, -norm, z);
glEnd();
gluPerspective(45, 70/70, 0.01f, 4333);
glPopMatrix();
SwapBuffers(hdc);
}
HGLRC hrc;
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpstr, int nCmdShow)
{
wclass.cbSize = sizeof(WNDCLASSEX);
wclass.style = 0;
wclass.lpfnWndProc = WinProc;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hInstance = hInstance;
wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wclass.hbrBackground = (HBRUSH) (COLOR_WINDOW);
wclass.lpszMenuName = NULL;
wclass.lpszClassName = "CLASS";
wclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wclass))
{
MessageBox(0, "Windows Class Registration Failure Detected!\nProgram Can't Be Initialized..", "Failure Detected", MB_ICONERROR | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
0, "CLASS", "OPENGL WORLD", WS_OVERLAPPEDWINDOW,
0, 0, 700, 700,
HWND_DESKTOP, NULL, hInstance, NULL
);
EnableOpenGL(hwnd, &hdc, &hrc);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
if(hwnd == NULL)
{
MessageBox(0, "Windows Form Creation Failure..", "Failure", MB_ICONERROR | MB_OK);
}
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
SetTimer(hwnd, 1, 1, NULL);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_TIMER:
game();
update();
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC win;
win = BeginPaint(hwnd, &ps);
p_hdc = win;
game();
EndPaint(hwnd, &ps);
break;
default:
return DefWindowProc (hwnd, msg, wParam, lParam);
}
return 0;
}
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
*hDC = GetDC(hwnd);
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat(*hDC, &pfd);
SetPixelFormat(*hDC, iFormat, &pfd);
*hRC = wglCreateContext(*hDC);
wglMakeCurrent(*hDC, *hRC);
}
What to do?
EDIT: THE NEW CODE
#include <Windows.h>
#include <gl\GL.h>
#include <gl/glut.h>
WNDCLASSEX wclass;
MSG msg;
HWND hwnd;
HDC hdc;
HDC p_hdc;
float t;
int red, green, blue, x, y, z;
float cx, cy, cz;
void handle_resize()
{
RECT rec;
GetClientRect(hwnd, &rec);
long width = rec.right - rec.left;
long height = rec.top - rec.bottom;
float aspect = (float)width/(float)height;
glViewport(0, 0, 700, 700);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, aspect, 0.01f, 99999);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void update()
{
RECT rec;
GetClientRect(hwnd, &rec);
InvalidateRect(hwnd, &rec, false);
UpdateWindow(hwnd);
t += 0.5f;
cz = -3;
}
void game()
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float norm = 1;
float z = 0;
red = 255;
green = 255;
glPushMatrix();
glRotatef(t, 0, 1, 1);
glBegin(GL_TRIANGLES);
glColor3f(255, 0, 0);
glVertex3f(-norm, norm, z);
glVertex3f(norm, norm, z);
glColor3f(0, 110, 10);
glVertex3f(-norm, -norm, z);
glEnd();
glPopMatrix();
SwapBuffers(hdc);
}
HGLRC hrc;
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpstr, int nCmdShow)
{
wclass.cbSize = sizeof(WNDCLASSEX);
wclass.style = 0;
wclass.lpfnWndProc = WinProc;
wclass.cbClsExtra = 0;
wclass.cbWndExtra = 0;
wclass.hInstance = hInstance;
wclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wclass.hbrBackground = (HBRUSH) (COLOR_WINDOW);
wclass.lpszMenuName = NULL;
wclass.lpszClassName = "CLASS";
wclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wclass))
{
MessageBox(0, "Windows Class Registration Failure Detected!\nProgram Can't Be Initialized..", "Failure Detected", MB_ICONERROR | MB_OK);
return 0;
}
hwnd = CreateWindowEx(
0, "CLASS", "OPENGL WORLD", WS_OVERLAPPEDWINDOW,
0, 0, 700, 700,
HWND_DESKTOP, NULL, hInstance, NULL
);
EnableOpenGL(hwnd, &hdc, &hrc);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
glMatrixMode(GL_PROJECTION);
glMatrixMode(GL_MODELVIEW);
if(hwnd == NULL)
{
MessageBox(0, "Windows Form Creation Failure..", "Failure", MB_ICONERROR | MB_OK);
}
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CREATE:
SetTimer(hwnd, 1, 1, NULL);
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
case WM_TIMER:
game();
update();
break;
case WM_PAINT:
PAINTSTRUCT ps;
HDC win;
win = BeginPaint(hwnd, &ps);
p_hdc = win;
game();
EndPaint(hwnd, &ps);
break;
case WM_SIZE:
handle_resize();
break;
default:
return DefWindowProc (hwnd, msg, wParam, lParam);
}
return 0;
}
void EnableOpenGL(HWND hwnd, HDC* hDC, HGLRC* hRC)
{
PIXELFORMATDESCRIPTOR pfd;
int iFormat;
*hDC = GetDC(hwnd);
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
iFormat = ChoosePixelFormat(*hDC, &pfd);
SetPixelFormat(*hDC, iFormat, &pfd);
*hRC = wglCreateContext(*hDC);
wglMakeCurrent(*hDC, *hRC);
}
gluPerspective(0, 70/70, 0, 4333);
^ nope ^ nope
fovy and zNear must both be positive and non-zero.
Try this:
gluPerspective( 45, 70/70, 0.1, 4333 );
EDIT: Push your camera back a bit too:
#include <GL/glut.h>
float t = 0;
void timer( int val )
{
t += 0.5f;
glutTimerFunc( 10, timer, 0 );
glutPostRedisplay();
}
void display()
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
double w = glutGet( GLUT_WINDOW_WIDTH );
double h = glutGet( GLUT_WINDOW_HEIGHT );
gluPerspective( 45, w / h, 0.1, 4333.0 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glTranslatef( 0, 0, -5 );
float norm = 1;
float z = 0;
glPushMatrix();
glRotatef(t, 0, 1, 1);
glBegin(GL_TRIANGLES);
glColor3f(255, 0, 0);
glVertex3f(-norm, norm, z);
glVertex3f(norm, norm, z);
glColor3f(0, 110, 10);
glVertex3f(-norm, -norm, z);
glEnd();
glPopMatrix();
glutSwapBuffers();
}
int main( int argc, char **argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
glutInitWindowSize( 640, 480 );
glutCreateWindow( "GLUT" );
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0 );
glutMainLoop();
return 0;
}
As-per our comments, I made a few changes to your code that are necessary to properly deal with the perspective projection matrix and window sizing. There are still a number of things about this code that I do not like, such as drawing using a timer but this should at least address the small things.
New code:
void handle_resize (void)
{
RECT rec;
GetClientRect(hwnd, &rec);
long width = rec.right - rec.left;
long height = rec.top - rec.bottom;
float aspect = (float)width/(float)height;
glViewport (0, 0, width, height);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective (45, aspect, 0.01f, 4333);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
}
void game()
{
glClearColor(0, 0, 0, 0); // Do this first
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
float norm = 1;
float z = 0;
red = 255;
green = 255;
glMatrixMode (GL_MODELVIEW);
glPushMatrix();
glRotatef(t, 0, 1, 1);
glBegin(GL_TRIANGLES);
glColor3ub(255, 0, 0);
glVertex3f(-norm, norm, z);
glVertex3f(norm, norm, z);
glColor3ub(0, 110, 10);
glVertex3f(-norm, -norm, z);
glEnd();
//gluPerspective(45, 70/70, 0.01f, 4333); // GET THIS OUT OF HERE!!!
glPopMatrix();
SwapBuffers(hdc);
}
Changes to your window message handler:
switch (msg)
{
case WM_CREATE:
SetTimer(hwnd, 1, 1, NULL);
break;
// NEW EVENT: Handle window size change
case WM_SIZE:
handle_resize ();
break;
Other things to note:
glColor3f clamps the floating-point value to the range [0.0,1.0], you were using values of 255 which is only appropriate if you use glColor3ub, which is essentially the same thing as glColor3f (1.0f, 1.0f, 1.0f).