Related
I am trying to build a code that uses OpenGL and shaders that adds texture to a square pyramid. After I added the functions to add the texture, ran the code but instead of rendering, I get a console window giving me the following error:
INFO: OpenGL Version: 4.4.0 NVIDIA 512.15
ERROR::SHADER::VERTEX::COMPILATION_FAILED
0(2) : error C1503: undefined variable "cameraPosition"
0(2) : error C1503: undefined variable "cameraPosition"
0(2) : error C1503: undefined variable "cameraPosition"
0(2) : error C1035: assignment of incompatible types
I have tried copying and pasting the cameraPosition variable from the bottom of my code to one of my main functions that has the gl_Position variable. But that did not solve the problem. Do I need to change the vec3 to vec4 somewhere or do I need to copy and paste the cameraPostion variable and definition somewhere else? Here is my code:
#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>
#include <SOIL2.h> // SOIL2 library
using namespace std; // Standard namespace
/*Shader program Macro*/
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version " core \n" #Source
#endif
// Input Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void cursor_position_callback(GLFWwindow* window, double xpos, double ypos);
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
// Declare View Matrix
glm::mat4 viewMatrix;
// Initialize FOV
GLfloat fov = 45.f;
// Define Camera Attributes
glm::vec3 cameraPosition = glm::vec3(0.f, 0.f, 3.f);
glm::vec3 target = glm::vec3(0.f, 0.f, 0.f);
glm::vec3 cameraDirection = glm::normalize(cameraPosition - target);
glm::vec3 worldUp = glm::vec3(0.f, 1.f, 0.f);
glm::vec3 cameraRight = glm::normalize(glm::cross(worldUp, cameraDirection));
glm::vec3 cameraUp = glm::normalize(glm::cross(cameraDirection, cameraRight));
glm::vec3 cameraFront = glm::normalize(glm::vec3(0.f, 0.f, -1.f));
// Declare target prototype
glm::vec3 getTarget();
// Camera transformation prototype
void TransformCamera();
// Boolean for keys and mouse buttons
bool keys[1024], mouseButtons[3];
// Boolean to check camera transformations
bool isPanning = false, isOrbiting = false;
// Radius, Pitch, and Yaw
GLfloat radius = 3.f, rawYaw = 0.f, rawPitch = 0.f, degYaw, degPitch;
GLfloat deltaTime = 0.f, lastFrame = 0.f;
GLfloat lastX = 400, lastY = 300, xChange, yChange;
bool firstMouseMove = true; // Detect inititial mouse movement
void initCamera();
// Unnamed namespace
namespace
{
const char* const WINDOW_TITLE = "Basic Camera Movement"; // Macro for window title
// Variables for window width and height
int WINDOW_WIDTH = 800;
int WINDOW_HEIGHT = 600;
// Stores the GL data relative to a given mesh
struct GLMesh
{
GLuint vao; // Handle for the vertex array object
GLuint vbos[2]; // Handles for the vertex buffer objects
GLuint nIndices; // Number of indices of the mesh
};
// Main GLFW window
GLFWwindow* gWindow = nullptr;
// Triangle mesh data
GLMesh gMesh;
// Shader program
GLuint gProgramId;
}
/* 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 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 vec3 color; // Color data from Vertex Attrib Pointer 1
layout(location = 2) in vec2 texture; // Texture data from Vertex Attrib Pointer 2
out vec3 vertexColor; // variable to transfer color data to the fragment shader
out vec3 vertexTexture;
//Global variables for the transform matrices
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
uniform sampler2D myTexture; // Sampler
void main()
{
gl_Position = projection * view * model * vec4(cameraPosition.x, cameraPosition.y, cameraPosition.z, 1.0f); // transforms vertices to clip coordinates
vertexColor = color; // references incoming color data
vertexTexture = texture;
}
);
/* Fragment Shader Source Code*/
const GLchar* fragmentShaderSource = GLSL(440,
in vec3 vertexColor; // Variable to hold incoming color data from vertex shader
out vec3 fragmentColor;
out vec3 fragmentTexture;
void main()
{
fragmentColor = texture(myTexture, textTexture);
fragmentTexture = vec2(vertexTexture);
}
);
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 implicitely used by glClear)
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Set input call back functions
glfwSetKeyCallback(gWindow, key_callback);
glfwSetCursorPosCallback(gWindow, cursor_position_callback);
glfwSetMouseButtonCallback(gWindow, mouse_button_callback);
glfwSetScrollCallback(gWindow, scroll_callback);
// render loop
// -----------
while (!glfwWindowShouldClose(gWindow))
{
// Set delta time
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
// Resize window and graphics simultaneously
glfwGetFramebufferSize(gWindow, &WINDOW_WIDTH, &WINDOW_HEIGHT);
// input
// -----
UProcessInput(gWindow);
// Render this frame
URender();
glfwPollEvents();
// Poll camera transformations
TransformCamera();
}
// 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);
// 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)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
float cameraSpeed = 2.5 * deltaTime;
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
cameraPosition += cameraSpeed * cameraFront;
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
cameraPosition -= cameraSpeed * cameraFront;
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
cameraPosition -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
cameraPosition += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
if (glfwGetKey(window, GLFW_KEY_Q) == GLFW_PRESS)
cameraPosition -= cameraSpeed * cameraUp;
if (glfwGetKey(window, GLFW_KEY_E) == GLFW_PRESS)
cameraPosition += cameraSpeed * cameraUp;
}
// 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);
}
// Functioned called to render a frame
void URender()
{
// Enable z-depth
glEnable(GL_DEPTH_TEST);
// Wireframe mode
// glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// 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 2
glm::mat4 scale = glm::scale(glm::vec3(1.0f, 1.0f, 1.0f));
// 2. Rotates shape by 15 degrees in the x axis
glm::mat4 rotation = glm::rotate(45.0f, glm::vec3(1.0, 1.0f, 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;
// Transforms the camera: move the camera back (z axis)
glm::mat4 view = glm::lookAt(cameraPosition, getTarget(), worldUp);
// Creates a perspective projection
glm::mat4 projection = glm::perspective(fov, (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));
GLuint crateTexture = {1};
glBindTexture(GL_TEXTURE_2D, crateTexture);
// Activate the VBOs contained within the mesh's VAO
glBindVertexArray(gMesh.vao);
// Draws the triangles
glDrawElements(GL_TRIANGLES, gMesh.nIndices, GL_UNSIGNED_SHORT, NULL); // Draws the triangle
// 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[] = {
0.0f, 1.0f, 0.0f, // Top Center Vertex 0
1.0f, 0.0f, 0.0f, 1.0f, // Red
0.5f, 1.0f, // UV
-1.0f, -1.0f, 1.0f, // Bottom Left Vertex 1
0.0f, 1.0f, 0.0f, 1.0f, // Green
0.0f, 0.0f, // UV
1.0f, -1.0f, 1.0f, // Bottom Right Vertex 2
0.0f, 0.0f, 1.0f, 1.0f, // Blue
1.0f, 0.0f, // UV
1.0f, -1.0f, -1.0f, // Bottom Back Right Vertex 3
1.0f, 0.0f, 1.0f, 1.0f, // Magenta
0.0f, 0.0f, // UV
-1.0f, -1.0f, -1.0f, // Bottom Back Left Vertex 4
1.0f, 1.0f, 0.0f, 1.0f, // Yellow
1.0f, 0.0f // UV
};
// Index data to share position data
GLushort indices[] = {
// Sides
0, 1, 2, // Triangle 1
0 ,2, 3, // Triangle 2
0, 3, 1, // Triangle 3
0, 3, 4, // Triangle 4
// Base
1, 2, 3, // Triangle 5
1, 4, 3 // Triangle 6
};
const GLuint floatsPerVertex = 3;
const GLuint floatsPerColor = 4;
const GLuint floatsPerTexture = 2;
glGenVertexArrays(1, &mesh.vao); // we can also generate multiple VAOs or buffers at the same time
glBindVertexArray(mesh.vao);
// Create 2 buffers: first one for the vertex data; second one for the indices
glGenBuffers(2, mesh.vbos);
glBindBuffer(GL_ARRAY_BUFFER, mesh.vbos[0]); // Activates the buffer
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW); // Sends vertex or coordinate data to the GPU
mesh.nIndices = sizeof(indices) / sizeof(indices[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vbos[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// Strides between vertex coordinates is 6 (x, y, z, r, g, b, a). A tightly packed stride is 0.
GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);// The number of floats before each
// 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);
glVertexAttribPointer(2, floatsPerTexture, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerTexture));
glEnableVertexAttribArray(2);
// Load textures
int crateTexWidth, crateTexHeight, gridTexWidth, gridTexHeight;
unsigned char* crateImage = SOIL_load_image("crate.png", &crateTexWidth, &crateTexHeight, 0, SOIL_LOAD_RGB);
unsigned char* gridImage = SOIL_load_image("crate.png", &gridTexWidth, &gridTexHeight, 0, SOIL_LOAD_RGB);
// Generate Textures
GLuint crateTexture = {1};
glGenTextures(1, &crateTexture);
glBindTexture(GL_TEXTURE_2D, crateTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, crateTexWidth, crateTexHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, crateImage);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(crateImage);
glBindTexture(GL_TEXTURE_2D, 0);
// Generate Textures
GLuint gridTexture;
glGenTextures(1, &gridTexture);
glBindTexture(GL_TEXTURE_2D, gridTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, gridTexWidth, gridTexHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, gridImage);
glGenerateMipmap(GL_TEXTURE_2D);
SOIL_free_image_data(gridImage);
glBindTexture(GL_TEXTURE_2D, 0);
}
void UDestroyMesh(GLMesh& mesh)
{
glDeleteVertexArrays(1, &mesh.vao);
glDeleteBuffers(2, mesh.vbos);
}
// 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;
}
glCompileShader(fragmentShaderId); // compile the fragment shader
// 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);
}
// Define Input Callback functions
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
// Display ASCII Keycode
//cout << "ASCII: " << key << endl;
if (action == GLFW_PRESS)
keys[key] = true;
else if (action == GLFW_RELEASE)
keys[key] = false;
}
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) {
/*
// Display scroll offset
if (yoffset > 0)
cout << "Scroll Up: ";
if (yoffset < 0)
cout << "Scroll Down: ";
cout << yoffset << endl;
*/
// Clamp FOV
if (fov >= 1.f && fov <= 45.f)
fov -= yoffset * 0.01f;
//Default FOV
if (fov < 1.f)
fov = 1.f;
if (fov > 45.f)
fov = 45.f;
}
void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) {
// Display mouse x and y coordinates
// cout << "Mouse X: " << xpos << endl;
// cout << "Mouse Y: " << ypos << endl;
if (firstMouseMove) {
lastX = xpos;
lastY = ypos;
firstMouseMove = false;
}
// Calculate cursor offset
xChange = xpos - lastX;
yChange = lastY - ypos;
lastX = xpos;
lastY = ypos;
// Pan camera
if (isPanning) {
if (cameraPosition.z < 0.f)
cameraFront.z = 1.f;
else
cameraFront.z = -1.f;
GLfloat cameraSpeed = xChange * deltaTime;
cameraPosition += cameraSpeed * cameraRight;
cameraSpeed = yChange * deltaTime;
cameraPosition += cameraSpeed * cameraUp;
}
// Orbit camera
if (isOrbiting) {
rawYaw += xChange;
rawPitch += yChange;
// Convert Yaw and Pitch to degrees
degYaw = glm::radians(rawYaw);
// degPitch = glm::radians(rawPitch)
degPitch = glm::clamp(glm::radians(rawPitch), -glm::pi<float>() / 2.f + .1f, glm::pi<float>() / 2.f - .1f);
// Azimuth Altitude formula
cameraPosition.x = target.x + radius * cosf(degPitch) * sin(degYaw);
cameraPosition.y = target.y + radius * sinf(degPitch);
cameraPosition.z = target.z + radius * cosf(degPitch) * cosf(degYaw);
}
}
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
/*
// Detect mouse button clicks
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
cout << "LMB clicked!" << endl;
if (button == GLFW_MOUSE_BUTTON_MIDDLE && action == GLFW_PRESS)
cout << "MMB clicked!" << endl;
if (button == GLFW_MOUSE_BUTTON_RIGHT && action == GLFW_PRESS)
cout << "RMB clicked!" << endl;
*/
if (action == GLFW_PRESS)
mouseButtons[button] = true;
else if (action == GLFW_RELEASE)
mouseButtons[button] = false;
}
// Define getTarget function
glm::vec3 getTarget() {
if (isPanning)
target = cameraPosition + cameraFront;
return target;
}
// Define TransformCamera function
void TransformCamera() {
// Pan camera
if (keys[GLFW_KEY_LEFT_ALT] && mouseButtons[GLFW_MOUSE_BUTTON_MIDDLE])
isPanning = true;
else
isPanning = false;
// Orbit camera
if ((mouseButtons[GLFW_MOUSE_BUTTON_LEFT]))
isOrbiting = true;
else
isOrbiting = false;
// Reset camera
if (keys[GLFW_KEY_F])
initCamera();
}
void initCamera() {
cameraPosition = glm::vec3(0.f, 0.f, 3.f);
target = glm::vec3(0.f, 0.f, 0.f);
cameraDirection = glm::normalize(cameraPosition - target);
worldUp = glm::vec3(0.f, 1.f, 0.f);
cameraRight = glm::normalize(glm::cross(worldUp, cameraDirection));
cameraUp = glm::normalize(glm::cross(cameraDirection, cameraRight));
cameraFront = glm::normalize(glm::vec3(0.f, 0.f, -1.f));
}
You never actually bother to declare/define a cameraPosition (presumably) uniform in your vertex shader or set its value via an appropriate glUniform*() call.
...not that you'd really want to since then every vertex would end up being set to the same position and you'd end up with a dot somewhere (maybe) on screen.
Rather,
gl_Position = projection * view * model * vec4(cameraPosition.x, cameraPosition.y, cameraPosition.z, 1.0f);
should probably be:
gl_Position = projection * view * model * vec4(position, 1.0);
...so all your fancy geometry in verts actually has some chance of being sensibly displayed.
I need to draw a simple rectangle (not a filled box) with directx 11.
I have found this code:
const float x = 0.1;
const float y = 0.1;
const float height = 0.9;
const float width = 0.9;
VERTEX OurVertices[] =
{
{ x, y, 0, col },
{ x + width, y, 0, col },
{ x, y + height, 0, col },
{ x + width, y, 0, col },
{ x + width, y + height, 0 , col },
{ x, y + height, 0, col }
};
static const XMVECTORF32 col = { 1.f, 2.f, 3.f, 4.f };
// this is the function used to render a single frame
void RenderFrameTest(void)
{
// float color[4] = { 0.0f, 0.2f, 0.4f, 1.0f };
float color[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
// clear the back buffer to a deep blue
devcon->ClearRenderTargetView(backbuffer, color);
// select which vertex buffer to display
UINT stride = sizeof(VERTEX);
UINT offset = 0;
devcon->IASetVertexBuffers(0, 1, &pVBuffer, &stride, &offset);
// select which primtive type we are using
// draw the vertex buffer to the back buffer
devcon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
devcon->Draw(sizeof(OurVertices) / sizeof(VERTEX), 0);
swapchain->Present(0, 0);
}
void DrawRectangle(float x, float y, float width, float height, XMVECTORF32 col)
{
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(OurVertices);
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
HRESULT val = dev->CreateBuffer(&bd, NULL, &pVBuffer); // create the buffer
D3D11_MAPPED_SUBRESOURCE ms;
val = devcon->Map(pVBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer
memcpy(ms.pData, OurVertices, sizeof(OurVertices)); // copy the data
devcon->Unmap(pVBuffer, NULL);
}
but the result is not what I expected:
I suspect the problem is OurVertices array and "D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP" but I don't have have experience with DirectX in general.
Can you help me please ?
You have 6 vertices defined for a rectangle, which means you want to use TriangleList topology and not TriangleStrip topology.
This is a question for anybody experienced with the Oculus Rift C++ SDK.
SDK Version: ovr_sdk_win_1.20.0_public
IDE: VS2013
I am trying to resolve a depth buffer problem in my code for a simplified 3D engine for the Oculus Rift DK2.
The OculusRoomTiny example supplied with the SDK is very complex as it is designed with versatility in mind. So, I've taken the SuperMinimal Sample code and used that as a basis for my engine. The SuperMinimal Sample did did not support multi-colour vertexes or depth buffers. So my code includes both.
I've had no problem creating depth buffers using Microsoft DirectX-11 libraries on PC apps so think it's an Oculus specific challenge. Note: the OculusRoomTiny example depth buffer works fine but is encapsulated in classes too complex for my code.
In my code, the Cube rendered as would be expected but inclusion of the Depth buffer only renders the world background colour.
I ripped the depth buffer code from the OculusRoomTiny_Advanced demo and am sure I have integrated it religiously.
I've posted my code for comment. Please note, it is super minimal and does not clean up the COM objects.
Any advice would be welcome as I've been playing with the code now for 6 weeks!
main.cpp
#include "d3d11.h"
#include "d3dcompiler.h"
#include "OVR_CAPI_D3D.h"
#include "DirectXMath.h"
#include "models.h"
using namespace DirectX;
#pragma comment(lib, "d3dcompiler.lib")
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "d3d11.lib")
void CreateSampleModel(ID3D11Device * Device, ID3D11DeviceContext *
Context);
void RenderSampleModel(XMMATRIX * viewProj, ID3D11Device * Device, ID3D11DeviceContext * Context);
ID3D11Buffer * IndexBuffer;
ID3D11RenderTargetView * eyeRenderTexRtv[2][3];
ID3D11DepthStencilView *zbuffer[2]; // containing one for each eye
ovrLayerEyeFov ld = { { ovrLayerType_EyeFov } }; //Only using one layer Update this to an array if using several
ovrSession session;
ID3D11Device * Device;
ID3D11DeviceContext * Context;
void CreateDepthBufferForBothEyes(int eye)
{
// Create the Depth Buffer Texture
D3D11_TEXTURE2D_DESC texd;
ZeroMemory(&texd, sizeof(texd));
texd.Width = ld.Viewport[eye].Size.w;
texd.Height = ld.Viewport[eye].Size.h;
texd.ArraySize = 1;
texd.MipLevels = 1;
texd.SampleDesc.Count = 1; // This matches the RTV
texd.Format = DXGI_FORMAT_D32_FLOAT;
texd.BindFlags = D3D11_BIND_DEPTH_STENCIL;
ID3D11Texture2D *pDepthBuffer;
Device->CreateTexture2D(&texd, NULL, &pDepthBuffer);
// Describe specific properties of the Depth Stencil Buffer
D3D11_DEPTH_STENCIL_VIEW_DESC dsvd;
ZeroMemory(&dsvd, sizeof(dsvd));
dsvd.Format = DXGI_FORMAT_D32_FLOAT; // Make the same as the texture format
dsvd.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
Device->CreateDepthStencilView(pDepthBuffer, &dsvd, &zbuffer[eye]);
pDepthBuffer->Release();
}
//-------------------------------------------------------------------------------------------------
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, LPWSTR, int)
{
// Init Rift and device
ovr_Initialize(0);
ovrGraphicsLuid luid;
ovr_Create(&session, &luid);
IDXGIFactory * DXGIFactory; CreateDXGIFactory1(__uuidof(IDXGIFactory), (void**)(&DXGIFactory));
IDXGIAdapter * DXGIAdapter; DXGIFactory->EnumAdapters(0, &DXGIAdapter);
D3D11CreateDevice(DXGIAdapter, D3D_DRIVER_TYPE_UNKNOWN, 0, 0, 0, 0, D3D11_SDK_VERSION, &Device, 0, &Context);
// Create eye render buffers
for (int eye = 0; eye < 2; eye++)
{
ld.Fov[eye] = ovr_GetHmdDesc(session).DefaultEyeFov[eye];
ld.Viewport[eye].Size = ovr_GetFovTextureSize(session, (ovrEyeType)eye, ld.Fov[eye], 1.0f);
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.Width = ld.Viewport[eye].Size.w;
desc.Height = ld.Viewport[eye].Size.h;
desc.MipLevels = 1;
desc.SampleCount = 1;
desc.StaticImage = ovrFalse;
desc.MiscFlags = ovrTextureMisc_DX_Typeless;
desc.BindFlags = ovrTextureBind_DX_RenderTarget;
ovr_CreateTextureSwapChainDX(session, Device, &desc, &ld.ColorTexture[eye]);
int textureCount = 0; ovr_GetTextureSwapChainLength(session, ld.ColorTexture[eye], &textureCount);
for (int j = 0; j < textureCount; j++) // Creates 3 backbuffers for each eye
{
ID3D11Texture2D* tex; ovr_GetTextureSwapChainBufferDX(session, ld.ColorTexture[eye], j, IID_PPV_ARGS(&tex));
D3D11_RENDER_TARGET_VIEW_DESC rtvd = { DXGI_FORMAT_R8G8B8A8_UNORM, D3D11_RTV_DIMENSION_TEXTURE2D };
Device->CreateRenderTargetView(tex, &rtvd, &eyeRenderTexRtv[eye][j]);
}
CreateDepthBufferForBothEyes(eye);
}
// Create sample model to be rendered in VR
CreateSampleModel(Device,Context);
// Loop for some frames, then terminate
float camX = 0.0f;
float camY = 0.0f;
float camZ = 0.0f;
for (long long frameIndex = 0; frameIndex < 1000;)
{
if (GetKeyState(VK_LEFT) & 0x8000)
camX -= 0.001f;
if (GetKeyState(VK_RIGHT) & 0x8000)
camX += 0.001f;
if (GetKeyState(VK_UP) & 0x8000)
camY += 0.001f;
if (GetKeyState(VK_DOWN) & 0x8000)
camY -= 0.001f;
if (GetKeyState(VK_NEXT) & 0x8000)
camZ += 0.001f;
if (GetKeyState(VK_PRIOR) & 0x8000)
camZ -= 0.001f;
// Get pose using a default IPD
ovrPosef HmdToEyePose[2] = {{{0,0,0,1}, {-0.032f, 0, 0}},
{{0,0,0,1}, {+0.032f, 0, 0}}};
ovrPosef pose[2]; ovr_GetEyePoses(session, 0, ovrTrue, HmdToEyePose, pose, &ld.SensorSampleTime);
//for (int eye = 0; eye < 2; eye++)
// ld.RenderPose[eye] = pose[eye]; // Update the Layer description with the new head position for each eye
// Render to each eye
for (int eye = 0; eye < 2; eye++)
{
ld.RenderPose[eye] = pose[eye]; // Update the Layer description with the new head position for each eye
// Set and clear current render target, and set viewport
int index = 0; ovr_GetTextureSwapChainCurrentIndex(session, ld.ColorTexture[eye], &index);
Context->OMSetRenderTargets(1, &eyeRenderTexRtv[eye][index], zbuffer[eye]); // zbuffer[eye]
Context->ClearRenderTargetView(eyeRenderTexRtv[eye][index], new float[]{ 0.1f, 0.0f, 0.0f, 0.0f });
Context->ClearDepthStencilView(zbuffer[eye], D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0, 0);
D3D11_VIEWPORT D3Dvp; // = { 0, 0, (float)ld.Viewport[eye].Size.w, (float)ld.Viewport[eye].Size.h };
D3Dvp.TopLeftX = 0.0f;
D3Dvp.TopLeftY = 0.0f;
D3Dvp.Width = (float)ld.Viewport[eye].Size.w;
D3Dvp.Height = (float)ld.Viewport[eye].Size.h;
D3Dvp.MinDepth = 0;
D3Dvp.MaxDepth = 1;
Context->RSSetViewports(1, &D3Dvp);
pose[eye].Position.z = 2.0f + camZ; // Move camera 2m from cube
pose[eye].Position.x = camX;
pose[eye].Position.y = camY;
// Calculate view and projection matrices using pose and SDK
XMVECTOR rot = XMLoadFloat4((XMFLOAT4 *)&pose[eye].Orientation);
XMVECTOR pos = XMLoadFloat3((XMFLOAT3 *)&pose[eye].Position);
XMVECTOR up = XMVector3Rotate(XMVectorSet(0, 1, 0, 0), rot);
XMVECTOR forward = XMVector3Rotate(XMVectorSet(0, 0, 1, 0), rot);
XMMATRIX view = XMMatrixLookAtLH(pos, XMVectorAdd(pos, forward), up);
ovrMatrix4f p = ovrMatrix4f_Projection(ld.Fov[eye], 0, 1, ovrProjection_None);
XMMATRIX proj = XMMatrixTranspose(XMLoadFloat4x4((XMFLOAT4X4 *)&p));
// Render model and commit frame
RenderSampleModel(&XMMatrixMultiply(view, proj), Device, Context);
ovr_CommitTextureSwapChain(session, ld.ColorTexture[eye]);
}
// Send rendered eye buffers to HMD, and increment the frame if we're visible
ovrLayerHeader* layers[1] = { &ld.Header };
if (ovrSuccess == ovr_SubmitFrame(session, 0, nullptr, layers, 1))
frameIndex; // was frameIndex++; but changed to loop forever
}
ovr_Shutdown();
}
//---------------------------------------------------------------------------------------
// THIS CODE IS NOT SPECIFIC TO VR OR THE SDK, JUST USED TO DRAW SOMETHING IN VR
//---------------------------------------------------------------------------------------
void CreateSampleModel(ID3D11Device * Device, ID3D11DeviceContext * Context)
{
// Create Vertex Buffer
//#define V(n) (n&1?+1.0f:-1.0f), (n&2?-1.0f:+1.0f), (n&4?+1.0f:-1.0f)
//float vertices[] = { V(0), V(3), V(2), V(6), V(3), V(7), V(4), V(2), V(6), V(1), V(5), V(3), V(4), V(1), V(0), V(5), V(4), V(7) };
D3D11_BUFFER_DESC vbDesc = { sizeof(VERTEX) * NUM_OF_VERTICES, D3D11_USAGE_DEFAULT, D3D11_BIND_VERTEX_BUFFER };
D3D11_SUBRESOURCE_DATA initData = { tList };
ID3D11Buffer* VertexBuffer;
Device->CreateBuffer(&vbDesc, &initData, &VertexBuffer);
//create the index buffer
D3D11_BUFFER_DESC bd;
bd.Usage = D3D11_USAGE_DYNAMIC;
bd.ByteWidth = sizeof(short) * NUM_OF_INDICES; // 3 per triangle, 12 triangles
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bd.MiscFlags = 0;
Device->CreateBuffer(&bd, NULL, &IndexBuffer);
D3D11_MAPPED_SUBRESOURCE ms;
Context->Map(IndexBuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms); // map the buffer
memcpy(ms.pData, indexes, NUM_OF_INDICES * sizeof(short)); // copy the data
Context->Unmap(IndexBuffer, NULL);
// Create Vertex Shader
char* vShader = "float4x4 m;"
"struct VOut { "
" float4 position : SV_POSITION;"
" float4 color : COLOR;"
"}; "
"VOut VS(float4 p1 : POSITION, float4 colour: COLOR)"
"{"
" VOut output;"
" output.position = mul(m, p1);"
" output.color = colour;"
" return output;"
"}";
ID3D10Blob * pBlob; D3DCompile(vShader, strlen(vShader), "VS", 0, 0, "VS", "vs_4_0", 0, 0, &pBlob, 0);
ID3D11VertexShader * VertexShader;
Device->CreateVertexShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), 0, &VertexShader);
// Create Input Layout
D3D11_INPUT_ELEMENT_DESC elements[] = {
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
ID3D11InputLayout * InputLayout;
Device->CreateInputLayout(elements, 2, pBlob->GetBufferPointer(), pBlob->GetBufferSize(), &InputLayout);
// Create Pixel Shader
char* pShader = "float4 PS(float4 position : POSITION, float4 colour : COLOR) : SV_Target { return colour; }";
D3DCompile(pShader, strlen(pShader), "PS", 0, 0, "PS", "ps_4_0", 0, 0, &pBlob, 0);
ID3D11PixelShader * PixelShader;
Device->CreatePixelShader(pBlob->GetBufferPointer(), pBlob->GetBufferSize(), 0, &PixelShader);
Context->IASetInputLayout(InputLayout);
Context->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R16_UINT, 0);
UINT stride = sizeof(float) * 4U; // 7U
UINT offset = 0;
Context->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
Context->VSSetShader(VertexShader, 0, 0);
Context->PSSetShader(PixelShader, 0, 0);
}
//------------------------------------------------------
void RenderSampleModel(XMMATRIX * viewProj, ID3D11Device * Device, ID3D11DeviceContext * Context)
{
D3D11_BUFFER_DESC desc = { sizeof(XMMATRIX), D3D11_USAGE_DYNAMIC, D3D11_BIND_CONSTANT_BUFFER, D3D11_CPU_ACCESS_WRITE };
D3D11_SUBRESOURCE_DATA initData = { viewProj };
ID3D11Buffer * ConstantBuffer; Device->CreateBuffer(&desc, &initData, &ConstantBuffer);
Context->VSSetConstantBuffers(0, 1, &ConstantBuffer);
Context->DrawIndexed(NUM_OF_INDICES, 0, 0);
}
models.h
#ifndef MODELS_H
#define MODELS_H
#include "DirectXMath.h"
using namespace DirectX;
#define NUM_OF_MODELS 1
struct VERTEX{
float x;
float y;
float z;
uint32_t C; // Colour
};
#define NUM_OF_VERTICES 24
#define NUM_OF_INDICES 36
extern VERTEX tList[];
extern short indexes[];
#endif
models.cpp
#include "models.h"
VERTEX tList[] = {
{ -0.1f, 0.1f, 0.2f, 0xFF0000FF }, // Cube Vertex Index 0
{ 0.1f, 0.1f, 0.2f, 0xFF0000FF }, // 1
{ -0.1f, -0.1f, 0.2f, 0xFF0000FF }, // 2
{ 0.1f, -0.1f, 0.2f, 0xFF0000FF }, // 3
{ -0.1f, 0.1f, -0.0f, 0x00FF00FF }, // 4
{ 0.1f, 0.1f, -0.0f, 0x00FF00FF }, // 5
{ -0.1f, -0.1f, -0.0f, 0x00FF00FF }, // 6
{ 0.1f, -0.1f, -0.0f, 0x00FF00FF }, // 7
{ 0.1f, 0.1f, 0.2f, 0x0000FFFF }, // 8
{ 0.1f, 0.1f, -0.0f, 0x0000FFFF }, // 9
{ 0.08f, -0.1f, 0.2f, 0x0000FFFF }, // 10 Distorted in prep to test Depth
{ 0.08f, -0.1f, -0.0f, 0x0000FFFF }, // 11 Distorted in prep to test Depth
{ -0.1f, 0.1f, 0.2f, 0xFF0000FF }, // 12
{ -0.1f, 0.1f, -0.0f, 0xFF0000FF }, // 13
{ -0.1f, -0.1f, 0.2f, 0xFF0000FF }, // 14
{ -0.1f, -0.1f, -0.0f, 0xFF0000FF }, // 15
{ -0.1f, 0.1f, -0.0f, 0x00FF00FF }, // 16
{ 0.1f, 0.1f, -0.0f, 0x00FF00FF }, // 17
{ -0.1f, 0.1f, 0.2f, 0x00FF00FF }, // 18
{ 0.1f, 0.1f, 0.2f, 0x00FF00FF }, // 19
{ -0.1f, -0.1f, -0.0f, 0x00FFFFFF }, // 20
{ 0.1f, -0.1f, -0.0f, 0x00FFFFFF }, // 21
{ -0.1f, -0.1f, 0.2f, 0x00FFFFFF }, // 22
{ 0.1f, -0.1f, 0.2f, 0x00FFFFFF }, // 23
};
short indexes[] = {
0, 1, 2, // FRONT QUAD
2, 1, 3,
5, 4, 6, // BACK QUAD
5, 6, 7,
8, 9, 11, // RIGHT QUAD
8, 11, 10,
13, 12,14, // LEFT QUAD
13, 14, 15,
18,16, 17, // TOP QUAD
18, 17, 19,
22, 23, 21, // BOTTOM QUAD
22, 21, 20
};
After much research I've found my own solution:
The line
ovrMatrix4f p = ovrMatrix4f_Projection(ld.Fov[eye], 0, 1, ovrProjection_None);
Creates the projection Matrix.
A was simply a case of setting the projection depth correctly
float zNear = 0.1f;
float zFar = 1000.0f;
ovrMatrix4f p = ovrMatrix4f_Projection(ld.Fov[eye], zNear, zFar, ovrProjection_None);
Amazing how, now 7 weeks of investigating, revealed the flaw as a simple ommission!
Hi I just got Introduction to 3D Game Programming with DirectX 11 and am trying to get the BoxDemo code working, however I am having troubles with the effect.
Basically the compiled shader part works, and even the creation of the effect works but when it comes to getting the description from the effect pass, I get a Access Violation error, I have tried, and researched online but can't find any help for this matter.
Please note I have the latest version of effects11.
Here is the fx:
//***************************************************************************** **********
// color.fx by Frank Luna (C) 2011 All Rights Reserved.
//
// Transforms and colors geometry.
//***************************************************************************************
cbuffer cbPerObject
{
float4x4 gWorldViewProj;
};
struct VertexIn
{
float3 PosL : POSITION;
float4 Color : COLOR;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float4 Color : COLOR;
};
VertexOut VS(VertexIn vin)
{
VertexOut vout;
// Transform to homogeneous clip space.
vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
// Just pass vertex color into the pixel shader.
vout.Color = vin.Color;
return vout;
}
float4 PS(VertexOut pin) : SV_Target
{
return pin.Color;
}
technique11 ColorTech
{
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS()));
}
}
here is the cpp file:
#include "BoxApp.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd)
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
BoxApp theApp(hInstance);
if (!theApp.Init())
return 0;
return theApp.Run();
}
BoxApp::BoxApp(HINSTANCE hInstance)
: D3DApp(hInstance), mBoxVB(0), mBoxIB(0), mFX(0), mTech(0),
mfxWorldViewProj(0), mInputLayout(0),
mTheta(1.5f*MathHelper::Pi), mPhi(0.25f*MathHelper::Pi), mRadius(5.0f)
{
mMainWndCaption = L"Box Demo";
mLastMousePos.x = 0;
mLastMousePos.y = 0;
XMMATRIX I = XMMatrixIdentity();
XMStoreFloat4x4(&mWorld, I);
XMStoreFloat4x4(&mView, I);
XMStoreFloat4x4(&mProj, I);
}
BoxApp::~BoxApp()
{
ReleaseCOM(mBoxVB);
ReleaseCOM(mBoxIB);
ReleaseCOM(mFX);
ReleaseCOM(mInputLayout);
}
bool BoxApp::Init()
{
if (!D3DApp::Init())
return false;
BuildGeometryBuffers();
BuildFX();
BuildVertexLayout();
return true;
}
void BoxApp::OnResize()
{
D3DApp::OnResize();
// The window resized, so update the aspect ratio and recompute the projection matrix.
XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathHelper::Pi, AspectRatio(), 1.0f, 1000.0f);
XMStoreFloat4x4(&mProj, P);
}
void BoxApp::UpdateScene(float dt)
{
// Convert Spherical to Cartesian coordinates.
float x = mRadius*sinf(mPhi)*cosf(mTheta);
float z = mRadius*sinf(mPhi)*sinf(mTheta);
float y = mRadius*cosf(mPhi);
// Build the view matrix.
XMVECTOR pos = XMVectorSet(x, y, z, 1.0f);
XMVECTOR target = XMVectorZero();
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
XMStoreFloat4x4(&mView, V);
}
void BoxApp::DrawScene()
{
md3dImmediateContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::LightSteelBlue));
md3dImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
md3dImmediateContext->IASetInputLayout(mInputLayout);
md3dImmediateContext- >IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
UINT stride = sizeof(Vertex);
UINT offset = 0;
md3dImmediateContext->IASetVertexBuffers(0, 1, &mBoxVB, &stride, &offset);
md3dImmediateContext->IASetIndexBuffer(mBoxIB, DXGI_FORMAT_R32_UINT, 0);
// Set constants
XMMATRIX world = XMLoadFloat4x4(&mWorld);
XMMATRIX view = XMLoadFloat4x4(&mView);
XMMATRIX proj = XMLoadFloat4x4(&mProj);
XMMATRIX worldViewProj = world*view*proj;
mfxWorldViewProj->SetMatrix(reinterpret_cast<float*>(&worldViewProj));
D3DX11_TECHNIQUE_DESC techDesc;
mTech->GetDesc(&techDesc);
for (UINT p = 0; p < techDesc.Passes; ++p)
{
mTech->GetPassByIndex(p)->Apply(0, md3dImmediateContext);
// 36 indices for the box.
md3dImmediateContext->DrawIndexed(36, 0, 0);
}
HRESULT hr = (mSwapChain->Present(0, 0));
}
void BoxApp::OnMouseDown(WPARAM btnState, int x, int y)
{
mLastMousePos.x = x;
mLastMousePos.y = y;
SetCapture(mhMainWnd);
}
void BoxApp::OnMouseUp(WPARAM btnState, int x, int y)
{
ReleaseCapture();
}
void BoxApp::OnMouseMove(WPARAM btnState, int x, int y)
{
if ((btnState & MK_LBUTTON) != 0)
{
// Make each pixel correspond to a quarter of a degree.
float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));
float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y));
// Update angles based on input to orbit camera around box.
mTheta += dx;
mPhi += dy;
// Restrict the angle mPhi.
mPhi = MathHelper::Clamp(mPhi, 0.1f, MathHelper::Pi - 0.1f);
}
else if ((btnState & MK_RBUTTON) != 0)
{
// Make each pixel correspond to 0.005 unit in the scene.
float dx = 0.005f*static_cast<float>(x - mLastMousePos.x);
float dy = 0.005f*static_cast<float>(y - mLastMousePos.y);
// Update the camera radius based on input.
mRadius += dx - dy;
// Restrict the radius.
mRadius = MathHelper::Clamp(mRadius, 3.0f, 15.0f);
}
mLastMousePos.x = x;
mLastMousePos.y = y;
}
void BoxApp::BuildGeometryBuffers()
{
// Create vertex buffer
Vertex vertices[] =
{
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), (const float*)&Colors::White },
{ XMFLOAT3(-1.0f, +1.0f, -1.0f), (const float*)&Colors::Black },
{ XMFLOAT3(+1.0f, +1.0f, -1.0f), (const float*)&Colors::Red },
{ XMFLOAT3(+1.0f, -1.0f, -1.0f), (const float*)&Colors::Green },
{ XMFLOAT3(-1.0f, -1.0f, +1.0f), (const float*)&Colors::Blue },
{ XMFLOAT3(-1.0f, +1.0f, +1.0f), (const float*)&Colors::Yellow },
{ XMFLOAT3(+1.0f, +1.0f, +1.0f), (const float*)&Colors::Cyan },
{ XMFLOAT3(+1.0f, -1.0f, +1.0f), (const float*)&Colors::Magenta }
};
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(Vertex) * 8;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = vertices;
HRESULT hr1 = (md3dDevice->CreateBuffer(&vbd, &vinitData, &mBoxVB));
// Create the index buffer
UINT indices[] = {
// front face
0, 1, 2,
0, 2, 3,
// back face
4, 6, 5,
4, 7, 6,
// left face
4, 5, 1,
4, 1, 0,
// right face
3, 2, 6,
3, 6, 7,
// top face
1, 5, 6,
1, 6, 2,
// bottom face
4, 0, 3,
4, 3, 7
};
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT) * 36;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = indices;
HRESULT hr2 = (md3dDevice->CreateBuffer(&ibd, &iinitData, &mBoxIB));
}
void BoxApp::BuildFX()
{
DWORD shaderFlags = 0;
//#if defined( DEBUG ) || defined( _DEBUG )
// shaderFlags |= D3D10_SHADER_DEBUG;
// shaderFlags |= D3D10_SHADER_SKIP_OPTIMIZATION;
//#endif
ID3D10Blob* compiledShader = 0;
ID3D10Blob* compilationMsgs = 0;
HRESULT hr;
hr = D3DX11CompileFromFile(L"color.fx", NULL, NULL, "ColorTech", "fx_5_0"
, shaderFlags, 0, 0, &compiledShader, &compilationMsgs, &hr);
// compilationMsgs can store errors or warnings.
if (compilationMsgs != 0)
{
MessageBoxA(0, (char*)compilationMsgs->GetBufferPointer(), 0, 0);
ReleaseCOM(compilationMsgs);
}
// Even if there are no compilationMsgs, check to make sure there were no other errors.
if (FAILED(hr))
{
//DXTrace(__FILE__, (DWORD)__LINE__, hr, L"D3DX11CompileFromFile", true);
}
ID3D10Blob* pErrorBlob = 0;
//ID3DInclude* include = D3D_COMPILE_STANDARD_FILE_INCLUDE;
HRESULT hr3 = (D3DX11CreateEffectFromMemory(compiledShader->GetBufferPointer(), compiledShader->GetBufferSize(),
0, md3dDevice, &mFX));
//HRESULT hr3 = (D3DX11CreateEffectFromFile(L"color.fx", shaderFlags, md3dDevice, &mFX));
// Done with compiled shader.
ReleaseCOM(compiledShader);
mTech = mFX->GetTechniqueByName("ColorTech");
mfxWorldViewProj = mFX->GetVariableByName("gWorldViewProj")->AsMatrix();
}
void BoxApp::BuildVertexLayout()
{
// Create the vertex input layout.
D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
// Create the input layout
D3DX11_PASS_DESC passDesc;
ID3DX11EffectPass* pass = mTech->GetPassByIndex(0);
if (pass != nullptr)
{
HRESULT hr5 = pass->GetDesc(&passDesc);
HRESULT hr4 = (md3dDevice->CreateInputLayout(vertexDesc, 2, passDesc.pIAInputSignature,
passDesc.IAInputSignatureSize, &mInputLayout));
}
}
You've commented out all the error checks, so it's probably that D3DX11CreateEffectFromMemory returned a failure. If a function returns an HRESULT, you must check it at runtime or you will miss potential errors. That means using the FAILED macro, the SUCCEEDED macro, or the ThrowIfFailed helper on every function that returns an HRESULT. See MSDN.
Since you are making use of the Effects for Direct3D 11 library, you should pick up the latest version from GitHub. If you are using VS 2013 or VS 2015 for a Windows desktop app, you can also get it from NuGet.
You should also read this post which has some additional notes about the Introduction to 3D Game Programming with DirectX 11 book. It's a good book, but unfortunately it was published just before the DirectX development story was changed rather radically with the deprecation of the DirectX SDK. See MSDN.
You should also take a look at the DirectX Tool Kit tutorials, particularly the material on ComPtr.
Ok finally here is the final code
BoxDemoApp.h:
#pragma once
//#pragma comment(lib, "Effects11.lib")
#pragma comment(lib, "d3d11.lib")
//#pragma comment(lib, "d3dx11.lib")
//#pragma comment(lib, "DxErr.lib")
//#pragma comment(lib, "D3DCompiler.lib")
//#pragma comment(lib, "dxguid.lib")
#include <windows.h>
#include <d3d11_1.h>
#include "d3dApp.h"
#include "d3dx11effect.h"
#include "MathHelper.h"
#include "StaticCamera.h"
#include "Conversion.h"
#include "DefinedModel.h"
#include <iostream>
using namespace std;
class BoxDemoApp : public D3DApp
{
public:
BoxDemoApp(HINSTANCE hInstance);
~BoxDemoApp();
bool Init();
bool InitScene();
void OnResize();
void UpdateScene(float dt);
void DrawScene();
private:
DefinedModel* m_Model;
bool m_bLoaded;
bool m_bInitModel;
};
BoxDemoApp.cpp:
#include "BoxDemoApp.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd)
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
BoxDemoApp theApp(hInstance);
if (!theApp.Init())
return 0;
return theApp.Run();
}
BoxDemoApp::BoxDemoApp(HINSTANCE hInstance)
: D3DApp(hInstance)
{
mMainWndCaption = L"Box Demo";
m_bLoaded = false;
m_bInitModel = false;
m_Model = NULL;
}
BoxDemoApp::~BoxDemoApp()
{
m_Model->Destroy();
SafeDelete(m_Model);
}
bool BoxDemoApp::Init()
{
if (!D3DApp::Init())
return false;
InitScene();
return true;
}
bool BoxDemoApp::InitScene()
{
//Camera information
m_Camera->setCamera(XMFLOAT4(0.0f, 3.0f, -8.0f, 0.0f),
XMFLOAT4(0.0f, 0.0f, 0.0f, 0.0f),
XMFLOAT4(0.0f, 1.0f, 0.0f, 0.0f));
//Set the Projection matrix
m_Camera->setFOV(0.4f*3.14f, (float)mClientWidth / mClientHeight, 1.0f, 1000.0f);
///////////////**************new**************////////////////////
return true;
}
void BoxDemoApp::OnResize()
{
D3DApp::OnResize();
//Create the Viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = this->mClientWidth;
viewport.Height = this->mClientHeight;
//Set the Viewport
md3dImmediateContext->RSSetViewports(1, &viewport);
//Set the Projection matrix
m_Camera->setFOV(0.4f*3.14f, (float)mClientWidth / mClientHeight, 1.0f, 1000.0f);
///////////////**************new**************////////////////////
}
void BoxDemoApp::UpdateScene(float dt)
{
if (m_bLoaded && !m_bInitModel)
{
m_Model = new DefinedModel(this);
m_Model->create3DCube(4, 4, 4);
m_bInitModel = true;
}
}
void BoxDemoApp::DrawScene()
{
assert(md3dImmediateContext);
assert(mSwapChain);
md3dImmediateContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::LightSteelBlue));
md3dImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
if (m_bInitModel)
{
m_Model->Draw();
}
if (!m_bLoaded)
{
m_bLoaded = true;
}
HRESULT hr = (mSwapChain->Present(0, 0));
}
MathHelper.h:
//***************************************************************************************
// MathHelper.h by Frank Luna (C) 2011 All Rights Reserved.
//
// Helper math class.
//***************************************************************************************
#pragma once
#ifndef MATHHELPER_H
#define MATHHELPER_H
#include <Windows.h>
#include <xnamath.h>
class MathHelper
{
public:
// Returns random float in [0, 1).
static float RandF()
{
return (float)(rand()) / (float)RAND_MAX;
}
// Returns random float in [a, b).
static float RandF(float a, float b)
{
return a + RandF()*(b - a);
}
template<typename T>
static T Min(const T& a, const T& b)
{
return a < b ? a : b;
}
template<typename T>
static T Max(const T& a, const T& b)
{
return a > b ? a : b;
}
template<typename T>
static T Lerp(const T& a, const T& b, float t)
{
return a + (b - a)*t;
}
template<typename T>
static T Clamp(const T& x, const T& low, const T& high)
{
return x < low ? low : (x > high ? high : x);
}
// Returns the polar angle of the point (x,y) in [0, 2*PI).
static float AngleFromXY(float x, float y);
static XMMATRIX InverseTranspose(CXMMATRIX M)
{
// Inverse-transpose is just applied to normals. So zero out
// translation row so that it doesn't get into our inverse-transpose
// calculation--we don't want the inverse-transpose of the translation.
XMMATRIX A = M;
A.r[3] = XMVectorSet(0.0f, 0.0f, 0.0f, 1.0f);
XMVECTOR det = XMMatrixDeterminant(A);
return XMMatrixTranspose(XMMatrixInverse(&det, A));
}
static XMVECTOR RandUnitVec3();
static XMVECTOR RandHemisphereUnitVec3(XMVECTOR n);
static const float Infinity;
static const float Pi;
};
#endif // MATHHELPER_H
MathHelper.cpp:
//***************************************************************************************
// MathHelper.cpp by Frank Luna (C) 2011 All Rights Reserved.
//***************************************************************************************
#include "MathHelper.h"
#include <float.h>
#include <cmath>
const float MathHelper::Infinity = FLT_MAX;
const float MathHelper::Pi = 3.1415926535f;
float MathHelper::AngleFromXY(float x, float y)
{
float theta = 0.0f;
// Quadrant I or IV
if (x >= 0.0f)
{
// If x = 0, then atanf(y/x) = +pi/2 if y > 0
// atanf(y/x) = -pi/2 if y < 0
theta = atanf(y / x); // in [-pi/2, +pi/2]
if (theta < 0.0f)
theta += 2.0f*Pi; // in [0, 2*pi).
}
// Quadrant II or III
else
theta = atanf(y / x) + Pi; // in [0, 2*pi).
return theta;
}
XMVECTOR MathHelper::RandUnitVec3()
{
XMVECTOR One = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
XMVECTOR Zero = XMVectorZero();
// Keep trying until we get a point on/in the hemisphere.
while (true)
{
// Generate random point in the cube [-1,1]^3.
XMVECTOR v = XMVectorSet(MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), 0.0f);
// Ignore points outside the unit sphere in order to get an even distribution
// over the unit sphere. Otherwise points will clump more on the sphere near
// the corners of the cube.
if (XMVector3Greater(XMVector3LengthSq(v), One))
continue;
return XMVector3Normalize(v);
}
}
XMVECTOR MathHelper::RandHemisphereUnitVec3(XMVECTOR n)
{
XMVECTOR One = XMVectorSet(1.0f, 1.0f, 1.0f, 1.0f);
XMVECTOR Zero = XMVectorZero();
// Keep trying until we get a point on/in the hemisphere.
while (true)
{
// Generate random point in the cube [-1,1]^3.
XMVECTOR v = XMVectorSet(MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), MathHelper::RandF(-1.0f, 1.0f), 0.0f);
// Ignore points outside the unit sphere in order to get an even distribution
// over the unit sphere. Otherwise points will clump more on the sphere near
// the corners of the cube.
if (XMVector3Greater(XMVector3LengthSq(v), One))
continue;
// Ignore points in the bottom hemisphere.
if (XMVector3Less(XMVector3Dot(n, v), Zero))
continue;
return XMVector3Normalize(v);
}
}
StaticCamera.h:
#pragma once
#include "MathHelper.h"
#include "Conversion.h"
class StaticCamera
{
public:
StaticCamera();
~StaticCamera();
XMMATRIX* WVP();
XMMATRIX* World();
XMMATRIX* camView();
XMMATRIX* camProjection();
XMVECTOR* camPosition();
XMVECTOR* camTarget();
XMVECTOR* camUp();
void WVP(XMMATRIX WVP);
void World(XMMATRIX World);
void setFOV(float FOV, float aspectRatio, float nearZ, float farZ);
void setCamera(XMFLOAT4 position, XMFLOAT4 Target, XMFLOAT4 Up);
void updateMatrix();
private:
///////////////**************new**************////////////////////
XMMATRIX m_WVP;
XMMATRIX m_World;
XMMATRIX m_camView;
XMMATRIX m_camProjection;
XMVECTOR m_camPosition;
XMVECTOR m_camTarget;
XMVECTOR m_camUp;
///////////////**************new**************////////////////////
};
StaticCamera.cpp:
#include "StaticCamera.h"
StaticCamera::StaticCamera()
{
}
StaticCamera::~StaticCamera()
{
}
XMMATRIX* StaticCamera::WVP()
{
return &m_WVP;
}
XMMATRIX* StaticCamera::World()
{
return &m_World;
}
XMMATRIX* StaticCamera::camView()
{
return &m_camView;
}
XMMATRIX* StaticCamera::camProjection()
{
return &m_camProjection;
}
XMVECTOR* StaticCamera::camPosition()
{
return &m_camPosition;
}
XMVECTOR* StaticCamera::camTarget()
{
return &m_camTarget;
}
XMVECTOR* StaticCamera::camUp()
{
return &m_camUp;
}
void StaticCamera::WVP(XMMATRIX WVP)
{
m_WVP = WVP;
}
void StaticCamera::World(XMMATRIX World)
{
m_World = World;
}
void StaticCamera::setFOV(float FOV, float aspectRatio, float nearZ, float farZ)
{
//Set the Projection matrix
m_camProjection = XMMatrixPerspectiveFovLH(FOV, aspectRatio, nearZ, farZ);
updateMatrix();
}
void StaticCamera::setCamera(XMFLOAT4 position, XMFLOAT4 Target, XMFLOAT4 Up)
{
//Camera information
m_camPosition = Conversion::XMFLOAT4TOXMVECTOR(position);
m_camTarget = Conversion::XMFLOAT4TOXMVECTOR(Target);
m_camUp = Conversion::XMFLOAT4TOXMVECTOR(Up);
//Set the View matrix
m_camView = XMMatrixLookAtLH(m_camPosition, m_camTarget, m_camUp);
///////////////**************new**************////////////////////
updateMatrix();
}
void StaticCamera::updateMatrix()
{
m_World = XMMatrixIdentity();
m_WVP = (m_World * m_camView * m_camProjection);
}
Conversion.h:
#pragma once
#include "MathHelper.h"
#include <vector>
using namespace std;
static class Conversion
{
public:
static XMFLOAT4 XMVECTORTOXMFLOAT4(XMVECTOR Xmvector);
static XMFLOAT3 XMVECTORTOXMFLOAT3(XMVECTOR Xmvector);
static XMVECTOR XMFLOAT4TOXMVECTOR(XMFLOAT4 Xmfloat);
static void INTVECTORTOARRAY(std::vector<int> vector, int *arr);
static LPCWSTR STRINGTOLPCWSTR(std::string stdstr);
};
Conversion.cpp:
#include "Conversion.h"
XMFLOAT4 Conversion::XMVECTORTOXMFLOAT4(XMVECTOR Xmvector)
{
XMFLOAT4 pos;
XMStoreFloat4(&pos, Xmvector);
return pos;
}
XMFLOAT3 Conversion::XMVECTORTOXMFLOAT3(XMVECTOR Xmvector)
{
XMFLOAT3 pos;
XMStoreFloat3(&pos, Xmvector);
return pos;
}
XMVECTOR Conversion::XMFLOAT4TOXMVECTOR(XMFLOAT4 Xmfloat)
{
return XMLoadFloat4(&Xmfloat);
}
void Conversion::INTVECTORTOARRAY(std::vector<int> vector, int *arr)
{
arr = &vector[0];
}
LPCWSTR Conversion::STRINGTOLPCWSTR(std::string stdstr)
{
std::wstring stemp = std::wstring(stdstr.begin(), stdstr.end());
LPCWSTR sw = stemp.c_str();
return sw;
}
DefinedModel.h:
#pragma once
#include <windows.h>
#include <d3d11_1.h>
#include "ShaderHelper.h"
#include "d3dx11effect.h"
#include "Conversion.h"
#include "Vector3.h"
#include "d3dApp.h"
class DefinedModel
{
public:
enum RastMode {
Solid,
Wireframe
};
public:
DefinedModel(D3DApp* parent);
~DefinedModel();
protected:
D3DApp* m_pParent;
//Vertex Structure and Vertex Layout (Input Layout)//
struct Vertex //Overloaded Vertex Structure
{
Vertex() {}
Vertex(float x, float y, float z,
float cr, float cg, float cb, float ca)
: pos(x, y, z), color(cr, cg, cb, ca) {}
XMFLOAT3 pos;
XMFLOAT4 color;
};
std::vector<Vertex> m_VertexArray;
std::vector<int> m_indices;
struct cbPerObject
{
XMMATRIX WVP;
};
cbPerObject cbPerObj;
ID3D11Buffer* cbPerObjectBuffer;
ID3D11Buffer* squareIndexBuffer;
ID3D11Buffer* squareVertBuffer;
ID3D11VertexShader* VS;
ID3D11PixelShader* PS;
ID3D10Blob* VS_Buffer;
ID3D10Blob* PS_Buffer;
ID3D11InputLayout* vertLayout;
///////////////**************new**************////////////////////
Vector3 m_Rotation;
Vector3 m_Scale;
Vector3 m_Offset;
XMMATRIX m_modelWorld;
///////////////**************new**************////////////////////
RastMode m_RastMode;
ID3D11RasterizerState* m_RastState;
public:
virtual void create3DCube(float Width, float Height, float Depth);
void Init();
void Draw();
void Rotation(float X, float Y, float Z);
void Scale(float X, float Y, float Z);
void Offset(float X, float Y, float Z);
void rastMode(RastMode rastmode);
Vector3 Rotation();
Vector3 Scale();
Vector3 Offset();
XMMATRIX worldMatrix();
void Destroy();
private:
virtual void InitBuffers();
virtual void InitFX();
virtual void InitInputLayout();
virtual void InitCBBuffer();
};
DefinedModel.cpp:
#include "DefinedModel.h"
DefinedModel::DefinedModel(D3DApp* parent): m_pParent(parent)
{
m_VertexArray = std::vector<Vertex>();
m_indices = std::vector<int>();
m_modelWorld = XMMatrixIdentity();
Offset(0, 0, 0);
Scale(1, 1, 1);
Rotation(0, 0, 0);
rastMode(RastMode::Solid);
}
DefinedModel::~DefinedModel()
{
}
void DefinedModel::create3DCube(float Width, float Height, float Depth)
{
///////////////**************new**************////////////////////
//Create the vertex buffer
m_VertexArray = {
Vertex(-Width / 2, -Height / 2, -Depth / 2, 1.0f, 0.0f, 0.0f, 1.0f),
Vertex(-Width / 2, +Height / 2, -Depth / 2, 0.0f, 1.0f, 0.0f, 1.0f),
Vertex(+Width / 2, +Height / 2, -Depth / 2, 0.0f, 0.0f, 1.0f, 1.0f),
Vertex(+Width / 2, -Height / 2, -Depth / 2, 1.0f, 1.0f, 0.0f, 1.0f),
Vertex(-Width / 2, -Height / 2, +Depth / 2, 0.0f, 1.0f, 1.0f, 1.0f),
Vertex(-Width / 2, +Height / 2, +Depth / 2, 1.0f, 1.0f, 1.0f, 1.0f),
Vertex(+Width / 2, +Height / 2, +Depth / 2, 1.0f, 0.0f, 1.0f, 1.0f),
Vertex(+Width / 2, -Height / 2, +Depth / 2, 1.0f, 0.0f, 0.0f, 1.0f),
};
///////////////**************new**************////////////////////
m_indices = {
// front face
0, 1, 2,
0, 2, 3,
// back face
4, 6, 5,
4, 7, 6,
// left face
4, 5, 1,
4, 1, 0,
// right face
3, 2, 6,
3, 6, 7,
// top face
1, 5, 6,
1, 6, 2,
// bottom face
4, 0, 3,
4, 3, 7
};
Init();
}
void DefinedModel::Init()
{
InitBuffers();
InitFX();
InitInputLayout();
InitCBBuffer();
}
void DefinedModel::InitBuffers()
{
HRESULT hr;
//index buffer creation
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;
iinitData.pSysMem = &m_indices[0];
hr = m_pParent->Device()->CreateBuffer(&indexBufferDesc, &iinitData, &squareIndexBuffer);
//vertex buffer creation
D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
vertexBufferDesc.ByteWidth = sizeof(Vertex) * 8;
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
D3D11_SUBRESOURCE_DATA vertexBufferData;
ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
vertexBufferData.pSysMem = &m_VertexArray[0];
hr = m_pParent->Device()->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &squareVertBuffer);
}
void DefinedModel::InitFX()
{
HRESULT hr;
//Compile Shaders from shader file
hr = D3DX11CompileFromFile(L"Trans.fx", 0, 0, "VS", "vs_4_0", 0, 0, 0, &VS_Buffer, 0, 0);
hr = D3DX11CompileFromFile(L"Trans.fx", 0, 0, "PS", "ps_4_0", 0, 0, 0, &PS_Buffer, 0, 0);
//Create the Shader Objects
hr = m_pParent->Device()->CreateVertexShader(VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), NULL, &VS);
hr = m_pParent->Device()->CreatePixelShader(PS_Buffer->GetBufferPointer(), PS_Buffer->GetBufferSize(), NULL, &PS);
//Set Vertex and Pixel Shaders
m_pParent->DeviceContext()->VSSetShader(VS, 0, 0);
m_pParent->DeviceContext()->PSSetShader(PS, 0, 0);
}
void DefinedModel::InitInputLayout()
{
HRESULT hr;
D3D11_INPUT_ELEMENT_DESC layout[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
UINT numElements = ARRAYSIZE(layout);
//Create the Input Layout
hr = m_pParent->Device()->CreateInputLayout(layout, numElements, VS_Buffer->GetBufferPointer(),
VS_Buffer->GetBufferSize(), &vertLayout);
}
void DefinedModel::InitCBBuffer()
{
HRESULT hr;
//Create the buffer to send to the cbuffer in effect file
D3D11_BUFFER_DESC cbbd;
ZeroMemory(&cbbd, sizeof(D3D11_BUFFER_DESC));
cbbd.Usage = D3D11_USAGE_DEFAULT;
cbbd.ByteWidth = sizeof(cbPerObject);
cbbd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
cbbd.CPUAccessFlags = 0;
cbbd.MiscFlags = 0;
hr = m_pParent->Device()->CreateBuffer(&cbbd, NULL, &cbPerObjectBuffer);
}
void DefinedModel::Draw()
{
//set index buffer
m_pParent->DeviceContext()->IASetIndexBuffer(squareIndexBuffer, DXGI_FORMAT_R32_UINT, 0);
//Set the vertex buffer
UINT stride = sizeof(Vertex);
UINT offset = 0;
m_pParent->DeviceContext()->IASetVertexBuffers(0, 1, &squareVertBuffer, &stride, &offset);
//Set the Input Layout
m_pParent->DeviceContext()->IASetInputLayout(vertLayout);
//Set Primitive Topology
m_pParent->DeviceContext()->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
//set rasteriser state
m_pParent->DeviceContext()->RSSetState(m_RastState);
//Matrices
///////////////**************new**************////////////////////
//Set the WVP matrix and send it to the constant buffer in effect file
XMMATRIX WVP = (worldMatrix()) * (*m_pParent->Camera()->camView()) * (*m_pParent->Camera()->camProjection());
cbPerObj.WVP = XMMatrixTranspose(WVP);
m_pParent->DeviceContext()->UpdateSubresource(cbPerObjectBuffer, 0, NULL, &cbPerObj, 0, 0);
m_pParent->DeviceContext()->VSSetConstantBuffers(0, 1, &cbPerObjectBuffer);
//draw shape
m_pParent->DeviceContext()->DrawIndexed(m_indices.size(), 0, 0);
}
void DefinedModel::Rotation(float X, float Y, float Z)
{
m_Rotation = Vector3(X, Y, Z);
//m_Rotation.X = X;
//m_Rotation.Y = Y;
//m_Rotation.Z = Z;
}
void DefinedModel::Scale(float X, float Y, float Z)
{
m_Scale = Vector3(X, Y, Z);
//m_Scale.X = X;
//m_Scale.Y = Y;
//m_Scale.Z = Z;
}
void DefinedModel::Offset(float X, float Y, float Z)
{
m_Offset = Vector3(X, Y, Z);
//m_Offset.X = X;
//m_Offset.Y = Y;
//m_Offset.Z = Z;
}
Vector3 DefinedModel::Rotation()
{
return m_Rotation;
}
Vector3 DefinedModel::Scale()
{
return m_Scale;
}
Vector3 DefinedModel::Offset()
{
return m_Offset;
}
XMMATRIX DefinedModel::worldMatrix()
{
XMMATRIX Scale = XMMatrixScaling(m_Scale.X(), m_Scale.Y(), m_Scale.Z());
XMMATRIX Rot = (XMMatrixRotationX(m_Rotation.X())) * (XMMatrixRotationY(m_Rotation.Y())) * (XMMatrixRotationZ(m_Rotation.Z()));
XMMATRIX Trans = XMMatrixTranslation(m_Offset.X(), m_Offset.Y(), m_Offset.Z());
// orbital
//m_modelWorld = Trans * Rot * Scale;
//on spot
m_modelWorld = Scale * Rot * Trans;
return m_modelWorld;
}
void DefinedModel::Destroy()
{
squareVertBuffer->Release();
squareIndexBuffer->Release();
VS->Release();
PS->Release();
VS_Buffer->Release();
PS_Buffer->Release();
vertLayout->Release();
cbPerObjectBuffer->Release();
m_VertexArray.clear();
m_indices.clear();
}
void DefinedModel::rastMode(RastMode rastmode)
{
HRESULT hr;
m_RastMode = rastmode;
switch (rastmode)
{
case RastMode::Solid:
{
///////////////**************new**************////////////////////
D3D11_RASTERIZER_DESC wfdesc;
ZeroMemory(&wfdesc, sizeof(D3D11_RASTERIZER_DESC));
wfdesc.FillMode = D3D11_FILL_SOLID;
wfdesc.CullMode = D3D11_CULL_BACK;
hr = m_pParent->Device()->CreateRasterizerState(&wfdesc, &m_RastState);
///////////////**************new**************////////////////////
break;
}
case RastMode::Wireframe:
{
///////////////**************new**************////////////////////
D3D11_RASTERIZER_DESC wfdesc;
ZeroMemory(&wfdesc, sizeof(D3D11_RASTERIZER_DESC));
wfdesc.FillMode = D3D11_FILL_WIREFRAME;
wfdesc.CullMode = D3D11_CULL_BACK;
hr = m_pParent->Device()->CreateRasterizerState(&wfdesc, &m_RastState);
///////////////**************new**************////////////////////
break;
}
}
}
Effect file (trans.fx):
cbuffer cbPerObject
{
float4x4 WVP;
};
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float4 Color : COLOR;
};
VS_OUTPUT VS(float4 inPos : POSITION, float4 inColor : COLOR)
{
VS_OUTPUT output;
output.Pos = mul(inPos, WVP);
output.Color = inColor;
return output;
}
float4 PS(VS_OUTPUT input) : SV_TARGET
{
return input.Color;
}
I'm doing something with DirectX 11 and came to a rectagle drawing (empty, non-colored), seemed simple for me at start (linelist_topology, 8 indices) but when I have it on the screen I see that my rectangle is kinda incomleted at left-top coordinate, there is a point of a background color there, the code is not complicated at all, vertices are 2D space:
SIMPLEVERTEX gvFrameVertices[4]=
{XMFLOAT3(0.0f,0.0f,1.0f),XMFLOAT2(0.0f, 0.0f),
XMFLOAT3(1.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 0.0f),
XMFLOAT3(1.0f, -1.0f, 1.0f), XMFLOAT2(1.0f, 1.0f),
XMFLOAT3(0.0f, -1.0f, 1.0f), XMFLOAT2(0.0f, 1.0f)};
indices:
WORD gvRectangularIndices[8] = { 0, 1, 1, 2, 2, 3, 3, 0 };
Shader just returns given color in constant buffer:
float4 PS_PANEL(PS_INPUT input) : SV_Target
{
return fontcolor;
}
Function code itself:
VOID rectangle(INT _left, INT _top, INT _width, INT _height, XMFLOAT4 _color)
{
XMMATRIX scale;
XMMATRIX translate;
XMMATRIX world;
scale = XMMatrixScaling( _width, _height, 1.0f );
translate = XMMatrixTranslation(_left, gvHeight - _top, 1.0f);
world = scale * translate;
gvConstantBufferData.world = XMMatrixTranspose(world);
gvConstantBufferData.index = 1.0f;
gvConstantBufferData.color = _color;
gvContext->PSSetShader(gvPanelPixelshader, NULL, 0);
gvContext->UpdateSubresource(gvConstantBuffer, 0, NULL, &gvConstantBufferData, 0, 0 );
gvContext->IASetIndexBuffer(gvLinelistIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
gvContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_LINELIST );
gvContext->DrawIndexed(8, 0, 0);
gvContext->IASetIndexBuffer(gvTriangleslistIndexBuffer, DXGI_FORMAT_R16_UINT, 0);
gvContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
};
gvHeight - _top - I'm using orthographic matrix for projection, so the coordinate center is at left-bottom, that why need to substract for proper Y coordinate.
gvOrthographicProjection = XMMatrixOrthographicOffCenterLH( 0.0f, gvWidth, 0.0f, gvHeight, 0.01f, 100.0f );
Do you have any idea what can cause this pointal incompletness of a rectangle in my case or I need to supply more code info (don't really want to link lines of the whole initializations cause they seem very obvious and simple for me, done for /at c++ and directx amateur level :)
Thank you:)