DirectX9 Access violation - c++

I'm not sure quite how to debug this, and I'd really appreciate some help.
When I exit the program using the X, I get the following error:
Unhandled exception at 0x00007FF854D4E797 (d3d9.dll) in directxtut.exe: 0xC0000005: Access violation reading location 0x0000000040400058.
The call stack shows the problem is occurring at line 195, d3d-Release();
Thanks in advance!
// include the basic windows header files and the Direct3D header file
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
#include <d3dx9.h>
// define the screen resolution
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
// include the Direct3D Library files
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
// global declarations
LPDIRECT3D9 d3d; // the pointer to the Direct3D interface
LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; // the pointer to the vertex buffer
LPDIRECT3DINDEXBUFFER9 i_buffer = NULL; // the pointer to the index buffer
// function prototypes
void initD3D(HWND hWnd); // sets up and initializes Direct3D
void render_frame(); // renders a single frame
void cleanD3D(); // closes Direct3D and releases memory
void init_graphics(); // 3D declarations
void init_light(); // sets up the light and the material
struct CUSTOMVERTEX {FLOAT X, Y, Z; D3DVECTOR NORMAL;};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL)
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
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 = "WindowClass";
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL, "WindowClass", "Jonathan's Direct3D Program",
WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT,
NULL, NULL, hInstance, NULL);
ShowWindow(hWnd, nCmdShow);
// set up and initialize Direct3D
initD3D(hWnd);
// enter the main loop:
MSG msg;
while(TRUE)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message == WM_QUIT)
break;
render_frame();
}
// clean up DirectX and COM
cleanD3D();
return msg.wParam;
}
// 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:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
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_X8R8G8B8;
d3dpp.BackBufferWidth = SCREEN_WIDTH;
d3dpp.BackBufferHeight = SCREEN_HEIGHT;
d3dpp.EnableAutoDepthStencil = TRUE; // automatically run the z-buffer
d3dpp.AutoDepthStencilFormat = D3DFMT_D16; // 16-bit pixel format for the z-buffer
// create a device class using this information and the info from the d3dpp stuct
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
init_graphics(); // call the function to initialize the models
init_light(); // call the function to initialize the light and material
d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE); // turn on the 3D lighting
d3ddev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // both sides of the triangles
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer
d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50)); //turn on ambient light
}
// this is the function used to render a single frame
void render_frame(void)
{
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->BeginScene();
// select which vertex format to use
d3ddev->SetFVF(CUSTOMFVF);
// set the view transform
D3DXMATRIX matView; // the view transform matrix
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (0.0f, 8.0f, 25.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); // set the view transform to matView
// set the projection transform
D3DXMATRIX matProjection; // the projection transform matrix
D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(45), // the horizontal field of view
(FLOAT)SCREEN_HEIGHT / (FLOAT)SCREEN_HEIGHT, // aspect ratio
1.0f, // the near view-plane
100.0f); // the far view-plane
d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection
// an ever-increasing float value
static float index = 0.0f;
index += 0.03f;
// set the world transform
D3DXMATRIX matRotateY; // a matrix to store the rotation for each triangle
D3DXMatrixRotationY(&matRotateY, index); // the rotation matrix
d3ddev->SetTransform(D3DTS_WORLD, &(matRotateY)); // set the world transform
// select the vertex buffer to display
d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
d3ddev->SetIndices(i_buffer);
// draw the model
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12);
d3ddev->EndScene();
d3ddev->Present(NULL, NULL, NULL, NULL);
}
// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
v_buffer->Release(); // close and release the vertex buffer
i_buffer->Release(); //close and release the index buffer
d3ddev->Release(); // close and release the 3D device
d3d->Release(); // close and release Direct3D *****HERE IS WHERE THE PROGRAM BREAKS*****
}
// this is the function that puts the 3D models into video RAM
void init_graphics(void)
{
// create the vertices using the CUSTOMVERTEX
struct CUSTOMVERTEX vertices[] =
{
{ -3.0f, -3.0f, 3.0f, 0.0f, 0.0f, 1.0f, }, // side 1
{ 3.0f, -3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },
{ -3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },
{ 3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },
{ -3.0f, -3.0f, -3.0f, 0.0f, 0.0f, -1.0f, }, // side 2
{ -3.0f, 3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },
{ 3.0f, -3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },
{ 3.0f, 3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },
{ -3.0f, 3.0f, -3.0f, 0.0f, 1.0f, 0.0f, }, // side 3
{ -3.0f, 3.0f, 3.0f, 0.0f, 1.0f, 0.0f, },
{ 3.0f, 3.0f, -3.0f, 0.0f, 1.0f, 0.0f, },
{ 3.0f, 3.0f, 3.0f, 0.0f, 1.0f, 0.0f, },
{ -3.0f, -3.0f, -3.0f, 0.0f, -1.0f, 0.0f, }, // side 4
{ 3.0f, -3.0f, -3.0f, 0.0f, -1.0f, 0.0f, },
{ -3.0f, -3.0f, 3.0f, 0.0f, -1.0f, 0.0f, },
{ 3.0f, -3.0f, 3.0f, 0.0f, -1.0f, 0.0f, },
{ 3.0f, -3.0f, -3.0f, 1.0f, 0.0f, 0.0f, }, // side 5
{ 3.0f, 3.0f, -3.0f, 1.0f, 0.0f, 0.0f, },
{ 3.0f, -3.0f, 3.0f, 1.0f, 0.0f, 0.0f, },
{ 3.0f, 3.0f, 3.0f, 1.0f, 0.0f, 0.0f, },
{ -3.0f, -3.0f, -3.0f, -1.0f, 0.0f, 0.0f, }, // side 6
{ -3.0f, -3.0f, 3.0f, -1.0f, 0.0f, 0.0f, },
{ -3.0f, 3.0f, -3.0f, -1.0f, 0.0f, 0.0f, },
{ -3.0f, 3.0f, 3.0f, -1.0f, 0.0f, 0.0f, },
};
// create a vertex buffer interface called v_buffer
d3ddev->CreateVertexBuffer(10*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
VOID* pVoid; // a void pointer
// lock v_buffer and load the vertices into it
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
// create the indices using an int array
short indices[] =
{
0, 1, 2, // side 1
2, 1, 3,
4, 5, 6, // side 2
6, 5, 7,
8, 9, 10, // side 3
10, 9, 11,
12, 13, 14, // side 4
14, 13, 15,
16, 17, 18, // side 5
18, 17, 19,
20, 21, 22, // side 6
22, 21, 23,
};
// create an index buffer interface called i_buffer
d3ddev->CreateIndexBuffer(18*sizeof(short),
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&i_buffer,
NULL);
//lock the i_buffer and load the indices into it
i_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, indices, sizeof(indices));
i_buffer->Unlock();
}
// this is the function that sets up the lights and materials
void init_light()
{
D3DLIGHT9 light; // create the light struct
D3DMATERIAL9 material; // create the material struct
ZeroMemory(&light, sizeof(light)); // clear out the light struct for use
light.Type = D3DLIGHT_DIRECTIONAL; // make the light type directional light
light.Diffuse = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f); // set the light's colour
light.Direction = D3DXVECTOR3(-1.0f, -0.3f, -1.0f); // set the light's direction
d3ddev->SetLight(0, &light); // send the light struct properties to light #0
d3ddev->LightEnable(0, TRUE); // turn on light #0
ZeroMemory(&material, sizeof(D3DMATERIAL9)); // clear out the struct for use
material.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); // set diffuse colour to white
material.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); // set ambient colour to white
d3ddev->SetMaterial(&material); // set the globally-used material to &material
}

Related

Toggle between ortho and perspective views in OpenGL?

I'm trying to create a toggle to change between ortho and perspective views. I have successfully coded buttons to initiate camera movement but can't figure out how to code a button to perform this change.
How I would toggle the projection modes here?
My code so far:
#include <iostream> // cout, cerr
#include <cstdlib> // EXIT_FAILURE
#include <GL/glew.h> // GLEW library
#include <GLFW/glfw3.h> // GLFW library
// GLM Math Header inclusions
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
#include <glm/gtc/type_ptr.hpp>
//Camera class
#include <learnOpengl/camera.h>
using namespace std; // Standard namespace
/*Shader program Macro*/
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version " core \n" #Source
#endif
// Unnamed namespace
namespace
{
const char* const WINDOW_TITLE = "Milestone 4-5"; // Macro for window title
// Variables for window width and height
const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 600;
// Stores the GL data relative to a given mesh
struct GLMesh
{
GLuint vao; // Handle for the vertex array object
GLuint vbo; // Handles for the vertex buffer objects
GLuint nVertices; // Number of indices of the mesh
};
// Main GLFW window
GLFWwindow* gWindow = nullptr;
// Triangle mesh data
GLMesh gMesh;
// Shader program
GLuint gProgramId;
// camera
Camera gCamera(glm::vec3(0.0f, 0.0f, 3.0f));
float gLastX = WINDOW_WIDTH / 2.0f;
float gLastY = WINDOW_HEIGHT / 2.0f;
bool gFirstMouse = true;
glm::vec3 gCameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 gCameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 gCameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
// timing
float gDeltaTime = 0.0f; // time between current frame and last frame
float gLastFrame = 0.0f;
}
/* User-defined Function prototypes to:
* initialize the program, set the window size,
* redraw graphics on the window when resized,
* and render graphics on the screen
*/
bool UInitialize(int, char* [], GLFWwindow** window);
void UResizeWindow(GLFWwindow* window, int width, int height);
void UProcessInput(GLFWwindow* window);
void UMousePositionCallback(GLFWwindow* window, double xpos, double ypos);
void UMouseScrollCallback(GLFWwindow* window, double xoffset, double yoffset);
void UMouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
void UCreateMesh(GLMesh& mesh);
void UDestroyMesh(GLMesh& mesh);
void URender();
bool UCreateShaderProgram(const char* vtxShaderSource, const char* fragShaderSource, GLuint& programId);
void UDestroyShaderProgram(GLuint programId);
/* Vertex Shader Source Code*/
const GLchar* vertexShaderSource = GLSL(440,
layout(location = 0) in vec3 position; // Vertex data from Vertex Attrib Pointer 0
layout(location = 1) in vec4 color; // Color data from Vertex Attrib Pointer 1
out vec4 vertexColor; // variable to transfer color data to the fragment shader
//Global variables for the transform matrices
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(position, 1.0f); // transforms vertices to clip coordinates
vertexColor = color; // references incoming color data
}
);
/* Fragment Shader Source Code*/
const GLchar* fragmentShaderSource = GLSL(440,
in vec4 vertexColor; // Variable to hold incoming color data from vertex shader
out vec4 fragmentColor;
void main()
{
fragmentColor = vec4(vertexColor);
}
);
int main(int argc, char* argv[])
{
if (!UInitialize(argc, argv, &gWindow))
return EXIT_FAILURE;
// Create the mesh
UCreateMesh(gMesh); // Calls the function to create the Vertex Buffer Object
// Create the shader program
if (!UCreateShaderProgram(vertexShaderSource, fragmentShaderSource, gProgramId))
return EXIT_FAILURE;
// Sets the background color of the window to black (it will be implicitly used by glClear)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// render loop
// -----------
while (!glfwWindowShouldClose(gWindow))
{
// per-frame timing
// --------------------
float currentFrame = glfwGetTime();
gDeltaTime = currentFrame - gLastFrame;
gLastFrame = currentFrame;
// input
// -----
UProcessInput(gWindow);
// Render this frame
URender();
glfwPollEvents();
}
// Release mesh data
UDestroyMesh(gMesh);
// Release shader program
UDestroyShaderProgram(gProgramId);
exit(EXIT_SUCCESS); // Terminates the program successfully
}
// Initialize GLFW, GLEW, and create a window
bool UInitialize(int argc, char* argv[], GLFWwindow** window)
{
// GLFW: initialize and configure
// ------------------------------
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
// GLFW: window creation
// ---------------------
* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE, NULL, NULL);
if (*window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return false;
}
glfwMakeContextCurrent(*window);
glfwSetFramebufferSizeCallback(*window, UResizeWindow);
glfwSetCursorPosCallback(*window, UMousePositionCallback);
glfwSetScrollCallback(*window, UMouseScrollCallback);
glfwSetMouseButtonCallback(*window, UMouseButtonCallback);
// tell GLFW to capture our mouse
glfwSetInputMode(*window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// GLEW: initialize
// ----------------
// Note: if using GLEW version 1.13 or earlier
glewExperimental = GL_TRUE;
GLenum GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult)
{
std::cerr << glewGetErrorString(GlewInitResult) << std::endl;
return false;
}
// Displays GPU OpenGL version
cout << "INFO: OpenGL Version: " << glGetString(GL_VERSION) << endl;
return true;
}
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
void UProcessInput(GLFWwindow* window)
{
static const float cameraSpeed = 2.5f;
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
gCamera.ProcessKeyboard(FORWARD, gDeltaTime);
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
gCamera.ProcessKeyboard(BACKWARD, gDeltaTime);
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
gCamera.ProcessKeyboard(LEFT, gDeltaTime);
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
gCamera.ProcessKeyboard(RIGHT, gDeltaTime);
if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
gCamera.ProcessKeyboard(UP, gDeltaTime);
if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
gCamera.ProcessKeyboard(DOWN, gDeltaTime);
}
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
void UResizeWindow(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
// glfw: whenever the mouse moves, this callback is called
// -------------------------------------------------------
void UMousePositionCallback(GLFWwindow* window, double xpos, double ypos)
{
if (gFirstMouse)
{
gLastX = xpos;
gLastY = ypos;
gFirstMouse = false;
}
float xoffset = xpos - gLastX;
float yoffset = gLastY - ypos; // reversed since y-coordinates go from bottom to top
gLastX = xpos;
gLastY = ypos;
gCamera.ProcessMouseMovement(xoffset, yoffset);
}
// glfw: whenever the mouse scroll wheel scrolls, this callback is called
// ----------------------------------------------------------------------
void UMouseScrollCallback(GLFWwindow* window, double xoffset, double yoffset)
{
gCamera.ProcessMouseScroll(yoffset);
}
// glfw: handle mouse button events
// --------------------------------
void UMouseButtonCallback(GLFWwindow* window, int button, int action, int mods)
{
switch (button)
{
case GLFW_MOUSE_BUTTON_LEFT:
{
if (action == GLFW_PRESS)
cout << "Left mouse button pressed" << endl;
else
cout << "Left mouse button released" << endl;
}
break;
case GLFW_MOUSE_BUTTON_MIDDLE:
{
if (action == GLFW_PRESS)
cout << "Middle mouse button pressed" << endl;
else
cout << "Middle mouse button released" << endl;
}
break;
case GLFW_MOUSE_BUTTON_RIGHT:
{
if (action == GLFW_PRESS)
cout << "Right mouse button pressed" << endl;
else
cout << "Right mouse button released" << endl;
}
break;
default:
cout << "Unhandled mouse button event" << endl;
break;
}
}
// Functioned called to render a frame
void URender()
{
// Enable z-depth
glEnable(GL_DEPTH_TEST);
// Clear the frame and z buffers
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// 1. Scales the object by 0.5
glm::mat4 scale = glm::scale(glm::vec3(0.5f, 0.5f, 0.5f));
// 2. Rotates shape by 37 degrees
glm::mat4 rotation = glm::rotate(37.0f, glm::vec3(1.0, 0.4f, 1.0f));
// 3. Place object at the origin
glm::mat4 translation = glm::translate(glm::vec3(0.0f, 0.0f, 0.0f));
// Model matrix: transformations are applied right-to-left order
glm::mat4 model = translation * rotation * scale;
// camera/view transformation
glm::mat4 view = gCamera.GetViewMatrix();
// Creates a perspective projection
glm::mat4 projection = glm::perspective(glm::radians(gCamera.Zoom), (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, 0.1f, 100.0f);
// Set the shader to be used
glUseProgram(gProgramId);
// Retrieves and passes transform matrices to the Shader program
GLint modelLoc = glGetUniformLocation(gProgramId, "model");
GLint viewLoc = glGetUniformLocation(gProgramId, "view");
GLint projLoc = glGetUniformLocation(gProgramId, "projection");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));
// Activate the VBOs contained within the mesh's VAO
glBindVertexArray(gMesh.vao);
// Draws the triangles
glDrawArrays(GL_TRIANGLES, 0, gMesh.nVertices);
// Deactivate the Vertex Array Object
glBindVertexArray(0);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
glfwSwapBuffers(gWindow); // Flips the the back buffer with the front buffer every frame.
}
// Implements the UCreateMesh function
void UCreateMesh(GLMesh& mesh)
{
// Position and Color data
GLfloat verts[] = {
// Vertex Positions // Colors (r,g,b,a)
2.8f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top right 0
2.8f, 0.2f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, // bottom right 1
-0.8f, 2.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top left 3
2.8f, 0.2f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, // bottom right 1
-0.8f, 0.2f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, // bottom left 2
-0.8f, 2.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top left 3
2.8f, 2.0f, -1.0f, 0.5f, 0.5f, 1.0f, 1.0f, // 4 back top right
2.8f, 0.2f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, // 5 back bot right
-0.8f, 2.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // 7 back top left
2.8f, 0.2f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, // 5 back bot right
-0.8f, 0.2f, -1.0f, 0.2f, 0.2f, 0.5f, 1.0f, // 6 back bot left
-0.8f, 2.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // 7 back top left
2.8f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top right 0
2.8f, 2.0f, -1.0f, 0.5f, 0.5f, 1.0f, 1.0f, // 4 back top right
-0.8f, 2.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // 7 back top left
2.8f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top right 0
-0.8f, 2.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top left 3
-0.8f, 2.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // 7 back top left
2.8f, 0.2f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, // bottom right 1
2.8f, 0.2f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, // 5 back bot right
-0.8f, 0.2f, -1.0f, 0.2f, 0.2f, 0.5f, 1.0f, // 6 back bot left
2.8f, 0.2f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, // bottom right 1
-0.8f, 0.2f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, // bottom left 2
-0.8f, 0.2f, -1.0f, 0.2f, 0.2f, 0.5f, 1.0f, // 6 back bot left
-0.8f, 0.2f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, // bottom left 2
-0.8f, 2.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top left 3
-0.8f, 2.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // 7 back top left
-0.8f, 0.2f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, // bottom left 2
-0.8f, 0.2f, -1.0, 0.2f, 0.2f, 0.5f, 1.0f, // 6 back bot left
-0.8f, 2.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // 7 back top left
2.8f, 2.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, // top right 0
2.8f, 0.2f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, // bottom right 1
2.8f, 2.0f, -1.0f, 0.5f, 0.5f, 1.0f, 1.0f, // 4 back top right
2.8f, 0.2f, 0.0f, 0.5f, 1.0f, 1.0f, 1.0f, // bottom right 1
2.8f, 2.0f, -1.0f, 0.5f, 0.5f, 1.0f, 1.0f, // 4 back top right
2.8f, 0.2f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f, // 5 back bot right
1.6f, 1.8f, 0.1f, 0.0f, 1.0f, 1.0f, 1.0f, // 8 top of vent pyramid
2.2f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 1.0f, // 9 right side of vent pyramid
1.5f, 1.2f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, // 11 center apex
1.6f, 0.2f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f, // 10 bottom of vent pyramid
2.2f, 1.0f, 0.1f, 1.0f, 0.0f, 1.0f, 1.0f, // 9 right side of vent pyramid
1.5f, 1.2f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, // 11 center apex
1.6f, 0.2f, 0.1f, 1.0f, 1.0f, 0.0f, 1.0f, // 10 bottom of vent pyramid
1.1f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f, // 12 left side of vent pyramid
1.5f, 1.2f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, // 11 center apex
1.1f, 1.0f, 0.1f, 0.0f, 1.0f, 0.0f, 1.0f, // 12 left side of vent pyramid
1.5f, 1.2f, 0.1f, 0.0f, 0.0f, 0.0f, 0.0f, // 11 center apex
1.6f, 1.8f, 0.1f, 0.0f, 1.0f, 1.0f, 1.0f, // 8 top of vent pyramid
-4.0f, 4.0f, -1.0f, 0.0f, 0.25f, 0.25f, 1.0f,
4.0f, 4.0f, -1.0f, 0.0f, 0.25f, 0.25f, 1.0f,
-4.0f, -4.0f, -1.0f, 0.0f, 0.25f, 0.25f, 1.0f,
4.0f, 4.0f, -1.0f, 0.0f, 0.25f, 0.25f, 1.0f,
4.0f, -4.0f, -1.0f, 0.0f, 0.25f, 0.25f, 1.0f,
-4.0f, -4.0f, -1.0f, 0.0f, 0.25f, 0.25f, 1.0f,
};
const GLuint floatsPerVertex = 3;
const GLuint floatsPerColor = 4;
mesh.nVertices = sizeof(verts) / (sizeof(verts[0]) * (floatsPerVertex + floatsPerColor));
glGenVertexArrays(1, &mesh.vao); // we can also generate multiple VAOs or buffers at the same time
glBindVertexArray(mesh.vao);
// Create VBO
glGenBuffers(1, &mesh.vbo);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo); // Activates the buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); // Sends vertex or coordinate data to the GPU
// Strides between vertex coordinates
GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);
// Create Vertex Attribute Pointers
glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
glEnableVertexAttribArray(1);
}
void UDestroyMesh(GLMesh& mesh)
{
glDeleteVertexArrays(1, &mesh.vao);
glDeleteBuffers(1, &mesh.vbo);
}
// Implements the UCreateShaders function
bool UCreateShaderProgram(const char* vtxShaderSource, const char* fragShaderSource, GLuint& programId)
{
// Compilation and linkage error reporting
int success = 0;
char infoLog[512];
// Create a Shader program object.
programId = glCreateProgram();
// Create the vertex and fragment shader objects
GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
// Retrive the shader source
glShaderSource(vertexShaderId, 1, &vtxShaderSource, NULL);
glShaderSource(fragmentShaderId, 1, &fragShaderSource, NULL);
// Compile the vertex shader, and print compilation errors (if any)
glCompileShader(vertexShaderId); // compile the vertex shader
// check for shader compile errors
glGetShaderiv(vertexShaderId, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShaderId, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
return false;
}
// compile the fragment shader
glCompileShader(fragmentShaderId);
// check for shader compile errors
glGetShaderiv(fragmentShaderId, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShaderId, sizeof(infoLog), NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
return false;
}
// Attached compiled shaders to the shader program
glAttachShader(programId, vertexShaderId);
glAttachShader(programId, fragmentShaderId);
glLinkProgram(programId); // links the shader program
// check for linking errors
glGetProgramiv(programId, GL_LINK_STATUS, &success);
if (!success)
{
glGetProgramInfoLog(programId, sizeof(infoLog), NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
return false;
}
glUseProgram(programId); // Uses the shader program
return true;
}
void UDestroyShaderProgram(GLuint programId)
{
glDeleteProgram(programId);
}
Simply change your
glm::mat4 projection = glm::perspective(glm::radians(gCamera.Zoom), (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, 0.1f, 100.0f);
to use glm::ortho depending on your game state.
You'll likely have to tinker a bit with the view projection as well.

DirectX::SpriteFont/SpriteBatch prevents 3D scene from drawing

I have a problem using DirectX::SpriteFont/DirectX::SpriteBatch (from DirectXTK; exactly the same problem as discussed here: Problems when drawing text using the SpriteFont class).
void DrawScene(void)
{
HRESULT hr;
float bgColor_a[4] = { 0.0f, 0.4f, 0.8f, 0.0f };
g_pDeviceContext->ClearRenderTargetView(g_pRenderTargetView, bgColor_a);
g_pDeviceContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
XMMATRIX cameraProj = XMLoadFloat4x4(&g_camera._cameraProjection);
XMVECTOR pos = XMLoadFloat3(&g_camera._pos);
XMVECTOR target = XMLoadFloat3(&g_camera._target);
XMVECTOR up = XMLoadFloat3(&g_camera._up);
XMMATRIX cameraView = XMMatrixLookAtLH(pos, target, up);
XMMATRIX worldBox2 = XMMatrixIdentity() * (XMMatrixTranslation(2.0f, 0.0f, 0.0f) * XMMatrixRotationY(XMConvertToRadians(g_rotBox2)));
XMMATRIX wvp = worldBox2 * cameraView * cameraProj;
XMMATRIX transposeWvp = XMMatrixTranspose(wvp);
XMStoreFloat4x4(&g_constantBufferPerObject._wvp, transposeWvp);
g_pDeviceContext->UpdateSubresource(g_pConstantBufferPerObject, 0, NULL, &g_constantBufferPerObject, 0, 0);
g_pDeviceContext->VSSetConstantBuffers(0, 1, &g_pConstantBufferPerObject);
g_pDeviceContext->PSSetShaderResources(0, 1, &g_pCageTexture);
g_pDeviceContext->PSSetSamplers(0, 1, &g_pCubeTextureSamplerState);
// box
g_pDeviceContext->DrawIndexed(36, 0, 0);
wchar_t buffer[32];
swprintf_s(buffer, 32, L"%.2f", g_fps._fps);
//g_pSpriteBatch->Begin();
//g_pSpriteFont->DrawString(g_pSpriteBatch, buffer, XMFLOAT2(30, 30));
//g_pSpriteBatch->End();
// Present the backbuffer to the screen
hr = g_pSwapChain->Present(0, 0);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot present without error.");
}
}
Without the calls to SpriteBatch::Begin(), SpriteFont::DrawString and SpriteBatch::End() you will see a textured cube rotating through space (a cage). With the calls to the described functions, you will only see the frames per second in the upper left corner, but no rotating cube.
I followed the tutorials from Chuck Walbourn on github DirectXTK and combined the 2 tutorials Draw String using SpriteFont and rendering a primitive 3D object (a simple triangle). In this example I will see the test string drawing over the triangle. But I do not understand why the rotating cube from my example is not visible while drawing a text string using SpriteFont class of DirectXTK and I cannot even find the root cause.
Pixel shader file (PixelShader.hlsl):
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
float2 TexCoord : TEXCOORD;
};
Texture2D ObjTexture;
SamplerState ObjSamplerState;
float4 PS( VS_OUTPUT input ) : SV_TARGET
{
float4 diffuse = ObjTexture.Sample(ObjSamplerState, input.TexCoord);
clip(diffuse.a - 0.25);
return diffuse;
}
Vertex shader file (VertexShader.hlsl):
cbuffer constantBufferPerObject
{
float4x4 WVP;
float ColorAdjust;
int Mode;
int Pad[2];
};
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
float2 TexCoord : TEXCOORD;
};
VS_OUTPUT VS( float4 pos : POSITION, float4 color : COLOR_ZERO, float4 color2 : COLOR_ONE, float2 texCoord : TEXCOORD )
{
VS_OUTPUT output;
float4 temp;
output.Pos = mul(pos, WVP);
temp = color;
output.Color.r = temp.r * color2.r * (1.0f - ColorAdjust);
output.Color.g = temp.g * color2.g * (1.0f - ColorAdjust);
output.Color.b = temp.b * color2.b * (1.0f - ColorAdjust);
output.Color.a = color.a * color2.a;
output.TexCoord = texCoord;
return output;
}
To reproduce the issue: I am working with Visual Studio 2015 Community Edition. I added DirectXTK (.lib) and DirectXTex (WICTextureLoader .cpp/.h, DDSTextureLoader .cpp/.h, .lib) to my project. Image for cube is .png with alpha.
Note: I created this duplicated question, to
avoid ... Asking for help, clarification, or responding to other answers.
on the other question.
First, as you are using DirectXTK, you don't need DirectXTex. DirectXTex is intended for texture processing tools, while DirectXTK texture loaders are more suited to use in applications. See this blog post.
Second, don't use the ancient timeGetTime function. You can use GetTickCount, although GetTickCount64 is better as it avoids overflow problems. For frame timing, however, these are not really precise enough. You should take a look at the StepTimer.h used in the DirectX Tool Kit tutorials.
Third, you should look at using Microsoft::WRL::ComPtr rather than all the SAFE_RELEASE macro stuff. See this page for details.
Your code was including xinput.h as well. You should take a look at using DirectX Tool Kit's GamePad instead which has a number of benefits. If nothing else, it uses XInput more robustly than you likely would.
With all that said, your problem is quite simple: 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.
void DrawScene(void)
{
HRESULT hr;
float bgColor_a[4] = { 0.0f, 0.4f, 0.8f, 0.0f };
g_pDeviceContext->ClearRenderTargetView(g_pRenderTargetView, bgColor_a);
g_pDeviceContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
//>>>> THESE WERE MOVED FROM INITSCENE ABOVE!
// Set Vertex and Pixel Shaders
g_pDeviceContext->VSSetShader(g_pVertexShader, 0, 0);
g_pDeviceContext->PSSetShader(g_pPixelShader, 0, 0);
// Set the vertex buffer
UINT stride = sizeof(SimpleVertex);
UINT offset = 0;
g_pDeviceContext->IASetVertexBuffers(0, 1, &g_pTriangleVertexBuffer, &stride, &offset);
g_pDeviceContext->IASetIndexBuffer(g_pSquareIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
// Set the Input Layout
g_pDeviceContext->IASetInputLayout(g_pVertexLayout);
// Set Primitive Topology
g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // 3 vertices per triangle
//g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); // 1 vertex per point
//g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); // 2 vertices per line
// Create the Viewport
g_pDeviceContext->RSSetState(g_pNoCullSolid);
//THESE WERE MOVED FROM INITSCENE ABOVE! <<<<
XMMATRIX cameraProj = XMLoadFloat4x4(&g_camera._cameraProjection);
XMVECTOR pos = XMLoadFloat3(&g_camera._pos);
XMVECTOR target = XMLoadFloat3(&g_camera._target);
XMVECTOR up = XMLoadFloat3(&g_camera._up);
XMMATRIX cameraView = XMMatrixLookAtLH(pos, target, up);
XMMATRIX worldBox2 = XMMatrixIdentity() * (XMMatrixTranslation(2.0f, 0.0f, 0.0f) * XMMatrixRotationY(XMConvertToRadians(g_rotBox2)));
XMMATRIX wvp = worldBox2 * cameraView * cameraProj;
XMMATRIX transposeWvp = XMMatrixTranspose(wvp);
XMStoreFloat4x4(&g_constantBufferPerObject._wvp, transposeWvp);
g_pDeviceContext->UpdateSubresource(g_pConstantBufferPerObject, 0, NULL, &g_constantBufferPerObject, 0, 0);
g_pDeviceContext->VSSetConstantBuffers(0, 1, &g_pConstantBufferPerObject);
g_pDeviceContext->PSSetShaderResources(0, 1, &g_pCageTexture);
g_pDeviceContext->PSSetSamplers(0, 1, &g_pCubeTextureSamplerState);
// box
g_pDeviceContext->DrawIndexed(36, 0, 0);
wchar_t buffer[32];
swprintf_s(buffer, 32, L"%.2f", g_fps._fps);
g_pSpriteBatch->Begin();
g_pSpriteFont->DrawString(g_pSpriteBatch, buffer, XMFLOAT2(30, 30));
g_pSpriteBatch->End();
// Present the backbuffer to the screen
hr = g_pSwapChain->Present(0, 0);
//>>>> This behavior means the app crashes if you hit a DEVICE_REMOVED or DEVICE_RESET.
if (FAILED(hr))
{
ErrorBoxW(L"Cannot present without error.");
}
}
You can generally 'set it and forget it' for the viewport state RSSetViewports which also implicitly sets the scissors state, but a better usage is to set it at the start of each frame when you do your initial Clear. This is the pattern I use in the Direct3D Game Templates.
Here is the complete code:
#include <Windows.h>
#include <stdio.h>
#include <Xinput.h>
#include <DirectXMath.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <DirectXTex.h>
#include <SpriteFont.h>
#include "DDSTextureLoader.h"
#include "WICTextureLoader.h"
using namespace DirectX;
#define CAMERA_ROTATION_SPEED (110.0f)
#define CAMERA_TARGET_DISTANCE (3.0f)
#define CAMERA_TARGET_VIEW_Y_START (-15.0f)
#define CAMERA_TARGET_VIEW_XZ_START (0.0f)
#define CAMERA_TARGET_START (XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f))
#define CAMERA_UP_START (XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f))
#define CAMERA_POS_START (XMVectorSet(0.0f, 0.0f, 3.0f, 0.0f))
#define PLAYER_MOVEMENT_SPEED (5.0f)
#define SAFE_DELETE(p) if (p) { delete (p); (p) = NULL; }
#define SAFE_RELEASE(p) if (p) { (p)->Release(); (p) = NULL; }
#ifdef _DEBUG
#define ErrorBoxW(msg) MessageBox(NULL, (msg), L"Error", MB_OK | MB_ICONERROR)
#else // _DEBUG
#define ErrorBox(msg)
#endif // _DEBUG
#define NORMALIZE_ANGLE(ang) { while ((ang) > 360.0f) { (ang) -= 360.0f; } while ((ang) < -360.0f) { (ang) += 360.0f; } }
#define LIMIT_ANGLE(ang, val) { if ((ang) > (val)) { (ang) = (val); } if ((ang) < -(val)) { (ang) = -(val); } }
#define CHECK_CHANGE_F(curr, prev, flag) { (flag) = (curr) != (prev); }
typedef struct _Camera
{
XMFLOAT3 _target;
XMFLOAT3 _pos;
XMFLOAT3 _up;
float _viewRotXZ;
float _viewRotY;
XMFLOAT4X4 _cameraProjection;
} Camera;
typedef struct _FPS
{
_FPS(void)
: _elapsedTime(0.0f), _frames(0), _fps(0.0f) {}
void Calc(float timeDelta)
{
_elapsedTime += timeDelta;
_frames++;
if (_elapsedTime >= 1.0f)
{
_fps = (float)_frames / _elapsedTime;
_elapsedTime = 0.0f;
_frames = 0;
#ifdef _DEBUG
wchar_t buffer[32];
swprintf_s(buffer, 32, L"FPS: %.2f\n", _fps);
OutputDebugString(buffer);
#endif // _DEBUG
}
}
float _fps;
float _elapsedTime;
int _frames;
} FPS;
typedef struct _Player
{
_Player(void)
: _moveX(0.0f), _moveY(0.0f), _moveZ(0.0f) {}
float _moveX;
float _moveY;
float _moveZ;
} Player;
using namespace DirectX;
typedef struct _SimpleVertex
{
_SimpleVertex() {}
_SimpleVertex(float x, float y, float z, float cr, float cg, float cb, float ca, float cr2, float cg2, float cb2, float ca2, float u, float v)
: _pos(x, y, z), _color0(cr, cg, cb, ca), _color1(cr2, cg2, cb2, ca2), _tex(u, v) {}
XMFLOAT3 _pos;
XMFLOAT4 _color0;
XMFLOAT4 _color1;
XMFLOAT2 _tex;
} SimpleVertex;
// sizeof(ConstantBufferPerObject) = 80; multiple of 16
typedef struct _ConstantBufferPerObject
{
XMFLOAT4X4 _wvp; // sizeof(XMFLOAT4X4) = 64
float _colorAdjust; // sizeof(float) = 4; 68
int _mode; // sizeof(int) = 4; 72
int _pad[2]; // 2 * sizeof(int) = 8; 80
} ConstantBufferPerObject;
LPWSTR const g_windowClassName = L"dx11demo";
LPWSTR const g_windowTitle = L"DirectX11Demo";
HWND g_hwnd = NULL;
HINSTANCE g_hinstance = NULL;
const int g_width = 800;
const int g_height = 600;
IDXGISwapChain *g_pSwapChain = NULL;
ID3D11Device *g_pDevice = NULL;
ID3D11DeviceContext *g_pDeviceContext = NULL;
ID3D11RenderTargetView *g_pRenderTargetView = NULL;
ID3D11Buffer *g_pTriangleVertexBuffer = NULL;
ID3D11Buffer *g_pSquareIndexBuffer = NULL;
ID3D11VertexShader *g_pVertexShader = NULL;
ID3D11PixelShader *g_pPixelShader = NULL;
ID3DBlob *g_pVertexShaderBuffer = NULL;
ID3DBlob *g_pPixelShaderBuffer = NULL;
ID3D11DepthStencilView *g_pDepthStencilView = NULL;
ID3D11Buffer *g_pConstantBufferPerObject = NULL;
ID3D11Texture2D *g_pDepthStencilBuffer = NULL;
ID3D11InputLayout *g_pVertexLayout = NULL;
ID3D11ShaderResourceView *g_pCageTexture = NULL;
ID3D11ShaderResourceView *g_pBrickTexture = NULL;
ID3D11SamplerState *g_pCubeTextureSamplerState = NULL;
bool g_solid = true;
float g_rotBox2 = 0.0f;
ID3D11RasterizerState *g_pNoCullSolid = NULL;
ID3D11RasterizerState *g_pNoCullWireframe = NULL;
ID3D11RasterizerState *g_pCWCullSolid = NULL;
ID3D11RasterizerState *g_pCCWCullSolid = NULL;
ID3D11BlendState *g_pTransparency = NULL;
SpriteBatch *g_pSpriteBatch = NULL;
SpriteFont *g_pSpriteFont = NULL;
D3D11_INPUT_ELEMENT_DESC g_layout_a[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR_ZERO", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR_ONE", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 44, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT g_numElements = ARRAYSIZE(g_layout_a);
bool g_isMoving = true;
ConstantBufferPerObject g_constantBufferPerObject;
bool g_enableDraw = true;
Player g_player;
Camera g_camera;
FPS g_fps;
void CleanUp(void);
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
bool InitD3D11(void);
bool InitScene(void);
void DrawScene(void);
void UpdateScene(float);
void UpdateScene(float timeDelta)
{
g_rotBox2 += 20.0f * timeDelta;
NORMALIZE_ANGLE(g_rotBox2);
}
void DrawScene(void)
{
HRESULT hr;
float bgColor_a[4] = { 0.0f, 0.4f, 0.8f, 0.0f };
g_pDeviceContext->ClearRenderTargetView(g_pRenderTargetView, bgColor_a);
g_pDeviceContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
XMMATRIX cameraProj = XMLoadFloat4x4(&g_camera._cameraProjection);
XMVECTOR pos = XMLoadFloat3(&g_camera._pos);
XMVECTOR target = XMLoadFloat3(&g_camera._target);
XMVECTOR up = XMLoadFloat3(&g_camera._up);
XMMATRIX cameraView = XMMatrixLookAtLH(pos, target, up);
XMMATRIX worldBox2 = XMMatrixIdentity() * (XMMatrixTranslation(2.0f, 0.0f, 0.0f) * XMMatrixRotationY(XMConvertToRadians(g_rotBox2)));
XMMATRIX wvp = worldBox2 * cameraView * cameraProj;
XMMATRIX transposeWvp = XMMatrixTranspose(wvp);
XMStoreFloat4x4(&g_constantBufferPerObject._wvp, transposeWvp);
g_pDeviceContext->UpdateSubresource(g_pConstantBufferPerObject, 0, NULL, &g_constantBufferPerObject, 0, 0);
g_pDeviceContext->VSSetConstantBuffers(0, 1, &g_pConstantBufferPerObject);
g_pDeviceContext->PSSetShaderResources(0, 1, &g_pCageTexture);
g_pDeviceContext->PSSetSamplers(0, 1, &g_pCubeTextureSamplerState);
// box
g_pDeviceContext->DrawIndexed(36, 0, 0);
wchar_t buffer[32];
swprintf_s(buffer, 32, L"%.2f", g_fps._fps);
//g_pSpriteBatch->Begin();
//g_pSpriteFont->DrawString(g_pSpriteBatch, buffer, XMFLOAT2(30, 30));
//g_pSpriteBatch->End();
// Present the backbuffer to the screen
hr = g_pSwapChain->Present(0, 0);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot present without error.");
}
}
bool InitScene(void)
{
HRESULT hr;
ID3DBlob *pErrorBlob = NULL;
UINT flags = D3DCOMPILE_ENABLE_STRICTNESS;
#ifdef _DEBUG
flags |= D3DCOMPILE_DEBUG;
#endif // _DEBUG
const D3D_SHADER_MACRO defines_a[] =
{
{ NULL, NULL }
};
// Compile Shaders from shader file
// https://msdn.microsoft.com/de-de/library/windows/desktop/hh968107(v=vs.85).aspx
hr = D3DCompileFromFile(L"VertexShader.hlsl", defines_a, D3D_COMPILE_STANDARD_FILE_INCLUDE, "VS", "vs_5_0", flags, 0, &g_pVertexShaderBuffer, &pErrorBlob);
if (FAILED(hr))
{
SAFE_RELEASE(pErrorBlob);
ErrorBoxW(L"Cannot compile vertex shader VS vs_5_0.");
return false;
}
hr = D3DCompileFromFile(L"PixelShader.hlsl", defines_a, D3D_COMPILE_STANDARD_FILE_INCLUDE, "PS", "ps_5_0", flags, 0, &g_pPixelShaderBuffer, &pErrorBlob);
if (FAILED(hr))
{
SAFE_RELEASE(pErrorBlob);
ErrorBoxW(L"Cannot compile pixel shader PS ps_5_0.");
return false;
}
// Create the Shader Objects
hr = g_pDevice->CreateVertexShader(g_pVertexShaderBuffer->GetBufferPointer(), g_pVertexShaderBuffer->GetBufferSize(), NULL, &g_pVertexShader);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create vertex shader.");
return false;
}
hr = g_pDevice->CreatePixelShader(g_pPixelShaderBuffer->GetBufferPointer(), g_pPixelShaderBuffer->GetBufferSize(), NULL, &g_pPixelShader);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create pixel shader.");
return false;
}
// Set Vertex and Pixel Shaders
g_pDeviceContext->VSSetShader(g_pVertexShader, 0, 0);
g_pDeviceContext->PSSetShader(g_pPixelShader, 0, 0);
// Create the vertex buffer (vertices must be in clock-wise order)
SimpleVertex vertices_a[] =
{
// Front Face
/* 11 */ SimpleVertex(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
/* 12 */ SimpleVertex(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
/* 13 */ SimpleVertex(1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
/* 14 */ SimpleVertex(1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
// Back Face
/* 15 */ SimpleVertex(-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
/* 16 */ SimpleVertex(1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
/* 17 */ SimpleVertex(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
/* 18 */ SimpleVertex(-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
// Top Face
/* 19 */ SimpleVertex(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
/* 20 */ SimpleVertex(-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
/* 21 */ SimpleVertex(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
/* 22 */ SimpleVertex(1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
// Bottom Face
/* 23 */ SimpleVertex(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
/* 24 */ SimpleVertex(1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
/* 25 */ SimpleVertex(1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
/* 26 */ SimpleVertex(-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
// Left Face
/* 27 */ SimpleVertex(-1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
/* 28 */ SimpleVertex(-1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
/* 29 */ SimpleVertex(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
/* 30 */ SimpleVertex(-1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
// Right Face
/* 31 */ SimpleVertex(1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 3.0f),
/* 32 */ SimpleVertex(1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f),
/* 33 */ SimpleVertex(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 0.0f),
/* 34 */ SimpleVertex(1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 3.0f, 3.0f),
};
D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof(SimpleVertex) * 24;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vertexBufferData;
ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
vertexBufferData.pSysMem = vertices_a;
hr = g_pDevice->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &g_pTriangleVertexBuffer);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create triangle buffer.");
return false;
}
// Set the vertex buffer
UINT stride = sizeof(SimpleVertex);
UINT offset = 0;
g_pDeviceContext->IASetVertexBuffers(0, 1, &g_pTriangleVertexBuffer, &stride, &offset);
DWORD indices_a[] =
{
// Front Face
/* 5 */ 0, 1, 2,
/* 6 */ 0, 2, 3,
// Back Face
/* 7 */ 4, 5, 6,
/* 8 */ 4, 6, 7,
// Top Face
/* 9 */ 8, 9, 10,
/* 10 */ 8, 10, 11,
// Bottom Face
/* 11 */ 12, 13, 14,
/* 12 */ 12, 14, 15,
// Left Face
/* 13 */ 16, 17, 18,
/* 14 */ 16, 18, 19,
// Right Face
/* 15 */ 20, 21, 22,
/* 16 */ 20, 22, 23,
};
D3D11_BUFFER_DESC indexBufferDesc;
ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc));
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(DWORD) * 12 * 3;
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
indexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA iinitData;
ZeroMemory(&iinitData, sizeof(D3D11_SUBRESOURCE_DATA));
iinitData.pSysMem = indices_a;
hr = g_pDevice->CreateBuffer(&indexBufferDesc, &iinitData, &g_pSquareIndexBuffer);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create index buffer.");
return false;
}
g_pDeviceContext->IASetIndexBuffer(g_pSquareIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
// Create the Input Layout
hr = g_pDevice->CreateInputLayout(g_layout_a, g_numElements, g_pVertexShaderBuffer->GetBufferPointer(), g_pVertexShaderBuffer->GetBufferSize(), &g_pVertexLayout);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create input layout.");
return false;
}
// Set the Input Layout
g_pDeviceContext->IASetInputLayout(g_pVertexLayout);
// Set Primitive Topology
g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); // 3 vertices per triangle
//g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_POINTLIST); // 1 vertex per point
//g_pDeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_LINELIST); // 2 vertices per line
// Create the Viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = g_width; // divide by 4 to only use 1/4 of client area (width)
viewport.Height = g_height; // divide by 4 to only use 1/4 of client area (height)
viewport.MinDepth = 0.0f;
viewport.MaxDepth = 1.0f;
//Set the Viewport
g_pDeviceContext->RSSetViewports(1, &viewport);
// Create the buffer to send to the cbuffer in effect file
D3D11_BUFFER_DESC constantBufferDesc;
ZeroMemory(&constantBufferDesc, sizeof(D3D11_BUFFER_DESC));
constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
constantBufferDesc.ByteWidth = sizeof(ConstantBufferPerObject);
constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDesc.CPUAccessFlags = 0;
constantBufferDesc.MiscFlags = 0;
hr = g_pDevice->CreateBuffer(&constantBufferDesc, NULL, &g_pConstantBufferPerObject);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create constant buffer.");
return false;
}
D3D11_RASTERIZER_DESC rasterizerDesc;
ZeroMemory(&rasterizerDesc, sizeof(D3D11_RASTERIZER_DESC));
rasterizerDesc.FillMode = D3D11_FILL_SOLID;
rasterizerDesc.CullMode = D3D11_CULL_NONE;
rasterizerDesc.FrontCounterClockwise = true;
hr = g_pDevice->CreateRasterizerState(&rasterizerDesc, &g_pNoCullSolid);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create rasterizer state (no culling, solid).");
return false;
}
rasterizerDesc.FillMode = D3D11_FILL_WIREFRAME;
hr = g_pDevice->CreateRasterizerState(&rasterizerDesc, &g_pNoCullWireframe);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create rasterizer state (no culling, wireframe).");
return false;
}
g_pDeviceContext->RSSetState(g_pNoCullSolid);
hr = CreateWICTextureFromFile(g_pDevice, L"tcage.png", NULL, &g_pCageTexture);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create shader resource view (cage).");
return false;
}
D3D11_SAMPLER_DESC sampDesc;
ZeroMemory(&sampDesc, sizeof(sampDesc));
sampDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
sampDesc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
sampDesc.ComparisonFunc = D3D11_COMPARISON_NEVER;
sampDesc.MinLOD = 0;
sampDesc.MaxLOD = D3D11_FLOAT32_MAX;
hr = g_pDevice->CreateSamplerState(&sampDesc, &g_pCubeTextureSamplerState);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create sampler state.");
return false;
}
D3D11_BLEND_DESC blendDesc; // Define the Blending Equation
ZeroMemory(&blendDesc, sizeof(blendDesc));
D3D11_RENDER_TARGET_BLEND_DESC rtbd;
ZeroMemory(&rtbd, sizeof(rtbd));
rtbd.BlendEnable = true;
rtbd.SrcBlend = D3D11_BLEND_SRC_COLOR;
rtbd.DestBlend = D3D11_BLEND_BLEND_FACTOR;
rtbd.BlendOp = D3D11_BLEND_OP_ADD;
rtbd.SrcBlendAlpha = D3D11_BLEND_ONE;
rtbd.DestBlendAlpha = D3D11_BLEND_ZERO;
rtbd.BlendOpAlpha = D3D11_BLEND_OP_ADD;
rtbd.RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
blendDesc.AlphaToCoverageEnable = false;
blendDesc.RenderTarget[0] = rtbd;
hr = g_pDevice->CreateBlendState(&blendDesc, &g_pTransparency);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create blend state.");
return false;
}
// Create the Counter Clockwise and Clockwise Culling States
D3D11_RASTERIZER_DESC cmdesc;
ZeroMemory(&cmdesc, sizeof(D3D11_RASTERIZER_DESC));
cmdesc.FillMode = D3D11_FILL_SOLID;
cmdesc.CullMode = D3D11_CULL_BACK;
cmdesc.FrontCounterClockwise = true;
hr = g_pDevice->CreateRasterizerState(&cmdesc, &g_pCCWCullSolid);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create ccw cull mode.");
return false;
}
cmdesc.FrontCounterClockwise = false;
hr = g_pDevice->CreateRasterizerState(&cmdesc, &g_pCWCullSolid);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create cw cull mode.");
return false;
}
g_pSpriteBatch = new SpriteBatch(g_pDeviceContext);
if (!g_pSpriteBatch)
{
ErrorBoxW(L"Cannot create sprite batch.");
return false;
}
g_pSpriteFont = new SpriteFont(g_pDevice, L"arial.font");
if (!g_pSpriteFont)
{
ErrorBoxW(L"Cannot create sprite font.");
return false;
}
XMStoreFloat3(&g_camera._target, CAMERA_TARGET_START);
XMStoreFloat3(&g_camera._pos, CAMERA_POS_START);
XMStoreFloat3(&g_camera._up, CAMERA_UP_START);
g_camera._viewRotXZ = CAMERA_TARGET_VIEW_XZ_START;
g_camera._viewRotY = CAMERA_TARGET_VIEW_Y_START;
// Set the Projection matrix
XMStoreFloat4x4(&g_camera._cameraProjection, XMMatrixPerspectiveFovLH(XMConvertToRadians(45.0f), (float)g_width / (float)g_height, 0.1f, 1000.0f));
return true;
}
bool InitD3D11(void)
{
HRESULT hr;
DXGI_MODE_DESC bufferDesc; // Describe our Buffer
ZeroMemory(&bufferDesc, sizeof(DXGI_MODE_DESC));
bufferDesc.Width = g_width;
bufferDesc.Height = g_height;
bufferDesc.RefreshRate.Numerator = 60;
bufferDesc.RefreshRate.Denominator = 1;
bufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
bufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
bufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
DXGI_SWAP_CHAIN_DESC swapChainDesc; // Describe our SwapChain
ZeroMemory(&swapChainDesc, sizeof(DXGI_SWAP_CHAIN_DESC));
swapChainDesc.BufferDesc = bufferDesc;
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.SampleDesc.Quality = 0;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferCount = 1;
swapChainDesc.OutputWindow = g_hwnd;
swapChainDesc.Windowed = TRUE;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
//Create our SwapChain
hr = D3D11CreateDeviceAndSwapChain(
NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
D3D11_CREATE_DEVICE_DEBUG,
NULL,
NULL,
D3D11_SDK_VERSION,
&swapChainDesc,
&g_pSwapChain,
&g_pDevice,
NULL,
&g_pDeviceContext);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create swap chain, device and device context.");
return false;
}
ID3D11Texture2D* backBuffer; // Create our BackBuffer
hr = g_pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void **)&backBuffer);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create back buffer.");
return false;
}
// Create our Render Target
hr = g_pDevice->CreateRenderTargetView(backBuffer, NULL, &g_pRenderTargetView);
SAFE_RELEASE(backBuffer); // release back buffer in any case
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create render target view.");
return false;
}
D3D11_TEXTURE2D_DESC depthStencilDesc; // Describe our Depth/Stencil Buffer
ZeroMemory(&depthStencilDesc, sizeof(D3D11_TEXTURE2D_DESC));
depthStencilDesc.Width = g_width;
depthStencilDesc.Height = g_height;
depthStencilDesc.MipLevels = 1;
depthStencilDesc.ArraySize = 1;
depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthStencilDesc.SampleDesc.Count = 1;
depthStencilDesc.SampleDesc.Quality = 0;
depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthStencilDesc.CPUAccessFlags = 0;
depthStencilDesc.MiscFlags = 0;
// Create the Depth/Stencil View
hr = g_pDevice->CreateTexture2D(&depthStencilDesc, NULL, &g_pDepthStencilBuffer);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create depth stencil buffer.");
return false;
}
hr = g_pDevice->CreateDepthStencilView(g_pDepthStencilBuffer, NULL, &g_pDepthStencilView);
if (FAILED(hr))
{
ErrorBoxW(L"Cannot create depth stencil view.");
return false;
}
// Set our Render Target
g_pDeviceContext->OMSetRenderTargets(1, &g_pRenderTargetView, g_pDepthStencilView);
return true;
}
void CleanUp(void)
{
SAFE_RELEASE(g_pDevice);
SAFE_RELEASE(g_pDeviceContext);
SAFE_RELEASE(g_pPixelShader);
SAFE_RELEASE(g_pPixelShaderBuffer);
SAFE_RELEASE(g_pRenderTargetView);
SAFE_RELEASE(g_pSwapChain);
SAFE_RELEASE(g_pTriangleVertexBuffer);
SAFE_RELEASE(g_pVertexLayout);
SAFE_RELEASE(g_pVertexShader);
SAFE_RELEASE(g_pVertexShaderBuffer);
SAFE_RELEASE(g_pSquareIndexBuffer);
SAFE_RELEASE(g_pDepthStencilBuffer);
SAFE_RELEASE(g_pDepthStencilView);
SAFE_RELEASE(g_pConstantBufferPerObject);
SAFE_RELEASE(g_pNoCullSolid);
SAFE_RELEASE(g_pNoCullWireframe);
SAFE_RELEASE(g_pCageTexture);
SAFE_RELEASE(g_pBrickTexture);
SAFE_RELEASE(g_pCubeTextureSamplerState);
SAFE_RELEASE(g_pTransparency);
SAFE_RELEASE(g_pCWCullSolid);
SAFE_RELEASE(g_pCCWCullSolid);
SAFE_DELETE(g_pSpriteBatch);
SAFE_DELETE(g_pSpriteFont);
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
// Check message
switch (msg)
{
case WM_KEYDOWN:
// if escape key was pressed, display popup box
if (wParam == VK_ESCAPE)
{
if (MessageBox(0, L"Are you sure you want to exit?", L"Really?", MB_YESNO | MB_ICONQUESTION) == IDYES)
{
// Release the windows allocated memory
DestroyWindow(hwnd);
}
}
return 0;
case WM_DESTROY:
// if x button in top right was pressed
PostQuitMessage(0);
return 0;
}
// return the message for windows to handle it
return DefWindowProc(hwnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
UNREFERENCED_PARAMETER(lpCmdLine);
UNREFERENCED_PARAMETER(hPrevInstance);
g_hinstance = hInstance;
WNDCLASSEX wc; // Create a new extended windows class
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX); // Size of our windows class
wc.style = CS_HREDRAW | CS_VREDRAW; // class styles
wc.lpfnWndProc = WndProc; // Default windows procedure function
wc.cbClsExtra = NULL; // Extra bytes after our wc structure
wc.cbWndExtra = NULL; // Extra bytes after our windows instance
wc.hInstance = hInstance; // Instance to current application
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); // Title bar Icon
wc.hCursor = LoadCursor(NULL, IDC_ARROW); // Default mouse Icon
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2); // Window bg color
wc.lpszMenuName = NULL; // Name of the menu attached to our window
wc.lpszClassName = g_windowClassName; // Name of our windows class
wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO); // Icon in your taskbar
if (!RegisterClassEx(&wc)) // Register our windows class
{
ErrorBoxW(L"Error registering class");
return 1;
}
// Create our Extended Window
g_hwnd = CreateWindowEx(
NULL, // Extended style
g_windowClassName, // Name of our windows class
g_windowTitle, // Name in the title bar of our window
WS_OVERLAPPEDWINDOW ^ (WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX), // style of our window
CW_USEDEFAULT, CW_USEDEFAULT, // Top left corner of window
g_width, // Width of our window
g_height, // Height of our window
NULL, // Handle to parent window
NULL, // Handle to a Menu
hInstance, // Specifies instance of current program
NULL // used for an MDI client window
);
// Make sure our window has been created
if (!g_hwnd)
{
ErrorBoxW(L"Error creating window");
return 1;
}
ShowWindow(g_hwnd, nShowCmd); // Shows our window
UpdateWindow(g_hwnd); // Its good to update our window
bool result;
result = InitD3D11();
if (result)
{
result = InitScene();
if (result)
{
MSG msg; // Create a new message structure
ZeroMemory(&msg, sizeof(MSG));
DWORD timeLast = timeGetTime();
DWORD timeCurr = timeLast;
float timeDelta = 0.0f;
bool run = true;
//float elapsed = 0.0f;
//float frameLimit = 1.0f / 60.0f;
while (run)
{
// if there was a windows message
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
// if the message was WM_QUIT
if (msg.message == WM_QUIT)
{
run = false; // Exit the message loop
}
TranslateMessage(&msg); // Translate the message
DispatchMessage(&msg); // Send the message to default windows procedure
}
timeCurr = timeGetTime();
timeDelta = (float)(timeCurr - timeLast) / 1000.0f;
//elapsed += timeDelta;
//if (elapsed >= frameLimit)
//{
g_fps.Calc(timeDelta);
UpdateScene(timeDelta);
DrawScene();
//elapsed = 0.0f;
//}
timeLast = timeCurr;
}
}
}
CleanUp();
return 0; // return the message
}
Scene without SpriteFont
Scene with SpriteFont

directx 9 : basic lighting on c++ 6?

i have a source code :
here's the initialization
//The Direct3d and device object
IDirect3D9 *g_pD3D = NULL;
IDirect3DDevice9 *g_pD3DDevice = NULL;
//the 3-D vertex format and descriptor
typedef struct
{
FLOAT x, y, z; //3-D coordinates
FLOAT nx, ny, nz; //Normals
D3DCOLOR Diffuse; //Colors
}sVertex;
#define VERTEXFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_NORMAL)
//Vertex buffer
IDirect3DVertexBuffer9 *g_pVB = NULL;
sVertex Verts[16] =
{
{-100.f, 100.0f, -100.0f, 0.0f, 0.0f, -1.0f, D3DCOLOR_RGBA(255,255,255,255)},
{ 100.f, 100.0f, -100.0f, 0.0f, 0.0f, -1.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ -100.f, -100.0f, -100.0f, 0.0f, 0.0f, -1.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ 100.f, -100.0f, -100.0f, 0.0f, 0.0f, -1.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ 100.f, 100.0f, -100.0f, 1.0f, 0.0f, 0.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ 100.f, 100.0f, 100.0f, 1.0f, 0.0f, 0.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ 100.f, -100.0f, -100.0f, 1.0f, 0.0f, 0.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ 100.f, -100.0f, 100.0f, 1.0f, 0.0f, -1.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ 100.f, 100.0f, 100.0f, 0.0f, 0.0f, 1.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ -100.f, 100.0f, 100.0f, 0.0f, 0.0f, 1.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ 100.f, -100.0f, 100.0f, 0.0f, 0.0f, 1.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ -100.f, -100.0f, 100.0f, 0.0f, 0.0f, 1.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ -100.f, 100.0f, 100.0f, -1.0f, 0.0f, 0.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ -100.f, 100.0f, -100.0f, -1.0f, 0.0f, 0.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ -100.f, -100.0f, 100.0f, -1.0f, 0.0f, 0.0f, D3DCOLOR_RGBA(255, 255, 255, 255) },
{ -100.f, -100.0f, -100.0f, -1.0f, 0.0f, 0.0f, D3DCOLOR_RGBA(255, 255, 255, 255) }
};
here's the init function
BOOL DoInit()
{
//perform application initialization functions here
//such as those that set up the graphics, sound, network, etc
//Return a value of TRUE for success, FALSE otherwise.
D3DPRESENT_PARAMETERS d3dpp;
D3DDISPLAYMODE d3ddm;
D3DXMATRIX matProj, matView;
D3DLIGHT9 Light;
BYTE *Ptr;
sVertex Verts[16];
//do a windowed mode initialization of Direct3D
if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL)
return FALSE;
if (FAILED(g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
return FALSE;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
if (FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pD3DDevice)))
return FALSE;
//set the rendering states
g_pD3DDevice->SetRenderState(D3DRS_LIGHTING, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
//create and set the view matrix
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3(0.0f, 0.0f, -500.0f),
&D3DXVECTOR3(0.0f, 0.0f, 0.0f),
&D3DXVECTOR3(0.0f, 1.0f,0.0f));
g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
//create the vertex buffer and set data
g_pD3DDevice->CreateVertexBuffer(sizeof(sVertex)* 16, 0, VERTEXFVF, D3DPOOL_DEFAULT, &g_pVB, 0);
g_pVB->Lock(0, 0, (VOID**)&Ptr, 0);
memcpy(Ptr, Verts, sizeof(Verts));
g_pVB->Unlock();
//set light data, color, position, and range
ZeroMemory(&Light, sizeof(Light));
Light.Type = D3DLIGHT_POINT;
Light.Diffuse.r = Light.Ambient.r = 0.5f;
Light.Diffuse.g = Light.Ambient.g = 0.5f;
Light.Diffuse.b = Light.Ambient.b = 0.0f;
Light.Diffuse.a = Light.Ambient.a = 1.0f;
Light.Range = 1000.0f;
Light.Attenuation0 = 0.5f;
Light.Position.x = 300.0f;
Light.Position.y = 0.0f;
Light.Position.z = -600.0f;
//set and enable the light
g_pD3DDevice->SetLight(0, &Light);
g_pD3DDevice->LightEnable(0, TRUE);
return TRUE;
}
and here's the function doFrame
BOOL DoFrame()
{
//Perform per-frame processing, such as rendering.
//Return TRUE on success, FALSE otherwise.
D3DXMATRIX matWorld;
//cleat device backbuffer
g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(0, 0, 0, 255), 1.0f, 0);
//begin scene
if (SUCCEEDED(g_pD3DDevice->BeginScene()))
{
//create and set the world transformation matrix
//rotate object along Y-axis
D3DXMatrixRotationY(&matWorld, (float)timeGetTime()/1000.0f);
g_pD3DDevice->SetTransform(D3DTS_WORLD, &matWorld);
//set the vertex stream and shader
g_pD3DDevice->SetStreamSource(0, g_pVB, sizeof(sVertex), 0);
//g_pD3DDevice->SetVertexShader(VERTEXFVF);
g_pD3DDevice->SetFVF(VERTEXFVF);
//Draw the vertex buffer
for (short i = 0; i < 4; i++)
g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP, i * 4, 2);
//end the scene
g_pD3DDevice->EndScene();
}
//displa the scene
g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
return TRUE;
}
when I compile this code, it just shows black background.. where's the problem??
I have a background of opengl. I don't know directx much. Correct me if I am wrong. But I think you need to set the projection matrix. I mean without the viewing frustum GPU won't render the scene.
It seems you have declared projection matrix but you haven't set values to it. (Value like FOV).

D3D Text uses up too much RAM..?

I have a VC++ DirectX application that renders a 3D cube, with the camera that can be moved around with W,A,S,D keys and mouse. In the top-left corner, a text shows the current camera coordinates; however, after 10-15 seconds, the allocated RAM and CPU increase to 1.6Gb and almost 50% of the total.. This happens only if I enable the text (even if the movement is still "FLOPS-based", so it's anyway a little "rusty" sometimes, with or without text print).
I guess having the text to be rendered over and over again causes the RAM to fill up because it won't "release" the previously written one..?
Here's my code (a bit long, I included everything 'cuz maybe is something else - however, I don't recommend you to run it since it could, in the worst case, freeze all the RAM up!):
#include <windows.h> // form header
#include <windowsx.h> // form header 2
#include <d3d9.h> // Direct3D9 header
#include <d3dx9.h> // DirectX9 header
#include <conio.h>
#include <dinput.h> // DirectInput header
#include <math.h>
#include <string>
using namespace std;
const double PI = 3.1415926;
// include the Direct3D Library file
#pragma comment (lib, "d3d9.lib")
#pragma comment (lib, "d3dx9.lib")
// include the DirectInput8 Library file
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")
// define the screen resolution
#define SCREEN_WIDTH 1024
#define SCREEN_HEIGHT 768
// global declarations
LPDIRECT3D9 d3d; // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; // the pointer to the vertex buffer
LPDIRECT3DINDEXBUFFER9 i_buffer; // the pointer to an index buffer
LPDIRECT3DTEXTURE9 texture; // declare a texture
LPDIRECT3DTEXTURE9 bump;
LPDIRECTINPUT8 din; // the pointer to our DirectInput interface
LPDIRECTINPUTDEVICE8 dinkeyboard; // the pointer to the keyboard device
LPDIRECTINPUTDEVICE8 dinmouse; // the pointer to the mouse device
BYTE keystate[256]; // the storage for the key-information
DIMOUSESTATE mousestate; // the storage for the mouse-information
ID3DXFont *dxfont;
VOID* pVoid; // a void pointer
// function prototypes
void initD3D(HWND hWnd); // sets up and initializes Direct3D
void render_frame(void); // renders a single frame
void cleanD3D(void); // closes Direct3D and releases memory
void init_graphics(void); // 3D declarations
void init_light(void); // sets up the light and the material
void initDInput(HINSTANCE hInstance, HWND hWnd); // sets up and initializes DirectInput
void detect_input(void); // gets the current input state
void cleanDInput(void); // closes DirectInput and releases memory
void PrintText(char* str, int size, int x, int y, DWORD color);
inline DWORD F2DW( FLOAT f ) { return *((DWORD*)&f); }
struct CUSTOMVERTEX {FLOAT X, Y, Z; D3DVECTOR NORMAL; FLOAT U,V;};
#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
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.hbrBackground = (HBRUSH)COLOR_WINDOW;
wc.lpszClassName = L"WindowClass";
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL,
L"WindowClass",
L"Our First Direct3D Program",
WS_OVERLAPPEDWINDOW, // non-fullscreen values
0, 0, // the starting x and y positions should be 0
SCREEN_WIDTH, SCREEN_HEIGHT, // set window to new resolution
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd, nCmdShow);
// set up and initialize Direct3D
initD3D(hWnd);
initDInput(hInstance, hWnd); // initialize DirectInput
// enter the main loop:
MSG msg;
while(TRUE)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message == WM_QUIT)
break;
detect_input(); // update the input data before rendering
render_frame();
if(keystate[DIK_ESCAPE] & 0x80)
PostMessage(hWnd, WM_DESTROY, 0, 0);
}
// clean up DirectX and COM
cleanD3D();
cleanDInput(); // release DirectInput
return msg.wParam;
}
// 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:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information
ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use
d3dpp.Windowed = TRUE; // program fullscreen, not windowed
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; // set the back buffer format to 32-bit
d3dpp.BackBufferWidth = SCREEN_WIDTH; // set the width of the buffer
d3dpp.BackBufferHeight = SCREEN_HEIGHT; // set the height of the buffer
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
// create a device class using this information and the info from the d3dpp stuct
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE); // turn off the 3D lighting
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer
d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50)); // ambient light
init_graphics(); // call the function to initialize the triangle
init_light(); // call the function to initialize the light and material
d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE); // turn on the 3D lighting
d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer
d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50)); // ambient light
d3ddev->SetRenderState(D3DRS_NORMALIZENORMALS, TRUE); // handle the normal lenght
d3ddev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); // turn color blending on
// set filters and samples
d3ddev->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 8);
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
//d3ddev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); // set the blending operation
//d3ddev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); // set the source blending
//d3ddev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); // set the destination blending
D3DXCreateTextureFromFile(d3ddev, // the Direct3D device
L"brick.bmp", // the filename of the texture
&texture); // the address of the texture storage
D3DXCreateTextureFromFile(d3ddev,
L"bump.bmp",
&bump);
//d3ddev->SetRenderState(D3DRS_TEXTUREFACTOR, D3DCOLOR_XRGB(200, 200, 200));
//d3ddev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DOTPRODUCT3);
//d3ddev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
//d3ddev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR);
//d3ddev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
//d3ddev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
//d3ddev->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);
//d3ddev->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
//d3ddev->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_TEXTURE);
//d3ddev->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
//d3ddev->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE);
d3ddev->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
d3ddev->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
//D3DXAssembleShaderFromFile("shader1.fx", 0 , NULL, &pCode, NULL );
}
// Hypotenuse function
float hypo(float x,float y)
{
float hypo=sqrt(x*x+y*y);
return hypo;
}
// this is the function used to render a single frame
void render_frame(void)
{
// clear the window to a specified color
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->BeginScene(); // begins the 3D scene
d3ddev->SetFVF(CUSTOMFVF); // tells Direct3D what FVF code we are using currently
// set the texture
d3ddev->SetTexture(1, bump);
d3ddev->SetTexture(0, texture);
///////
D3DXMATRIX matTranslateA; // a matrix to store the translation for triangle A
D3DXMATRIX matTranslateB; // a matrix to store the translation for triangle B
D3DXMATRIX matRotate; // a matrix to store the rotation for each triangle
D3DXMATRIX matRotate2;
D3DXMATRIX matScale;
static float index = 0.0f; // left movement (A)
static float index2 = 10.0f; // upward movement (PRIOR)
static float index3 = 18.0f; // backward movement (S) -- 1.0f
static float index4 = 0.0f; // left lookAt
static float index5 = 10.0f; // upward lookAt
static float index6 = 18.0f; // backward lookAt
// camera variables
static float radius = 30.00f;
static float theta = (3.0f * D3DX_PI) / 2.0f;
static float phi = D3DX_PI/2;
float Cx, Cy, Cz;
static int field = 45;
float slide = 0.001f;
static float dist1 = fabs(index-index4);
static float dist2 = fabs(index2-index5);
static float dist3 = fabs(index3-index6);
// player movements
// mouse movements
field -= 0.01 * mousestate.lZ;
theta += slide * mousestate.lX;
phi -= slide * mousestate.lY;
if(phi >= (D3DX_PI/9) * 8)
{
phi = (D3DX_PI/9) * 8;
}
if(phi <= (D3DX_PI/9))
{
phi = (D3DX_PI/9);
}
Cx = radius * cosf(theta) * sinf(phi);
Cy = radius * cosf(phi);
Cz = radius * sinf(theta) * sinf(phi);
float mov = radius*0.012;
float mov1 = Cz*0.012;
float mov2 = -Cx*0.012;
// previous index. values
float indexb = index;
float index3b = index3;
//if (GetAsyncKeyState(VK_SHIFT)) // --- 0.06f/0.03f
//{
if (keystate[DIK_A] & 0x80)
{
index=index-mov1;
index3=index3+mov2;
}
if (keystate[DIK_D] & 0x80)
{
index=index+mov1;
index3=index3-mov2;
}
if (keystate[DIK_PRIOR] & 0x80) // up +
{
index2+=0.22f;
}
if (keystate[DIK_NEXT] & 0x80) // down -
{
index2-=0.22f;
}
if (keystate[DIK_W] & 0x80) // prior
{
index3=index3+mov1;
index=index+mov2;
}
if (keystate[DIK_S] & 0x80) // next
{
index3=index3-mov1;
index=index-mov2;
}
if (keystate[DIK_SPACE] & 0x80) // next
{
// JUMP!!!!!!!!!!!!
}
if (hypo(index-indexb,index3-index3b)>mov)
{
index=indexb+0.7071*(index-indexb);
index3=index3b+0.7071*(index3-index3b);
}
// print a text
char msg1[64], msg2[64], msg3[64];
sprintf (msg1, "X axis: %f", index);
sprintf (msg2, "Z axis: %f", index3);
PrintText(msg1, 20, 30, 30, D3DCOLOR_XRGB(255,255,255));
PrintText(msg2, 20, 30, 60, D3DCOLOR_XRGB(255,255,255));
//}
/*else
if (GetAsyncKeyState(VK_LEFT))
{
index+=0.06f;
index4+=0.06f;
}
if (GetAsyncKeyState(VK_RIGHT))
{
index-=0.06f;
index4-=0.06f;
}
if (GetAsyncKeyState(VK_PRIOR))
{
index2-=0.06f;
index5-=0.06f;
}
if (GetAsyncKeyState(VK_NEXT))
{
index2+=0.06f;
index5+=0.06f;
}
if (GetAsyncKeyState(VK_UP))
{
index3-=0.03f;
index6-=0.06f;
}
if (GetAsyncKeyState(VK_DOWN))
{
index3+=0.03f;
index6+=0.06f;
}*/
// build MULTIPLE matrices to translate the model and one to rotate
D3DXMatrixTranslation(&matTranslateA, 0.0f, 0.0f, 0.0f);
//D3DXMatrixTranslation(&matTranslateB, 0.0f, 0.0f, -3.0f);
D3DXMatrixRotationY(&matRotate, 0.0f); // the front side --- index
D3DXMatrixRotationX(&matRotate2, 0.0f); // index2
D3DXMatrixScaling(&matScale, 1.0f, 1.0f, 1.0f); // index3
///////
D3DXMATRIX matView; // the view transform matrix
D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (index, index2, index3), // the camera position --- (0.0f, 10.0f, 18.0f)
&D3DXVECTOR3 (index-Cx, index2-Cy, index3+Cz), // the look-at position --- (0.0f, 0.0f, 0.0f)
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); // the up direction
d3ddev->SetTransform(D3DTS_VIEW, &matView); // set the view transform to matView
D3DXMATRIX matProjection; // the projection transform matrix
D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(field), // the horizontal field of view
(FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
1.0f, // the near view-plane
100.0f); // the far view-plane
d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection
// tell Direct3D about each world transform, and then draw another triangle
d3ddev->SetTransform(D3DTS_WORLD, &(matTranslateA * matRotate * matRotate2 * matScale));
///////
/// select the vertex and index buffers to use
d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
d3ddev->SetIndices(i_buffer);
// draw the cube
d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12);
d3ddev->EndScene(); // ends the 3D scene
d3ddev->Present(NULL, NULL, NULL, NULL); // displays the created frame on the screen
}
// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
v_buffer->Release(); // close and release the vertex buffer
//i_buffer->Release(); // close and release the index buffer
texture->Release(); // close and release the texture
d3ddev->Release(); // close and release the 3D device
d3d->Release(); // close and release Direct3D
}
// this is the function that puts the 3D models into video RAM
void init_graphics(void)
{
// create the vertices using the CUSTOMVERTEX struct
CUSTOMVERTEX vertices[] =
{
{ -3.0f, -3.0f, 3.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f }, // side 1
{ 3.0f, -3.0f, 3.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f },
{ -3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f },
{ 3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f },
{ 3.0f, -3.0f, -3.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 2
{ -3.0f, -3.0f, -3.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
{ 3.0f, 3.0f, -3.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
{ -3.0f, 3.0f, -3.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f },
{ -3.0f, 3.0f, -3.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f }, // side 3
{ -3.0f, 3.0f, 3.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f },
{ 3.0f, 3.0f, -3.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f },
{ 3.0f, 3.0f, 3.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f },
{ -3.0f, -3.0f, -3.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f }, // side 4
{ 3.0f, -3.0f, -3.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f },
{ -3.0f, -3.0f, 3.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f },
{ 3.0f, -3.0f, 3.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f },
{ 3.0f, -3.0f, 3.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, // side 5
{ 3.0f, -3.0f, -3.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f },
{ 3.0f, 3.0f, 3.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f },
{ 3.0f, 3.0f, -3.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f },
{ -3.0f, -3.0f, -3.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f }, // side 6
{ -3.0f, -3.0f, 3.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f },
{ -3.0f, 3.0f, -3.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f },
{ -3.0f, 3.0f, 3.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f },
};
// create a vertex buffer interface called v_buffer
d3ddev->CreateVertexBuffer(24*sizeof(CUSTOMVERTEX),
0,
CUSTOMFVF,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
VOID* pVoid; // a void pointer
// lock v_buffer and load the vertices into it
v_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, vertices, sizeof(vertices));
v_buffer->Unlock();
// create the indices using an int array
short indices[] =
{
0, 1, 2, // side 1
2, 1, 3,
4, 5, 6, // side 2
6, 5, 7,
8, 9, 10, // side 3
10, 9, 11,
12, 13, 14, // side 4
14, 13, 15,
16, 17, 18, // side 5
18, 17, 19,
20, 21, 22, // side 6
22, 21, 23,
};
// create an index buffer interface called i_buffer
d3ddev->CreateIndexBuffer(36*sizeof(short),
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&i_buffer,
NULL);
// lock i_buffer and load the indices into it
i_buffer->Lock(0, 0, (void**)&pVoid, 0);
memcpy(pVoid, indices, sizeof(indices));
i_buffer->Unlock();
}
// this is the function that sets up the lights and materials
void init_light(void)
{
D3DLIGHT9 light; // create the light struct
D3DMATERIAL9 material; // create the material struct
ZeroMemory(&light, sizeof(light)); // clear out the light struct for use
light.Type = D3DLIGHT_POINT; // make the light type 'point light'
light.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); // set the light's color
//light.Specular = D3DXCOLOR(5.5f, 5.5f, 5.5f, 1.0f);
light.Position = D3DXVECTOR3(10.0f, 10.0f, 5.0f);
light.Range = 100.0f;
//light.Direction = D3DXVECTOR3(-1.0f, -0.3f, -1.0f);
light.Attenuation0 = 0.0f; // constant attenuation
light.Attenuation1 = 0.0f; // inverse attenuation
light.Attenuation2 = 0.01f; // square inverse attenuation
d3ddev->SetLight(0, &light); // send the light struct properties to light #0
d3ddev->LightEnable(0, TRUE); // turn on light #0
ZeroMemory(&material, sizeof(D3DMATERIAL9)); // clear out the struct for use
material.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); // set diffuse color
material.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f); // set ambient color
d3ddev->SetMaterial(&material); // set the globably-used material to &material
}
// this is the function that initializes DirectInput
void initDInput(HINSTANCE hInstance, HWND hWnd)
{
// create the DirectInput interface
DirectInput8Create(hInstance, // the handle to the application
DIRECTINPUT_VERSION, // the compatible version
IID_IDirectInput8, // the DirectInput interface version
(void**)&din, // the pointer to the interface
NULL); // COM stuff, so we'll set it to NULL
// create the keyboard device
din->CreateDevice(GUID_SysKeyboard, // the default keyboard ID being used
&dinkeyboard, // the pointer to the device interface
NULL); // COM stuff, so we'll set it to NULL
din->CreateDevice(GUID_SysMouse,
&dinmouse,
NULL);
// set the data format to keyboard format
dinkeyboard->SetDataFormat(&c_dfDIKeyboard);
dinmouse->SetDataFormat(&c_dfDIMouse);
// set the control you will have over the keyboard
dinkeyboard->SetCooperativeLevel(hWnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
dinmouse->SetCooperativeLevel(hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
}
// this is the function that gets the latest input data
void detect_input(void)
{
// get access if we don't have it already
dinkeyboard->Acquire();
dinmouse->Acquire();
// get the input data
dinkeyboard->GetDeviceState(256, (LPVOID)keystate);
dinmouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mousestate);
}
// this is the function that closes DirectInput
void cleanDInput(void)
{
dinkeyboard->Unacquire(); // make sure the keyboard is unacquired
dinmouse->Unacquire(); // make sure the mouse in unacquired
din->Release(); // close DirectInput before exiting
}
void PrintText(char* str, int size, int x, int y, DWORD color)
{
static RECT textbox;
SetRect(&textbox, x, y, SCREEN_WIDTH, SCREEN_HEIGHT);
D3DXCreateFont(d3ddev, // the D3D Device
size, // font height
0, // default font width
FW_NORMAL, // font weight
1, // not using MipLevels
false, // italic font
DEFAULT_CHARSET, // default character set
OUT_DEFAULT_PRECIS, // default OutputPrecision,
DEFAULT_QUALITY, // default Quality
DEFAULT_PITCH | FF_DONTCARE, // default pitch and family
L"Arial", // use Facename Arial
&dxfont); // the font object
dxfont->DrawTextA(NULL,
str,
strlen(str),
&textbox,
DT_LEFT | DT_TOP,
color);
}
Don't create a new font object every time you print text.
As stefan posted, a new font is being created every time the PrintText function is called.
One way to fix this would be to move the D3DXCreateFont function call into the initD3D function, and add a matching dxfont->Release(); to the cleanD3D function.

c++ first person camera in directx

m a beginner programmer and im creating a project which allows me to walk around rooms via a first person camera so far i have the buildings drawn etc but now im stuck and don't know how to make a first person camera to allow me to walk around could anyone point me towards a camera class i could use or some useful code? thanks in advance
below is the code for one of my buildings but not my full project, its rotating so i could see what i was drawing.
i want to be able to move forwards and backwards using the arrow keys and also left and right :)
#include <stdio.h>
#include <d3d9.h>
#include <d3dx9.h>
#include <dinput.h>
#include <math.h>
const char TITLE[] = "game experimenting";
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
//*****Direct 3D Initialization*****
LPDIRECT3D9 g_pD3D = NULL;
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;
// Buffer to hold vertices
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
//Direct Input References
LPDIRECTINPUT8 m_pDIObject = NULL;//DirectInput object
LPDIRECTINPUTDEVICE8 m_pDIKeyboardDevice = NULL;//keyboard device
LPDIRECTINPUTDEVICE8 m_pDIMouseDevice = NULL;//mouse device
LPDIRECTINPUTDEVICE8 m_pDIJoystickDevice = NULL;//joystick device
//D3DXMATRIX Transformation Matrices
D3DXMATRIX g_matProj;
D3DXMATRIX g_matView;
D3DXMATRIX g_matWorld;
//**********************
//****** Vertex Buffer Definition and Setting ***
struct CUSTOMVERTEX
{
FLOAT x, y, z; // The position for the vertex
DWORD color; // The vertex color
};
int numberOfTriangles = 34;
int numberOfVertecies = 3*numberOfTriangles;
float scale = 1.0f;
float doorHeight = 1.0f;
float doorWidth = 0.25f;
CUSTOMVERTEX g_Vertices[] =
{
// Y +Axis
//Top Side Outer Wall
{ 1.0f, 1.0f,-1.0f, 0xffffffff, },
{ 1.0f, 1.0f,1.0f, 0xffffffff, },
{ -1.0f,1.0f, -1.0f, 0xffffffff,}, //Triangle
{ -1.0f,1.0f, 1.0f, 0xffffffff,},
{ 1.0f, 1.0f, 1.0f, 0xffffffff, },
{ -1.0f,1.0f, -1.0f, 0xffffffff,}, //Triangle
//Top Side Inner Wall
{ 0.9f, 0.9f,-0.9f, 0x00ff0000, },
{ 0.9f, 0.9f,0.9f, 0x00ff0000, },
{ -0.9f,0.9f, -0.9f, 0x00ff0000,}, //Triangle
{ -0.9f,0.9f, 0.9f, 0x00ff0000,},
{ 0.9f, 0.9f, 0.9f, 0x00ff0000, },
{ -0.9f,0.9f, -0.9f, 0x00ff0000,}, //Triangle
// X +Axis
//Right Side Outer Wall
{ 1.0f, 1.0f,-1.0f, 0xffffffff, },
{ 1.0f, 1.0f,1.0f, 0xffffffff, },
{ 1.0f,-1.0f, -1.0f, 0xffffffff,}, /////Triangle
{ 1.0f,-1.0f, 1.0f, 0xffffffff,},
{ 1.0f, 1.0f, 1.0f, 0xffffffff, },
{ 1.0f,-1.0f, -1.0f, 0xffffffff,}, /////Triangle
//Right Side Inner Wall
{ 0.9f, 0.9f,-0.9f, 0xff0000ff, },
{ 0.9f, 0.9f,0.9f, 0xff0000ff, },
{ 0.9f,-1.0f, -0.9f, 0xff0000ff,}, /////Triangle
{ 0.9f,-1.0f, 0.9f, 0xff0000ff,},
{ 0.9f, 0.9f, 0.9f, 0xff0000ff, },
{ 0.9f,-1.0f, -0.9f, 0xff0000ff,}, /////Triangle
// X -Axis
//Left Side Outer Wall
{-1.0f, 1.0f,-1.0f, 0xffffffff, },
{-1.0f, 1.0f,1.0f, 0xffffffff, },
{-1.0f,-1.0f, -1.0f, 0xffffffff,}, /////Triangle
{-1.0f,-1.0f, 1.0f, 0xffffffff,},
{-1.0f, 1.0f, 1.0f, 0xffffffff, },
{-1.0f,-1.0f, -1.0f, 0xffffffff,}, /////Triangle
//Left Side Inner Wall
{-0.9f, 0.9f,-0.9f, 0xff0000ff, },
{-0.9f, 0.9f,0.9f, 0xff0000ff, },
{-0.9f,-1.0f, -0.9f, 0xff0000ff,}, /////Triangle
{-0.9f,-1.0f, 0.9f, 0xff0000ff,},
{-0.9f, 0.9f, 0.9f, 0xff0000ff, },
{-0.9f,-1.0f, -0.9f, 0xff0000ff,}, /////Triangle
// Z +Axis
//Back Outer Wall
{ 1.0f,-1.0f, 1.0f, 0xffffffff, },
{ 1.0f, 1.0f, 1.0f, 0xffffffff, },
{ -1.0f,-1.0f, 1.0f, 0xffffffff,}, /////Triangle
{ -1.0f,1.0f, 1.0f, 0xffffffff,},
{ 1.0f, 1.0f, 1.0f, 0xffffffff, },
{ -1.0f,-1.0f, 1.0f, 0xffffffff,}, /////Triangle
//Back Inner Wall
{ 0.9f,-1.0f, 0.9f, 0xff0000ff, },
{ 0.9f, 0.9f, 0.9f, 0xff0000ff, },
{ -0.9f,-1.0f, 0.9f, 0xff0000ff,}, /////Triangle
{ -0.9f,0.9f, 0.9f, 0xff0000ff,},
{ 0.9f, 0.9f, 0.9f, 0xff0000ff, },
{ -0.9f,-1.0f, 0.9f, 0xff0000ff,}, /////Triangle
// Z Negative Axis
//Front Outer Wall Top1
{ 1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff, },
{ 1.0f, 1.0f, -1.0f, 0xffffffff, },
{ -1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,}, /////Triangle
//Front Outer Wall Top2
{ -1.0f, 1.0f, -1.0f, 0xffffffff, },
{ 1.0f, 1.0f, -1.0f, 0xffffffff, },
{ -1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,}, /////Triangle
//Front Outer Wall Left1
{ -1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,},
{ -1.0f,-1.0f, -1.0f, 0xffffffff,},
{ -1.0f+(scale-doorWidth),-1.0f, -1.0f, 0xffffffff,}, /////Triangle
//Front Outer Wall Left2
{ -1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,},
{ -1.0f+(scale-doorWidth),-1.0f, -1.0f, 0xffffffff,},
{ -1.0f+(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffffffff,}, /////Triangle
//Front Outer Wall Right1
{ 1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,},
{ 1.0f,-1.0f, -1.0f, 0xffffffff,},
{ 1.0f-(scale-doorWidth),-1.0f, -1.0f, 0xffffffff,}, /////Triangle
//Front Outer Wall Right2
{ 1.0f,-1.0f+doorHeight, -1.0f, 0xffffffff,},
{ 1.0f-(scale-doorWidth),-1.0f, -1.0f, 0xffffffff,},
{ 1.0f-(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffffffff,}, /////Triangle
//Door Inner Edges Right of door 1
{ 1.0f-(scale-doorWidth),-1.0f, -1.0f, 0xffff0099,},
{ 1.0f-(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,},
{ 1.0f-(scale-doorWidth),-1.0f, -0.9f, 0xffff0099,}, /////Triangle
//Door Inner Edges Right of door 2
{ 1.0f-(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,},
{ 1.0f-(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xffff0099,},
{ 1.0f-(scale-doorWidth),-1.0f, -0.9f, 0xffff0099,}, /////Triangle
//Door Inner Edges Left of door 1
{ -1.0f+(scale-doorWidth),-1.0f, -1.0f, 0xffff0099,},
{ -1.0f+(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,},
{ -1.0f+(scale-doorWidth),-1.0f, -0.9f, 0xffff0099,}, /////Triangle
//Door Inner Edges Left of door 2
{ -1.0f+(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,},
{ -1.0f+(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xffff0099,},
{ -1.0f+(scale-doorWidth),-1.0f, -0.9f, 0xffff0099,}, /////Triangle
//Door Inner Edges Top Of Door 1
{ -1.0f+(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,},
{ 1.0f-(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,},
{ 1.0f-(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xffff0099,}, /////Triangle
//Door Inner Edges Top Of Door 2
{ 1.0f-(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xffff0099,},
{ -1.0f+(scale-doorWidth),-1.0f+doorHeight, -1.0f, 0xffff0099,},
{ -1.0f+(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xffff0099,}, /////Triangle
//FRONT Inner Wall Top1
{ 0.9f,-1.0f+doorHeight, -0.9f, 0xff0000ff, },
{ 0.9f, 1.0f, -0.9f, 0xff0000ff, },
{ -0.9f,-1.0f+doorHeight, -0.9f, 0xff0000ff,}, /////Triangle
//FRONT Inner Wall Top2
{ -0.9f, 1.0f, -0.9f, 0xff0000ff, },
{ 0.9f, 1.0f, -0.9f, 0xff0000ff, },
{ -0.9f,-1.0f+doorHeight, -0.9f, 0xff0000ff,}, /////Triangle
//FRONT Inner Wall Left1
{ -0.9f,-1.0f+doorHeight, -0.9f, 0xff0000ff,},
{ -0.9f,-1.0f, -0.9f, 0xff0000ff,},
{ -1.0f+(scale-doorWidth),-1.0f, -0.9f, 0xff0000ff,}, /////Triangle
//FRONT Inner Wall Left2
{ -0.9f,-1.0f+doorHeight, -0.9f, 0xff0ff0ff,},
{ -1.0f+(scale-doorWidth),-1.0f, -0.9f, 0xff0ff0ff,},
{ -1.0f+(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xff0ff0ff,}, /////Triangle
//FRONT Inner Wall Right1
{ 0.9f,-1.0f+doorHeight, -0.9f, 0xff0ff0ff,},
{ 0.9f,-1.0f, -0.9f, 0xff0ff0ff,},
{ 1.0f-(scale-doorWidth),-1.0f, -0.9f, 0xff0ff0ff,}, /////Triangle
//FRONT Inner Wall Right2
{ 0.9f,-1.0f+doorHeight, -0.9f, 0xff0000ff,},
{ 1.0f-(scale-doorWidth),-1.0f, -0.9f, 0xff0000ff,},
{ 1.0f-(scale-doorWidth),-1.0f+doorHeight, -0.9f, 0xff0000ff,}, /////Triangle
};
//*******************************************************************
// Name: SetupMatrices()
// Desc: Sets up the world, view, and projection transform matrices.
//-------------------------------------------------------------------
void SetupMatrices()
{
static float time = 0.0f;
time += 10.0f;
D3DXMatrixIdentity( &g_matWorld );
D3DXMatrixRotationYawPitchRoll( &g_matWorld,
time/1000.0f,
time/700.0f,
time/850.0f );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &g_matWorld );
D3DXMatrixLookAtLH( &g_matView, &D3DXVECTOR3( 0.0f, 0.0f,-5.0f ),
&D3DXVECTOR3( 0.0f, 0.0f, 0.0f ),
&D3DXVECTOR3( 0.0f, 1.0f, 0.0f ) );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &g_matView );
D3DXMatrixPerspectiveLH(&g_matProj, 2.0f, 2.0f/1.5f,
1.0f, 10000.0f);
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &g_matProj );
}
void TestForMouse()
{
DIMOUSESTATE mouseState;
m_pDIMouseDevice->GetDeviceState(sizeof(mouseState),
(LPVOID)&mouseState);
if(mouseState.rgbButtons[0] & 0x80) // left mouse button down
{
}
}
//************************ MESSAGE HANDLER **************************
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam)
{
// this is the main message handler of the system
PAINTSTRUCT ps; // used in WM_PAINT
HDC hdc; // handle to a device context
// what is the message
switch(msg)
{
case WM_CREATE:
{
// do initialization stuff here
return(0);
}
case WM_PAINT:
{
// validate the window
hdc = BeginPaint(hwnd,&ps);
EndPaint(hwnd,&ps);
return(0);
}
case WM_KEYDOWN:
{
// Handle any non-accelerated key commands
switch (wparam)
{
case VK_ESCAPE:
case VK_F12:
PostMessage(hwnd, WM_CLOSE, 0, 0);
return (0);
default:
char message[15];
sprintf_s(message, "Key Pressed: %c", (char)wparam);
MessageBox(NULL, message, "Key Pressed", MB_OK);
}
break;
}
case WM_DESTROY:
{
// kill the application
PostQuitMessage(0);
return(0);
}
default:
break;
} // end switch
// process any messages that wasn't taken care of
return (DefWindowProc(hwnd, msg, wparam, lparam));
} // end WinProc
//********************* END OF MESSAGE HANDLER ***********************
void InitializeDX(HWND hwnd)
{
if(!( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
MessageBox(hwnd,"Direct3d Create problem", NULL, NULL);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
if(FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
MessageBox(hwnd,"CreateDevice problem", NULL, NULL);
//InitializeCircleArray();
//InitializeSquareArray();
//*************************** Create Vertex Buffer ****************************
if( FAILED( g_pd3dDevice->CreateVertexBuffer( numberOfVertecies*sizeof(CUSTOMVERTEX),
0 /* Usage */, D3DFVF_CUSTOMVERTEX,
D3DPOOL_MANAGED, &g_pVB, NULL ) ) )
MessageBox(hwnd,"Vertex Buffer problem",NULL,NULL);
VOID* pVertices;
if( FAILED( g_pVB->Lock( 0, sizeof(g_Vertices), (void**)&pVertices, 0 ) ) )
MessageBox(hwnd,"Vertex Lock Problem",NULL,NULL);
memcpy( pVertices, g_Vertices, sizeof(g_Vertices) );
g_pVB->Unlock();
g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, TRUE); // turn on the z-buffer
}
void InitializeDI(HWND hwnd)
{
if(FAILED(DirectInput8Create(GetModuleHandle(NULL),
DIRECTINPUT_VERSION,
IID_IDirectInput8,
(void**)&m_pDIObject,
NULL)))
MessageBox(hwnd,"DirectInput8Create() failed!",NULL,NULL);
// Setup Mouse Input
if(FAILED(m_pDIObject->CreateDevice(GUID_SysMouse,
&m_pDIMouseDevice,
NULL)))
MessageBox(hwnd,"CreateDevice() failed!",NULL,NULL);
if(FAILED(m_pDIMouseDevice->SetDataFormat(&c_dfDIMouse)))
MessageBox(hwnd,"SetDataFormat() failed!",NULL,NULL);
if(FAILED(m_pDIMouseDevice->SetCooperativeLevel(hwnd,
DISCL_BACKGROUND | DISCL_NONEXCLUSIVE)))
MessageBox(hwnd,"SetCooperativeLevel() failed!",NULL,NULL);
if(FAILED(m_pDIMouseDevice->Acquire()))
MessageBox(hwnd,"Acquire() failed!",NULL,NULL);
}
//**************************Render and display the scene***********************
void Render()
{
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
// Turn off D3D lighting,
// providing our own vertex colours
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
// Turn off culling
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
// Begin the scene
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
SetupMatrices();
// Rendering of scene objects can happen here
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof(CUSTOMVERTEX) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
//g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 179 ); // 179 triangles from 181 vertices
//g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, numberOfTriangles ); //1 triangle
// End the scene
g_pd3dDevice->EndScene();
}
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
//************************ WIN MAIN***********************
int WINAPI WinMain( HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)
{
WNDCLASS winclass; // this will hold the class
HWND hwnd; // generic window handle
MSG msg; // generic message
// first fill in the window class stucture
winclass.style = CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
// winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
// winclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
winclass.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(255, 0, 0));
winclass.lpszMenuName = NULL;
winclass.lpszClassName = "DX9WinClass";
// register the window class
if (!RegisterClass(&winclass))
return(0);
// create the window
if (!(hwnd = CreateWindow( "DX9WinClass", // class
TITLE, // title
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0,
0,
//Set the size of the window to the size of the screen
600,
400,
//GetSystemMetrics(SM_CXSCREEN),
//GetSystemMetrics(SM_CYSCREEN),
NULL, // handle to parent
NULL, // handle to menu
hinstance, // instance
NULL))) // creation parms
return(0);
InitializeDX(hwnd);
InitializeDI(hwnd);
// enter main event loop
bool quit = false;
while(!quit)
{
TestForMouse();
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
{
// test if this is a quit
if (msg.message == WM_QUIT) quit = true;
// translate any accelerator keys
TranslateMessage(&msg);
// send the message to the window proc
DispatchMessage(&msg);
} // end if
else {
Render();
}
} // end while
//Set Mouse Free Run Away Mouse
m_pDIMouseDevice->Release();
// return to Windows like this
return(msg.wParam);
} // end WinMain
//************************ END OF WIN MAIN *******************
Normally you create your model using an external program (e.g. Blender 3D) and then read the model into your program. Maybe in your case it would be better to take a look at an existing free game engine to get a better idea of how it works, one that people like to use which is free is the quake3 engine which although a bit dated should give you a better understanding and maybe can act as inspiration for your own engine. Another recommended, more simpler graphics engine is Ogre3D