Related
I've successfully got some triangles to show up on screen together with some textures and a couple of event listeners. However, my texture is not rendering properly, it seems like pixels between 0 and 255 in brightness gets disorted while completely black/white pixels are rendering as they should. <- This might not be the best description but I will provide an example below.
This is the texture I'm trying to map onto my two triangles at the moment:
Here is the result after compiling and running the program:
What I think is that it may have something to do with the shaders, at the moment I do not have any shaders activated, neither vertex nor fragment shaders. I don't know if this is the problem but it might be a clue to it all.
Below is my main.cpp:
#include <iostream>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysymdef.h>
#include <GL/glx.h>
#include <GL/gl.h>
// #include <GL/glut.h>
// #include <GL/glu.h>
#include <sys/time.h>
#include <unistd.h>
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
#define WINDOW_WIDTH 800
#define WINDOW_HEIGHT 800
#define FPS 30
uint8_t shutdown = 0;
#define SKIP_TICKS ( 1000 / FPS )
// macros
void Render( void );
void HandleEvents( XEvent ev );
void Resize( int w, int h );
void Shutdown( void );
void fill_triangle_buffer( void );
struct triangle {
float color[ 3 ];
float p1[ 3 ];
float p2[ 3 ];
float p3[ 3 ];
};
struct triangle triangles[ 12 ];
static double GetMilliseconds() {
static timeval s_tTimeVal;
gettimeofday(&s_tTimeVal, NULL);
double time = s_tTimeVal.tv_sec * 1000.0; // sec to ms
time += s_tTimeVal.tv_usec / 1000.0; // us to ms
return time;
}
GLuint loadBMP_custom( const char * imagepath ) {
// Data read from the header of the BMP file
unsigned char header[54]; // Each BMP file begins by a 54-bytes header
unsigned int dataPos; // Position in the file where the actual data begins
unsigned int width, height;
unsigned int imageSize; // = width*height*3
// Actual RGB data
unsigned char * data;
// Open the file
FILE * file = fopen(imagepath,"rb");
if (!file) {
printf("Image could not be opened\n");
return 0;
}
if ( fread(header, 1, 54, file)!=54 ){ // If not 54 bytes read : problem
printf("Not a correct BMP file\n");
return false;
}
if ( header[0]!='B' || header[1]!='M' ){
printf("Not a correct BMP file\n");
return 0;
}
// Read ints from the byte array
dataPos = *(int*)&(header[0x0A]);
imageSize = *(int*)&(header[0x22]);
width = *(int*)&(header[0x12]);
height = *(int*)&(header[0x16]);
// Some BMP files are misformatted, guess missing information
if (imageSize==0)
imageSize=width*height*3; // 3 : one byte for each Red, Green and Blue component
if (dataPos==0)
dataPos=54; // The BMP header is done that way
// Create a buffer
data = new unsigned char [imageSize];
// Read the actual data from the file into the buffer
fread(data,1,imageSize,file);
//Everything is in memory now, the file can be closed
fclose(file);
// Create one OpenGL texture
GLuint textureID;
glGenTextures(1, &textureID);
// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, textureID);
// Give the image to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR, GL_UNSIGNED_BYTE, data);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
// return GLuint
return textureID;
}
int main (int argc, char ** argv){
Display *dpy = XOpenDisplay(0);
Window win;
XEvent ev;
int nelements;
GLXFBConfig *fbc = glXChooseFBConfig(dpy, DefaultScreen(dpy), 0, &nelements);
static int attributeList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None };
XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy),attributeList);
// Set Window attributes
XSetWindowAttributes swa;
swa.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;
win = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 0, 0, WINDOW_WIDTH, WINDOW_HEIGHT, 0, vi->depth, InputOutput, vi->visual, CWBorderPixel|CWColormap|CWEventMask, &swa);
// Select window inputs to be triggered in the eventlistener
XSelectInput( dpy, win, PointerMotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask );
XMapWindow (dpy, win);
//oldstyle context:
// GLXContext ctx = glXCreateContext(dpy, vi, 0, GL_TRUE);
std::cout << "glXCreateContextAttribsARB " << (void*) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB") << std::endl;
GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddress((const GLubyte*)"glXCreateContextAttribsARB");
int attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 0,
0};
// Redirect Close
Atom atomWmDeleteWindow = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
XSetWMProtocols(dpy, win, &atomWmDeleteWindow, 1);
// Create GLX OpenGL context
GLXContext ctx = glXCreateContextAttribsARB(dpy, *fbc, 0, true, attribs);
glXMakeCurrent( dpy, win, ctx );
glMatrixMode( GL_PROJECTION );
glEnable( GL_CULL_FACE );
glCullFace( GL_FRONT );
glFrustum( -1, 1, 1, -1, -1, 1 );
glClearColor (0, 0.5, 1, 1);
glClear (GL_COLOR_BUFFER_BIT);
glXSwapBuffers (dpy, win);
fill_triangle_buffer();
// Load and bind texture
glEnable(GL_TEXTURE_2D);
loadBMP_custom("textures/texture.bmp");
// prepare gameloop
double prevTime = GetMilliseconds();
double currentTime = GetMilliseconds();
double deltaTime = 0.0;
timeval time;
long sleepTime = 0;
gettimeofday(&time, NULL);
long nextGameTick = (time.tv_sec * 1000) + (time.tv_usec / 1000);
while ( shutdown != 1 ) {
// Get events if there is any
if (XPending(dpy) > 0) {
XNextEvent(dpy, &ev);
if (ev.type == Expose) {
XWindowAttributes attribs;
XGetWindowAttributes(dpy, win, &attribs);
Resize(attribs.width, attribs.height);
}
if (ev.type == ClientMessage) {
if (ev.xclient.data.l[0] == atomWmDeleteWindow) {
break;
}
}
else if (ev.type == DestroyNotify) {
break;
}
}
// Framelimit calculations, before heavy load
currentTime = GetMilliseconds();
deltaTime = double( currentTime - prevTime ) * 0.001;
prevTime = currentTime;
// Do work
HandleEvents( ev );
//Render();
glClear( GL_COLOR_BUFFER_BIT );
glBegin(GL_TRIANGLES);
glColor3f( 255, 255, 255 );
/*
glTexCoord2f( 0.0f, 1.0f );
glVertex3f( -0.5f, 0.5f, 0.0f );
glTexCoord2f( 1.0f, 1.0f );
glVertex3f( 0.5f, 0.5f, 0.0f );
glTexCoord2f( 0.0f, 0.0f );
glVertex3f( -0.5f, -0.5f, 0.0f );
glVertex3f( 0.5f, 0.5f, 0.0f );
glTexCoord2f( 1.0f, 0.0f );
glVertex3f( 0.5f, -0.5f, 0.0f );
glVertex3f( -0.5f, -0.5f, 0.0f );
*/
// first triangle, bottom left half
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( -0.5f, -0.5f, 0 );
glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -0.5f, 0.5f, 0 );
glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 0.5f, -0.5f, 0 );
// second triangle, top right half
glTexCoord2f( 1.0f, 0.0f ); glVertex3f( 0.5f, -0.5f, 0 );
glTexCoord2f( 0.0f, 1.0f ); glVertex3f( -0.5f, 0.5f, 0 );
glTexCoord2f( 1.0f, 1.0f ); glVertex3f( 0.5f, 0.5f, 0 );
glEnd();
glFlush();
glXSwapBuffers( dpy, win );
// Limit Framerate
gettimeofday( &time, NULL );
nextGameTick += SKIP_TICKS;
sleepTime = nextGameTick - ( (time.tv_sec * 1000) + (time.tv_usec / 1000) );
usleep((unsigned int)(sleepTime/1000));
}
ctx = glXGetCurrentContext();
glXDestroyContext(dpy, ctx);
}
void fill_triangle_buffer( void ){
triangles[ 0 ] = {
{ 1.0f, 0.0f, 0.0f },
{ -0.5f, -0.5f, -0.5f },
{ 0.5f, 0.5f, -0.5f },
{ 0.5f, -0.5f, -0.5f } };
triangles[ 1 ] = {
{ 0.0f, 0.0f, 1.0f },
{ -0.5f, -0.5f, -0.5f },
{ -0.5f, 0.5f, -0.5f },
{ 0.5f, 0.5f, -0.5f } };
triangles[ 2 ] = {
{ 0.0f, 0.0f, 1.0f },
{ 0.5f, 0.5f, -0.5f },
{ 0.5f, -0.5f, 0.5f },
{ 0.5f, -0.5f, -0.5f } };
triangles[ 3 ] = {
{ 1.0f, 1.0f, 0.0f },
{ 0.5f, 0.5f, -0.5f },
{ 0.5f, 0.5f, 0.5f },
{ 0.5f, -0.5f, 0.5f } };
triangles[ 4 ] = {
{ 1.0f, 0.0f, 0.0f },
{ -0.5f, -0.5f, 0.5f },
{ 0.5f, -0.5f, 0.5f },
{ -0.5f, 0.5f, 0.5f } };
triangles[ 5 ] = {
{ 0.0f, 0.0f, 1.0f },
{ 0.5f, -0.5f, 0.5f },
{ 0.5f, 0.5f, 0.5f },
{ -0.5f, 0.5f, 0.5f } };
triangles[ 6 ] = {
{ 0.0f, 0.0f, 1.0f },
{ -0.5f, 0.5f, -0.5f },
{ -0.5f, -0.5f, 0.5f },
{ -0.5f, 0.5f, 0.5f } };
triangles[ 7 ] = {
{ 1.0f, 1.0f, 0.0f },
{ -0.5f, 0.5f, -0.5f },
{ -0.5f, -0.5f, -0.5f },
{ -0.5f, -0.5f, 0.5f } };
triangles[ 8 ] = {
{ 1.0f, 0.0f, 0.0f },
{ -0.5f, 0.5f, -0.5f },
{ -0.5f, 0.5f, 0.5f },
{ 0.5f, 0.5f, 0.5f } };
triangles[ 9 ] = {
{ 0.0f, 0.0f, 1.0f },
{ -0.5f, 0.5f, -0.5f },
{ 0.5f, 0.5f, 0.5f },
{ 0.5f, 0.5f, -0.5f } };
triangles[ 10 ] = {
{ 0.0f, 0.0f, 1.0f },
{ 0.5f, -0.5f, -0.5f },
{ 0.5f, -0.5f, 0.5f },
{ -0.5f, -0.5f, 0.5f } };
triangles[ 11 ] = {
{ 1.0f, 1.0f, 0.0f },
{ 0.5f, -0.5f, -0.5f },
{ -0.5f, -0.5f, 0.5f },
{ -0.5f, -0.5f, -0.5f } };
}
void Resize(int w, int h) {
glViewport(0, 0, w, h);
}
void Shutdown() {
shutdown = 1;
}
void Render( void ) {
glClearColor ( 1.0f, 1.0f, 1.0f, 1 );
glClear( GL_COLOR_BUFFER_BIT );
glBegin(GL_TRIANGLES);
/*glColor3f( 0.0f, 1.0f, 0.0f );
glVertex3f( test_cnt, 0.0f, 1.0f );
glVertex3f( 1.0f, 0.0f, 1.0f );
glVertex3f( 0.0f, -1.0f, 1.0f );
*/
int numTriangles = sizeof(triangles)/sizeof(triangles[0]);
for ( int i = 0; i < numTriangles; i++ ) {
glClear( GL_COLOR_BUFFER_BIT );
glBegin(GL_TRIANGLES);
struct triangle tr = triangles[ i ];
glColor3f( tr.color[ 0 ], tr.color[ 1 ], tr.color[ 2 ] );
glVertex3f( tr.p1[ 0 ], tr.p1[ 1 ], tr.p1[ 2 ] );
glVertex3f( tr.p2[ 0 ], tr.p2[ 1 ], tr.p2[ 2 ] );
glVertex3f( tr.p3[ 0 ], tr.p3[ 1 ], tr.p3[ 2 ] );
}
glEnd();
glFlush();
}
float dx, dy;
float prevx, prevy;
uint8_t prev_defined = 0;
uint8_t key_down = 0;
void HandleEvents( XEvent ev ) {
int x, y;
switch ( ev.type ) {
case ButtonPress:
if ( ev.xbutton.button == 1 ) {
std::cout << "Left mouse down \n";
// glRotatef( 0.01, 0.0, 0.0, 1.0 );
if ( key_down == 0 )
prev_defined = 0;
key_down = 1;
}
break;
case ButtonRelease:
if ( ev.xbutton.button == 1 ) {
std::cout << "Left mouse up \n";
key_down = 0;
}
break;
case KeyPress:
if ( ev.xkey.keycode == 9 ) { // ESC
Shutdown();
}
break;
case MotionNotify:
x = ev.xmotion.x;
y = ev.xmotion.y;
if ( key_down == 0 )
break;
if ( !prev_defined ) {
prevx = x;
prevy = y;
prev_defined = 1;
break;
}
dx = x - prevx;
dy = y - prevy;
prevx = x;
prevy = y;
glRotatef( -dy/10, 1.0f, 0.0f, 0.0f );
glRotatef( -dx/10, 0.0f, 1.0f, 0.0f );
//std::cout << "Mouse X:" << x << ", Y: " << y << "\n";
break;
}
}
I compile with:
g++ -g -Wall -o _build/main main.cpp -I/opt/x11/include -L/usr/x11/lib -lglfw -lGLEW -lGL -lX11
OS:
Linux kali 5.9.0-kali4-amd64 #1 SMP Debian 5.9.11-1kali1 (2020-12-01) x86_64 GNU/Linux
Do anyone know how to resolve this issue in order to completely show above texture on my triangles?
I'm fairly new to Directx, so I have next to no idea what's going on here.
I have confirmed that the initial setup and activation of the window and DirectX API has been successful. However, although the drawing and update functions seem to be fully operational, they still aren't successful at displaying output. I've checked over the linker, my object classes, my effects file, and basically the entire project a dozen times over. Please help!
Cube.h
#pragma once
#pragma comment(lib,"d3d11.lib")
#include <d3d11.h>
#include <d3dcompiler.h>
#include <DirectXMath.h>
#include <string>
#include <WICTextureLoader.h>
#include <d3d11_2.h>
#include <vector>
using namespace DirectX;
struct Vertex {
XMFLOAT3 pos;
XMFLOAT2 texCoord;
XMFLOAT3 normal;
};
using namespace DirectX;
class Cube
{
private:
Vertex vertices[24];
XMMATRIX RotX, RotZ, RotY,trans;
double scale;
XMFLOAT3 loc;
DWORD indices[36];
ID3D11DeviceContext* d3dDevCon;
ID3D11Device*d3dDev;
ID3D11ShaderResourceView*CubeTexture;
XMMATRIX cubeWorld;
public:
Cube();
Cube(double,double,double, double, XMFLOAT3,ID3D11DeviceContext*,ID3D11Device*,std::string );
~Cube();
Vertex* getVertices();
void Rotate(double,double,double);
void Move(double,double,double);
void Draw();
void Update();
XMMATRIX getWorld();
DWORD* getIndices();
ID3D11ShaderResourceView*getCubeTexture();
};
Cube.cpp
#include "stdafx.h"
#include "Cube.h"
using namespace DirectX;
Cube::Cube()
{
RotX = XMMatrixRotationAxis(XMVectorSet(1.0, 0.0, 0.0, 0.0), 0);
RotY = XMMatrixRotationAxis(XMVectorSet(0.0, 1.0, 0.0, 0.0), 0);
RotZ = XMMatrixRotationAxis(XMVectorSet(0.0, 0.0, 1.0, 0.0), 0);
scale = 1;
loc = XMFLOAT3(0.0, 0.0, 0.0);
Vertex v[] =
{ //remember that structs do not have constructors unless defined!
// Front Face
{ { -1.0f, -1.0f, -1.0f },{ 0.0f, 1.0f },{ -1.0f, -1.0f, -1.0f } },
{ { -1.0f, 1.0f, -1.0f },{ 0.0f, 0.0f },{ -1.0f, 1.0f, -1.0f } },
{ { 1.0f, 1.0f, -1.0f },{ 1.0f, 0.0f } ,{ 1.0f, 1.0f, -1.0f } },
{ { 1.0f, -1.0f, -1.0f },{ 1.0f, 1.0f } ,{ 1.0f, -1.0f, -1.0f } },
// Back Face
{ { -1.0f, -1.0f, 1.0f },{ 1.0f, 1.0f } ,{ -1.0f, -1.0f, 1.0f } },
{ { 1.0f, -1.0f, 1.0f },{ 0.0f, 1.0f } ,{ 1.0f, -1.0f, 1.0f } },
{ { 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f } ,{ 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f, 1.0f },{ 1.0f, 0.0f },{ -1.0f, 1.0f, 1.0f } },
// Top Face
{ { -1.0f, 1.0f, -1.0f },{ 1.0f, 1.0f },{ -1.0f, 1.0f, -1.0f } },
{ { -1.0f, 1.0f, 1.0f },{ 0.0f, 1.0f },{ -1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f },{ 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f, -1.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f, -1.0f } },
// Bottom Face
{ { -1.0f, -1.0f, -1.0f },{ 1.0f, 1.0f },{ -1.0f, -1.0f, -1.0f } },
{ { 1.0f, -1.0f, -1.0f },{ 0.0f, 1.0f },{ 1.0f, -1.0f, -1.0f } },
{ { 1.0f, -1.0f, 1.0f },{ 0.0f, 0.0f },{ 1.0f, -1.0f, 1.0f } },
{ { -1.0f, -1.0f, 1.0f },{ 1.0f, 0.0f },{ -1.0f, -1.0f, 1.0f } },
// Left Face
{ { -1.0f, -1.0f, 1.0f },{ 0.0f, 1.0f },{ -1.0f, -1.0f, 1.0f } },
{ { -1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f },{ -1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f, -1.0f },{ 1.0f, 0.0f },{ -1.0f, 1.0f, -1.0f } },
{ { -1.0f, -1.0f, -1.0f },{ 1.0f, 1.0f },{ -1.0f, -1.0f, -1.0f } },
// Right Face
{ { 1.0f, -1.0f, -1.0f },{ 0.0f, 1.0f },{ 1.0f, -1.0f, -1.0f } },
{ { 1.0f, 1.0f, -1.0f },{ 0.0f, 0.0f },{ 1.0f, 1.0f, -1.0f } },
{ { 1.0f, 1.0f, 1.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f, 1.0f } },
{ { 1.0f, -1.0f, 1.0f },{ 1.0f, 1.0f },{ 1.0f, -1.0f, 1.0f } }
};
for (int i = 0; i < 24; i++) {
vertices[i] = v[i];
}
DWORD ind[] = {
// Front Face
0, 1, 2,
0, 2, 3,
// Back Face
4, 5, 6,
4, 6, 7,
// Top Face
8, 9, 10,
8, 10, 11,
// Bottom Face
12, 13, 14,
12, 14, 15,
// Left Face
16, 17, 18,
16, 18, 19,
// Right Face
20, 21, 22,
20, 22, 23
};
for (int s = 0; s < 36; s++) {
indices[s] = ind[s];
}
}
Cube::Cube(double rotx,double roty,double rotz, double scale, XMFLOAT3 loc,ID3D11DeviceContext*devcon, ID3D11Device*dev,std::string name ) {
RotX = XMMatrixRotationAxis(XMVectorSet(1.0, 0.0, 0.0, 0.0), rotx);
RotY = XMMatrixRotationAxis(XMVectorSet(0.0, 1.0, 0.0, 0.0), roty);
RotZ = XMMatrixRotationAxis(XMVectorSet(0.0, 0.0, 1.0, 0.0), rotz);
this->scale = scale;
this->loc = loc;
d3dDevCon = devcon;
d3dDev = dev;
CreateWICTextureFromFile(d3dDev, L"gray.jpg", NULL, &CubeTexture, 0);
Vertex v[] =
{ //remember that structs do not have constructors unless defined!
// Front Face
{ { -1.0f, -1.0f, -1.0f },{ 0.0f, 1.0f },{ -1.0f, -1.0f, -1.0f } },
{ { -1.0f, 1.0f, -1.0f },{ 0.0f, 0.0f },{ -1.0f, 1.0f, -1.0f } },
{ { 1.0f, 1.0f, -1.0f },{ 1.0f, 0.0f } ,{ 1.0f, 1.0f, -1.0f } },
{ { 1.0f, -1.0f, -1.0f },{ 1.0f, 1.0f } ,{ 1.0f, -1.0f, -1.0f } },
// Back Face
{ { -1.0f, -1.0f, 1.0f },{ 1.0f, 1.0f } ,{ -1.0f, -1.0f, 1.0f } },
{ { 1.0f, -1.0f, 1.0f },{ 0.0f, 1.0f } ,{ 1.0f, -1.0f, 1.0f } },
{ { 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f } ,{ 1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f, 1.0f },{ 1.0f, 0.0f },{ -1.0f, 1.0f, 1.0f } },
// Top Face
{ { -1.0f, 1.0f, -1.0f },{ 1.0f, 1.0f },{ -1.0f, 1.0f, -1.0f } },
{ { -1.0f, 1.0f, 1.0f },{ 0.0f, 1.0f },{ -1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f },{ 1.0f, 1.0f, 1.0f } },
{ { 1.0f, 1.0f, -1.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f, -1.0f } },
// Bottom Face
{ { -1.0f, -1.0f, -1.0f },{ 1.0f, 1.0f },{ -1.0f, -1.0f, -1.0f } },
{ { 1.0f, -1.0f, -1.0f },{ 0.0f, 1.0f },{ 1.0f, -1.0f, -1.0f } },
{ { 1.0f, -1.0f, 1.0f },{ 0.0f, 0.0f },{ 1.0f, -1.0f, 1.0f } },
{ { -1.0f, -1.0f, 1.0f },{ 1.0f, 0.0f },{ -1.0f, -1.0f, 1.0f } },
// Left Face
{ { -1.0f, -1.0f, 1.0f },{ 0.0f, 1.0f },{ -1.0f, -1.0f, 1.0f } },
{ { -1.0f, 1.0f, 1.0f },{ 0.0f, 0.0f },{ -1.0f, 1.0f, 1.0f } },
{ { -1.0f, 1.0f, -1.0f },{ 1.0f, 0.0f },{ -1.0f, 1.0f, -1.0f } },
{ { -1.0f, -1.0f, -1.0f },{ 1.0f, 1.0f },{ -1.0f, -1.0f, -1.0f } },
// Right Face
{ { 1.0f, -1.0f, -1.0f },{ 0.0f, 1.0f },{ 1.0f, -1.0f, -1.0f } },
{ { 1.0f, 1.0f, -1.0f },{ 0.0f, 0.0f },{ 1.0f, 1.0f, -1.0f } },
{ { 1.0f, 1.0f, 1.0f },{ 1.0f, 0.0f },{ 1.0f, 1.0f, 1.0f } },
{ { 1.0f, -1.0f, 1.0f },{ 1.0f, 1.0f },{ 1.0f, -1.0f, 1.0f } }
};
for (int i = 0; i < 24; i++) {
vertices[i] = v[i];
}
DWORD ind[] = {
// Front Face
0, 1, 2,
0, 2, 3,
// Back Face
4, 5, 6,
4, 6, 7,
// Top Face
8, 9, 10,
8, 10, 11,
// Bottom Face
12, 13, 14,
12, 14, 15,
// Left Face
16, 17, 18,
16, 18, 19,
// Right Face
20, 21, 22,
20, 22, 23
};
for (int s = 0; s < 36; s++) {
indices[s] = ind[s];
}
}
Cube::~Cube()
{
}
void Cube::Rotate(double rotx, double roty, double rotz) {
RotX = XMMatrixRotationAxis(XMVectorSet(1.0, 0.0, 0.0, 0.0), rotx);
RotY = XMMatrixRotationAxis(XMVectorSet(0.0, 1.0, 0.0, 0.0), roty);
RotZ = XMMatrixRotationAxis(XMVectorSet(0.0, 0.0, 1.0, 0.0), rotz);
}
void Cube::Move(double x,double y, double z) {
trans = XMMatrixTranslation(x, y, z);
}
void Cube::Update() {
cubeWorld = XMMatrixIdentity();
cubeWorld = trans*RotX*RotY*RotZ;
}
void Cube::Draw() {
return;
}
XMMATRIX Cube::getWorld() {
return cubeWorld;
}
Vertex* Cube::getVertices() {
return vertices;
}
DWORD* Cube::getIndices() {
return indices;
}
ID3D11ShaderResourceView* Cube::getCubeTexture() {
return CubeTexture;
}
headers
#pragma comment(lib,"D3D11.lib")
#pragma comment(lib,"d3dcompiler.lib")
#pragma comment(lib,"DXGI.lib")
#pragma comment(lib,"dwrite.lib")
#pragma comment(lib,"dinput8.lib")
#pragma comment(lib,"dxguid.lib")
#include "stdafx.h"
#include "Cube.h"
#include "D3DIndependentExperimentation.h"
#include <d3d11.h>
#include <d3dcompiler.h>
#include <DirectXMath.h>
#include <dinput.h>
#include <vector>
#include <iostream>
#include <d3dcompiler.h>
DrawScene()
void DrawScene(std::vector<Cube> cubelist) { // performs actual rendering
//clear backbuffer
float bgColor[4] = { 0.0, 0.0, 0.0, 0.0f };
d3d11DevCon->ClearRenderTargetView(renderTargetView, bgColor);
//clear depth stencil
d3d11DevCon->ClearDepthStencilView(depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0, 0.0);
//set default blend state(no blending)
d3d11DevCon->OMSetBlendState(0, 0, 0xffffff);
World = XMMatrixIdentity();
d3d11DevCon->PSSetConstantBuffers(0, 1, &cbPerFrameBuffer);
d3d11DevCon->VSSetShader(VS, 0, 0);
d3d11DevCon->PSSetShader(PS, 0, 0);
constBufferPerFrame.light = light;
d3d11DevCon->UpdateSubresource(cbPerFrameBuffer, 0, NULL, &constBufferPerFrame, 0, 0);
d3d11DevCon->OMSetRenderTargets(1, &renderTargetView, depthStencilView);
d3d11DevCon->IASetIndexBuffer(IndexBuffer, DXGI_FORMAT_R32_UINT, 0);
//set buffer data
UINT stride = sizeof(Vertex);//size of each Vertex
UINT offset = 0;// how far from the buffer beginning we start
d3d11DevCon->IASetVertexBuffers(0, 1, &VertexBuffer, &stride, &offset);
//TODO: everything
XMMATRIX cubeWorld = XMMatrixIdentity();
for (int i = 0; i < cubelist.size(); i++) {
Cube active = cubelist.at(i);
cubeWorld = active.getWorld();
WVP = cubeWorld*camView*camProjection;
cbPerObj.WVP = XMMatrixTranspose(WVP);
cbPerObj.World = XMMatrixTranspose(cubeWorld);
d3d11DevCon->UpdateSubresource(cbPerObjectBuffer, 0, NULL, &cbPerObj, 0, 0);
d3d11DevCon->VSSetConstantBuffers(0, 1, &cbPerObjectBuffer);
ID3D11ShaderResourceView* temp = active.getCubeTexture();
d3d11DevCon->PSSetShaderResources(0, 1, &temp);
d3d11DevCon->PSSetSamplers(0, 1, &CubesTexSamplerState);
d3d11DevCon->RSSetState(NOcullMode);
d3d11DevCon->DrawIndexed(36, 36 * i, 24 * i);
}
SwapChain->Present(0, 0);
}
InitScene()
bool InitScene(std::vector<Cube> cubelist) {
HRESULT hr;
//Compiling Shaders
hr = D3DCompileFromFile(L"effects.fx", 0, 0, "VS", "vs_5_0", 0, 0, &VS_Buffer, 0);
hr = D3DCompileFromFile(L"effects.fx", 0, 0, "PS", "ps_5_0", 0, 0, &PS_Buffer, 0);
//Creating Shaders
hr = d3d11Device->CreateVertexShader(VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), NULL, &VS);
hr = d3d11Device->CreatePixelShader(PS_Buffer->GetBufferPointer(), PS_Buffer->GetBufferSize(), NULL, &PS);
//Setting Shaders
d3d11DevCon->VSSetShader(VS, NULL, NULL);
d3d11DevCon->PSSetShader(PS, NULL, NULL);
//Creating and populating Vertex Buffers
//Buffer description
D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; //describes how buffer is used
vertexBufferDesc.ByteWidth = sizeof(Vertex)*cubelist.size() *24; // specifies the size of buffer; dependent on amount of vertices passed and size of vertices
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;//Specifies that this is a vertex buffer
vertexBufferDesc.CPUAccessFlags = 0;
vertexBufferDesc.MiscFlags = 0;
//Specifies what kind of data is placed in buffer
D3D11_SUBRESOURCE_DATA vertexBufferData;
ZeroMemory(&vertexBufferData, sizeof(vertexBufferData));
std::vector<Vertex> cubeVertices;
for (int i = 0; i < cubelist.size(); i++) {
Vertex *point = cubelist.at(i).getVertices();
cubeVertices.insert(cubeVertices.end(), point, point + 24);
}
vertexBufferData.pSysMem = &cubeVertices;
hr = d3d11Device->CreateBuffer(&vertexBufferDesc, &vertexBufferData, &VertexBuffer);
//Buffer description is mostly the same as vertex buffer
D3D11_BUFFER_DESC indexBufferDesc;
ZeroMemory(&indexBufferDesc, sizeof(indexBufferDesc));
indexBufferDesc.Usage = D3D11_USAGE_DEFAULT;
indexBufferDesc.ByteWidth = sizeof(DWORD) * 36*cubelist.size();
indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER;
vertexBufferDesc.CPUAccessFlags = 0;
indexBufferDesc.MiscFlags = 0;
std::vector<short> cubeIndices;
D3D11_SUBRESOURCE_DATA indexBufferData;
ZeroMemory(&indexBufferData, sizeof(indexBufferData));
for (int i = 0; i < cubelist.size(); i++) {
DWORD*point = cubelist.at(i).getIndices();
cubeIndices.insert(cubeIndices.end(), point, point + 36);
}
indexBufferData.pSysMem = &cubeIndices;
d3d11Device->CreateBuffer(&indexBufferDesc, &indexBufferData, &IndexBuffer);
//set input layout
hr = d3d11Device->CreateInputLayout(layout, NUMELEMENTS, VS_Buffer->GetBufferPointer(), VS_Buffer->GetBufferSize(), &vertLayout);
d3d11DevCon->IASetInputLayout(vertLayout);
d3d11DevCon->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
//Create and set viewport
D3D11_VIEWPORT viewport;
ZeroMemory(&viewport, sizeof(D3D11_VIEWPORT));
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = SCREENWIDTH;
viewport.Height = SCREENHEIGHT;
viewport.MinDepth = 0.0;
viewport.MaxDepth = 1.0;
d3d11DevCon->RSSetViewports(1, &viewport);
D3D11_BUFFER_DESC constantBufferDesc;
ZeroMemory(&constantBufferDesc, sizeof(D3D11_BUFFER_DESC));
constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
constantBufferDesc.ByteWidth = sizeof(cbPerObject);
constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDesc.CPUAccessFlags = 0;
constantBufferDesc.MiscFlags = 0;
hr = d3d11Device->CreateBuffer(&constantBufferDesc, NULL, &cbPerObjectBuffer);
ZeroMemory(&constantBufferDesc, sizeof(D3D11_BUFFER_DESC));
constantBufferDesc.Usage = D3D11_USAGE_DEFAULT;
constantBufferDesc.ByteWidth = sizeof(cbPerFrame);
constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDesc.CPUAccessFlags = 0;
constantBufferDesc.MiscFlags = 0;
hr = d3d11Device->CreateBuffer(&constantBufferDesc, NULL, &cbPerFrameBuffer);
camPosition = XMVectorSet(0.0f, 5.0f, -10.0f, 0.0f);
camTarget = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
camUp = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
camView = XMMatrixLookAtLH(camPosition, camTarget, camUp);
camProjection = XMMatrixPerspectiveFovLH(0.4f*3.14f, (float)SCREENWIDTH / SCREENHEIGHT, 1.0f, 1000.0f);
//Describe and create rasterizer state
D3D11_RASTERIZER_DESC wfdesc;
ZeroMemory(&wfdesc, sizeof(D3D11_RASTERIZER_DESC));
wfdesc.FillMode = D3D11_FILL_SOLID;
wfdesc.CullMode = D3D11_CULL_NONE;
hr = d3d11Device->CreateRasterizerState(&wfdesc, &FULL);
//hr = CreateWICTextureFromFile(d3d11Device, L"gray.jpg", NULL, &CubeTexture, 0);
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 = d3d11Device->CreateSamplerState(&sampDesc, &CubesTexSamplerState);
//describe and create blend state
/*D3D11_BLEND_DESC blendDesc;
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_INV_SRC_ALPHA;
rtbd.BlendOp = D3D11_BLEND_OP_ADD;
rtbd.SrcBlendAlpha = D3D11_BLEND_ONE;
rtbd.DestBlendAlpha = D3D11_BLEND_ZERO;
rtbd.BlendOpAlpha = D3D11_BLEND_OP_ADD;
rtbd.RenderTargetWriteMask = D3D10_COLOR_WRITE_ENABLE_ALL;
blendDesc.AlphaToCoverageEnable = false;
blendDesc.RenderTarget[0] = rtbd;
//d3d11Device->CreateBlendState(&blendDesc, &Transparency);*/
//define rasterizer states for blending
D3D11_RASTERIZER_DESC cmdesc;
ZeroMemory(&cmdesc, sizeof(D3D11_RASTERIZER_DESC));
cmdesc.CullMode = D3D11_CULL_BACK;
cmdesc.FillMode = D3D11_FILL_SOLID;
cmdesc.FrontCounterClockwise = true;
hr = d3d11Device->CreateRasterizerState(&cmdesc, &CCWcullMode);
cmdesc.FrontCounterClockwise = false;
hr = d3d11Device->CreateRasterizerState(&cmdesc, &CWcullMode);
cmdesc.CullMode = D3D11_CULL_NONE;
hr = d3d11Device->CreateRasterizerState(&cmdesc, &NOcullMode);
//light setting
//light.dir = XMFLOAT3(1.0f, 0.0f, 0.0f);
light.ambient = XMFLOAT4(0.3f, 0.3f, 0.3f, 1.0f);
light.diffuse = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
light.pos = XMFLOAT3(2.0f, 4.0f, 0.0f);
light.range = 250.0f;
light.att = XMFLOAT3(0.0f, 0.2f, 0.0f);
return true;
}
effects.fx
cbuffer cbPerObject {
float4x4 WVP;
float4x4 World;
};
//note: keep structure of structs in fx files same as those in c++ code.
struct Light {
float3 dir;
float3 att;
float3 pos;
float range;
float4 ambient;
float4 diffuse;
};
cbuffer cbPerFrame {
Light light;
};
struct VS_OUTPUT
{
float4 Pos : SV_POSITION;
float2 texCoord : TEXCOORD;
float3 normal: NORMAL;
float4 worldPos: POSITION;
};
Texture2D ObjTexture;
SamplerState ObjSamplerState;
VS_OUTPUT VS(float4 inPos: POSITION, float2 texCoord : TEXCOORD, float3 normal : NORMAL) {
VS_OUTPUT output;
output.texCoord = texCoord;
output.Pos = mul(inPos, WVP);
output.worldPos = mul(inPos, World);
output.normal = mul(normal, World);
return output;
}
float4 PS(VS_OUTPUT input) : SV_TARGET{
input.normal = normalize(input.normal);
float4 diffuse = ObjTexture.Sample(ObjSamplerState, input.texCoord);
float3 finalColor = float3(0.0, 0.0, 0.0);
float3 lightToPixelVec = light.pos - input.worldPos;
float d = length(lightToPixelVec);
float3 finalAmbient = diffuse*light.ambient;
if (d > light.range) {
return float4(finalAmbient, diffuse.a);
}
lightToPixelVec /= d;
float Intensity = dot(lightToPixelVec, input.normal)*20;
if (Intensity > 0.0f) {
finalColor += Intensity*diffuse*light.diffuse;
finalColor /= light.att[0] + (light.att[1] * d) + (light.att[2] * (d*d));
}
finalColor = saturate(finalColor + finalAmbient);
return float4(1.0, 1.0, 1.0, 1.0);//float4(finalColor,diffuse.a);
}
float4 D2D_PS(VS_OUTPUT input) : SV_TARGET
{ input.normal = normalize(input.normal);
float4 diffuse = ObjTexture.Sample(ObjSamplerState, input.texCoord);
return diffuse;
}
If any more information is needed, I'm ready to oblige.
Reviewing your code and comparing it to the code I've written in the past for DirectX 11 rendering, you are missing at least one thing - a Depth/Stencil State. I'm not certain what the GPU will do if you decide to use a depth/stencil buffer without it, but it looks to be the only difference between the calls your system makes (which doesn't work) and the calls my system makes (which does).
You can create a depth/stencil state with ID3D11Device::CreateDepthStencilState, and set it to the pipeline with ID3D11DeviceContext::OMSetDepthStencilState. This function works the same as ID3D11DeviceContext::OMSetBlendState, in that passing nullptr, NULL or 0 as the state object will bind a default state.
I have been trying to learn the basics of DirectX 11 programming using the MSDN tutorial05 sample code and I have run into an issue I cannot find a solution for on the internet (that I could see anyway). Basically I am trying to draw and render a player cube object, complete with user input, and pyramid-like objects that the player must collect.
My issue is that when I am rendering the scene, only the cube vertex (and indices) data is being read so all objects are cubes when they shouldn't be.
This is the function where the vertex data is made:
PyramidVertex Pyramid[] =
{
// Square base of the pyramid
{ XMFLOAT3( -0.5f, -0.5f, 0.5f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3( 0.5f, -0.5f, 0.5f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-0.5f, -0.5f, -0.5f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(0.5f, -0.5f, -0.5f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
// The tip of the pyramid
{ XMFLOAT3(0.0f, 0.5f, 0.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
};
D3D11_BUFFER_DESC bdP;
ZeroMemory(&bdP, sizeof(bdP));
bdP.Usage = D3D11_USAGE_DEFAULT;
bdP.ByteWidth = sizeof(PyramidVertex) * 5;
bdP.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bdP.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitPData;
ZeroMemory(&InitPData, sizeof(InitPData));
InitPData.pSysMem = Pyramid;
hr = g_pd3dDevice->CreateBuffer(&bdP, &InitPData, &g_pVertexBufferP);
if (FAILED(hr))
return hr;
// Set vertex buffer
UINT pStride = sizeof(PyramidVertex);
UINT pOffset = 1;
g_pImmediateContext->IASetVertexBuffers(0, 1, &g_pVertexBufferP, &pStride, &pOffset);
// create the index buffer
DWORD pIndex[] =
{
0, 2, 1,
1, 2, 3,
0, 1, 4,
1, 3, 4,
3, 2, 4,
2, 0, 4,
};
// create the index buffer
bdP.Usage = D3D11_USAGE_DYNAMIC;
bdP.ByteWidth = sizeof(DWORD) * 18;
bdP.BindFlags = D3D11_BIND_INDEX_BUFFER;
bdP.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
bdP.MiscFlags = 0;
InitPData.pSysMem = pIndex;
hr = g_pd3dDevice->CreateBuffer(&bdP, &InitPData, &g_pIndexBufferP);
if (FAILED(hr))
return hr;
// Set index buffer
g_pImmediateContext->IASetIndexBuffer(g_pIndexBufferP, DXGI_FORMAT_R16_UINT, 0);
// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Create vertex buffer
SimpleVertex vertices[] =
{
{ XMFLOAT3( -1.0f, 1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, 1.0f, 1.0f ), XMFLOAT4( .0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, -1.0f, -1.0f ), XMFLOAT4 (1.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, -1.0f, -1.0f ), XMFLOAT4( 1.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( 1.0f, -1.0f, 1.0f ), XMFLOAT4( 0.0f, 1.0f, 1.0f, 1.0f ) },
{ XMFLOAT3( -1.0f, -1.0f, 1.0f ), XMFLOAT4( .0f, 1.0f, 1.0f, 1.0f ) },
};
D3D11_BUFFER_DESC bd;
ZeroMemory( &bd, sizeof(bd) );
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( SimpleVertex ) * 8;
bd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
bd.CPUAccessFlags = 0;
D3D11_SUBRESOURCE_DATA InitData;
ZeroMemory( &InitData, sizeof(InitData) );
InitData.pSysMem = vertices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pVertexBuffer );
if( FAILED( hr ) )
return hr;
// Set vertex buffer
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride, &offset );
// Create index buffer
WORD indices[] =
{
3,1,0,
2,1,3,
0,5,4,
1,5,0,
3,4,7,
0,4,3,
1,6,5,
2,6,1,
2,7,6,
3,7,2,
6,4,5,
7,4,6,
};
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof( WORD ) * 36; // 36 vertices needed for 12 triangles in a triangle list
bd.BindFlags = D3D11_BIND_INDEX_BUFFER;
bd.CPUAccessFlags = 0;
InitData.pSysMem = indices;
hr = g_pd3dDevice->CreateBuffer( &bd, &InitData, &g_pIndexBuffer );
if( FAILED( hr ) )
return hr;
// Set index buffer
g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT, 0 );
// Set primitive topology
g_pImmediateContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
// Create the constant buffer
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(ConstantBuffer);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bd.CPUAccessFlags = 0;
hr = g_pd3dDevice->CreateBuffer( &bd, nullptr, &g_pConstantBuffer );
if( FAILED( hr ) )
return hr;
// Create the constant buffer
bdP.Usage = D3D11_USAGE_DEFAULT;
bdP.ByteWidth = sizeof(ConstantBuffer);
bdP.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
bdP.CPUAccessFlags = 0;
hr = g_pd3dDevice->CreateBuffer(&bdP, nullptr, &g_pConstantBufferP);
if (FAILED(hr))
return hr;
// Initialize the world matrix
g_Player = XMMatrixIdentity();
for (int i = 0; i < 10; ++i)
{
g_Shapes[i] = XMMatrixIdentity();
}
// Initialize the view matrix
XMVECTOR Eye = XMVectorSet( 0.0f, 1.0f, -5.0f, 0.0f );
XMVECTOR At = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
XMVECTOR Up = XMVectorSet( 0.0f, 4.0f, 0.0f, 0.0f );
g_View = XMMatrixLookAtLH( Eye, At, Up );
// Initialize the projection matrix
g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV2, width / (FLOAT)height, 0.01f, 100.0f );
I believe that the issue is somewhere here and my theory is that the pyramid g_pImmediateContext is being overwritten when it comes to drawing the cubes. If this is the case then I have no clue on how to solve, or research, this problem. I has taken me an hour to figure out to put my code on this page properly but got weird results so I will leave a link to my Google Drive containing this code if someone wants to have an in-depth look (for whatever reason) at the code.
This is the render function:
//
// Clear the back buffer
//
g_pImmediateContext->ClearRenderTargetView(g_pRenderTargetView, Colors::Black);
//
// Clear the depth buffer to 1.0 (max depth)
//
g_pImmediateContext->ClearDepthStencilView(g_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);
XMMATRIX mRotate = XMMatrixRotationZ(DXGame->playerUser->getRotation());
XMMATRIX mTranslate = XMMatrixTranslation(DXGame->playerUser->getXpos(), DXGame->playerUser->getYpos(), DXGame->playerUser->getZpos());
XMMATRIX mScale = XMMatrixScaling(0.7f, 0.7f, 0.7f);
g_Player = mScale * mRotate * mTranslate;
ConstantBuffer cb1;
cb1.mWorld = XMMatrixTranspose(g_Player);
cb1.mView = XMMatrixTranspose(g_View);
cb1.mProjection = XMMatrixTranspose(g_Projection);
g_pImmediateContext->UpdateSubresource(g_pConstantBuffer, 0, nullptr, &cb1, 0, 0);
g_pImmediateContext->VSSetShader(g_pVertexShader, nullptr, 0);
g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pConstantBuffer);
g_pImmediateContext->PSSetShader(g_pPixelShader, nullptr, 0);
g_pImmediateContext->DrawIndexed(36, 0, 0);
for (int i = 0; i < 10; i++)
{
XMMATRIX sRotate = XMMatrixRotationY((DXGame->pickUps[i].rotation += 0.001f));
XMMATRIX sTranslate = XMMatrixTranslation(DXGame->pickUps[i].xPos, DXGame->pickUps[i].yPos, DXGame->pickUps[i].zPos);
XMMATRIX sScale = XMMatrixScaling(0.2f, 0.2f, 0.2f);
g_Shapes[i] = sScale * sRotate * sTranslate;
ConstantBuffer constB;
constB.mWorld = XMMatrixTranspose(g_Shapes[i]);
constB.mView = XMMatrixTranspose(g_View);
constB.mProjection = XMMatrixTranspose(g_Projection);
g_pImmediateContext->UpdateSubresource(g_pConstantBufferP, 0, nullptr, &constB, 0, 0);
g_pImmediateContext->VSSetShader(g_pVertexShader, nullptr, 0);
g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pConstantBufferP);
g_pImmediateContext->PSSetShader(g_pPixelShader, nullptr, 0);
g_pImmediateContext->DrawIndexed(18, 0, 0);
}
g_pSwapChain->Present(0, 0);
Something I am also looking at is constant buffers and HLSL to see if that is an issue as well.
Please could someone at least point me in the right direction as this issue has bugged me for almost 2 months now (I left it this long because I wanted to figure it out for myself but now I am desperate for a solution).
Thank you for taking the time to read this post, sorry its so long but I needed to get as much info out there as possible in the hope that it is easier to read.
your calls to IASetIndexBuffer and IASetVertexBuffers are in your creation routines, They need to be in your render function (before to call the relevant Draw function, as those are attaching those buffers to the runtime before drawing)
They do not need to be in creation part at all (as in DirectX11 context eg building commands and device eg : creating resource are decoupled).
You should have, in the render loop:
// Set vertex buffer and index buffer for your cube
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride,
&offset );
// Set index buffer
g_pImmediateContext->IASetIndexBuffer( g_pIndexBuffer, DXGI_FORMAT_R16_UINT,
0 );
g_pImmediateContext->VSSetShader(g_pVertexShader, nullptr, 0);
g_pImmediateContext->VSSetConstantBuffers(0, 1, &g_pConstantBuffer);
g_pImmediateContext->PSSetShader(g_pPixelShader, nullptr, 0);
g_pImmediateContext->DrawIndexed(36, 0, 0);
and just before to draw all pyramids:
// Set vertex buffer and index buffer for pyramids as you will draw it 10 times, you can do it once just before the loop as geometry will not change
UINT stride = sizeof( SimpleVertex );
UINT offset = 0;
g_pImmediateContext->IASetVertexBuffers( 0, 1, &g_pVertexBuffer, &stride,
&offset );
// Set index buffer
g_pImmediateContext->IASetIndexBuffer(g_pIndexBufferP, DXGI_FORMAT_R16_UINT, 0);
for (int i = 0; i < 10; i++)
{
//Same draw code as before
}
I have the following code that renders a square beautifully:
static const VertexPositionColor cubeVertices[] =
{
{ XMFLOAT3( 1.0f, -1.0f, 0.0f ), XMFLOAT3( 1.0f, 0.0f, 0.0f ) },
{ XMFLOAT3( -1.0f, -1.0f, 0.0f ), XMFLOAT3( 1.0f, 0.0f, 0.0f ) },
{ XMFLOAT3( 1.0f, 1.0f, 0.0f ), XMFLOAT3( 1.0f, 0.0f, 0.0f ) },
{ XMFLOAT3( -1.0f, 1.0f, 0.0f ), XMFLOAT3( 1.0f, 0.0f, 0.0f ) },
};
D3D11_SUBRESOURCE_DATA vertexBufferData = { 0 };
vertexBufferData.pSysMem = &cubeVertices;
vertexBufferData.SysMemPitch = 0;
vertexBufferData.SysMemSlicePitch = 0;
CD3D11_BUFFER_DESC vertexBufferDesc( sizeof( cubeVertices ), D3D11_BIND_VERTEX_BUFFER );
DX::ThrowIfFailed(
m_deviceResources->GetD3DDevice()->CreateBuffer(
&vertexBufferDesc,
&vertexBufferData,
&m_vertexBuffer[ a ]
)
);
Now, take this code... which is exact replica with exact same sizeof (96)... but this one uses a vector... why does it render nothing?
FormatCollada* colladaObj = new FormatCollada();
static const vector<VertexPositionColor> cubeVertices = colladaObj->Format( *geometryData->Collada->LibraryGeometries->Geometry[ a ] );
D3D11_SUBRESOURCE_DATA vertexBufferData = { 0 };
vertexBufferData.pSysMem = &cubeVertices;
vertexBufferData.SysMemPitch = 0;
vertexBufferData.SysMemSlicePitch = 0;
CD3D11_BUFFER_DESC vertexBufferDesc( sizeof( VertexPositionColor ) * cubeVertices.size(), D3D11_BIND_VERTEX_BUFFER );
DX::ThrowIfFailed(
m_deviceResources->GetD3DDevice()->CreateBuffer(
&vertexBufferDesc,
&vertexBufferData,
&m_vertexBuffer[ a ]
)
);
&cubeVertices does not give you the address of the first element of the vector, it gives you the address of the vector object itself. You probably wanted cubeVertices.data().
I am creating a game that will have 2d pictures inside a 3d world.
I originally started off by not caring about my images been stretched to a square while I learnt more about how game mechanics work... but it's now time to get my textures to display in the correct ratio and... size.
Just a side note, I have played with orthographic left hand projections but I noticed that you cannot do 3d in that... (I guess that makes sense... but I could be wrong, I tried it and when I rotated my image, it went all stretchy and weirdosss).
the nature of my game is as follows:
In the image it says -1.0 to 1.0... i'm not fussed if the coordinates are:
topleft = 0,0,0
bottom right = 1920, 1200, 0
But if that's the solution, then whatever... (p.s the game is not currently set up so that -1.0 and 1.0 is left and right of screen. infact i'm not sure how i'm going to make the screen edges the boundaries (but that's a question for another day)
Question:
The issue I am having is that my image for my player (2d) is 128 x 64 pixels. After world matrix multiplication (I think that's what it is) the vertices I put in scale my texture hugely... which makes sense but it looks butt ugly and I don't want to just whack a massive scaling matrix into the mix because it'll be difficult to work out how to make the texture 1:1 to my screen pixels (although maybe you will tell me it's actually how you do it but you need to do a clever formula to work out what the scaling should be).
But basically, I want the vertices to hold a 1:1 pixel size of my image, unstretched...
So I assume I need to convert my world coords to screen coords before outputting my textures and vertices??? I'm not sure how it works...
Anyways, here are my vertices.. you may notice what I've done:
struct VERTEX
{
float X, Y, Z;
//float R, G, B, A;
float NX, NY, NZ;
float U, V; // texture coordinates
};
const unsigned short SquareVertices::indices[ 6 ] = {
0, 1, 2, // side 1
2, 1, 3
};
const VERTEX SquareVertices::vertices[ 4 ] = {
//{ -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 1
//{ 1.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
//{ -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
//{ 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }
{ -64.0f, -32.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 1
{ 64.0f, -32.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
{ -64.0f, 32.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
{ 64.0f, 64.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }
};
(128 pixels / 2 = 64 ), ( 64 / 2 = 32 ) because the centre is 0.0... but what do I need to do to projections, world transdoobifications and what nots to get the worlds to screens?
My current setups look like this:
// called 1st
void Game::SetUpViewTransformations( )
{
XMVECTOR vecCamPosition = XMVectorSet( 0.0f, 0.0f, -20.0f, 0 );
XMVECTOR vecCamLookAt = XMVectorSet( 0, 0, 0, 0 );
XMVECTOR vecCamUp = XMVectorSet( 0, 1, 0, 0 );
matView = XMMatrixLookAtLH( vecCamPosition, vecCamLookAt, vecCamUp );
}
// called 2nd
void Game::SetUpMatProjection( )
{
matProjection = XMMatrixPerspectiveFovLH(
XMConvertToRadians( 45 ), // the field of view
windowWidth / windowHeight, // aspect ratio
1, // the near view-plane
100 ); // the far view-plan
}
and here is a sneaky look at my update and render methods:
// called 3rd
void Game::Update( )
{
world->Update();
worldRotation = XMMatrixRotationY( world->rotation );
player->Update( );
XMMATRIX matTranslate = XMMatrixTranslation( player->x, player->y, 0.0f );
//XMMATRIX matTranslate = XMMatrixTranslation( 0.0f, 0.0f, 1.0f );
matWorld[ 0 ] = matTranslate;
}
// called 4th
void Game::Render( )
{
// set our new render target object as the active render target
d3dDeviceContext->OMSetRenderTargets( 1, rendertarget.GetAddressOf( ), zbuffer.Get( ) );
// clear the back buffer to a deep blue
float color[ 4 ] = { 0.0f, 0.2f, 0.4f, 1.0f };
d3dDeviceContext->ClearRenderTargetView( rendertarget.Get( ), color );
d3dDeviceContext->ClearDepthStencilView( zbuffer.Get( ), D3D11_CLEAR_DEPTH, 1.0f, 0 ); // clear the depth buffer
CBUFFER cBuffer;
cBuffer.DiffuseVector = XMVectorSet( 0.0f, 0.0f, 1.0f, 0.0f );
cBuffer.DiffuseColor = XMVectorSet( 0.5f, 0.5f, 0.5f, 1.0f );
cBuffer.AmbientColor = XMVectorSet( 0.2f, 0.2f, 0.2f, 1.0f );
//cBuffer.Final = worldRotation * matWorld[ 0 ] * matView * matProjection;
cBuffer.Final = worldRotation * matWorld[ 0 ] * matView * matProjection;
cBuffer.Rotation = XMMatrixRotationY( world->rotation );
// calculate the view transformation
SetUpViewTransformations();
SetUpMatProjection( );
//matFinal[ 0 ] = matWorld[0] * matView * matProjection;
UINT stride = sizeof( VERTEX );
UINT offset = 0;
d3dDeviceContext->PSSetShaderResources( 0, 1, player->texture.GetAddressOf( ) ); // Set up texture
d3dDeviceContext->IASetVertexBuffers( 0, 1, player->vertexbuffer.GetAddressOf( ), &stride, &offset ); // Set up vertex buffer
d3dDeviceContext->IASetPrimitiveTopology( D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST ); // How the vertices be drawn
d3dDeviceContext->IASetIndexBuffer( player->indexbuffer.Get( ), DXGI_FORMAT_R16_UINT, 0 ); // Set up index buffer
d3dDeviceContext->UpdateSubresource( constantbuffer.Get( ), 0, 0, &cBuffer, 0, 0 ); // set the new values for the constant buffer
d3dDeviceContext->OMSetBlendState( blendstate.Get( ), 0, 0xffffffff ); // DONT FORGET IF YOU DISABLE THIS AND YOU WANT COLOUR, * BY Color.a!!!
d3dDeviceContext->DrawIndexed( ARRAYSIZE( player->indices ), 0, 0 ); // draw
swapchain->Present( 1, 0 );
}
Just to clarify, if I make my vertices use 2 and 1 respective of the fact my image is 128 x 64.. I get a normal looking size image.. and yet at 0,0,0 it's not at 1:1 size... wadduuuppp buddyyyy
{ -2.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f }, // side 1
{ 2.0f, -1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f },
{ -2.0f, 1.0f, 0.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f },
{ 2.0f, 2.0f, 0.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f }
Desired outcome 2 teh max:
Cool picture isn't it :D ?
Comment help:
I'm not familliar with direct-x but as far as I can see the thing with your image that is screen coordinates are [-1...+1] on x and y. So total length on both axis equals 2 and your image is scaled times 2. Try consider this scale in camera matrix.