Easiest way to draw a scalar and vector field with C++? - c++

What is the easiest, while being decently fast, way to draw a grid (say, 100 x 100) of scalar values as colors and vectors as lines from arrays of values in C++? Pure OpenGL? Something like this:
I am planning on using either basic OpenGL or SDL. This Windows program will be a real-time demonstration (not static image) and should be able to handle user (cursor) input. I do not think OpenGL alone can handle input.

In OpenGL you can create the array of floats wich can be represents as bitmap image
float computations[10000][3] = {
{ 1, 0.5, 0.5 }, // ..... 100 elements in row
//..............................
// 100 rows
};
Than call OpenGL function
glDrawPixels(100 /*width*/, 100 /*height*/, GL_RGB, GL_FLOAT, computations);
or using glTexImage()
glTexImage(GL_TEXTURE_2D, 0, GL_RGB, 100 /*width*/, 100 /*height*/, GL_RGB, GL_FLOAT, computations);
But it is wery important to represent the the float data in the range of [0; 1].
for example this code draws 8x8 image
float pixels[64][3]= {
{ 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
{ 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
{ 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
{ 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
{ 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
{ 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
{ 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f },
{ 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }, { 0.0f, .0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 0.0f, 1.0f } };
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2i(0, 0);
glDrawPixels(8, 8, GL_RGB, GL_FLOAT, pixels);
glFlush();
}
the result will be
The result picture can be simply scaled using glPixelZoom or magnificated as texture filtration result.
here is example of texture loading.
glGenTextures(1, &g_nTexture);
glBindTexture(GL_TEXTURE_2D, g_nTexture);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 8, 8, 0, GL_RGB, GL_FLOAT, pixels);
glEnable(GL_TEXTURE_2D);
the result of filtering.
here you can see smooth color transition.
There are others ways to do that things with shaders.
Vectors may be drawn separately as single line with the cone on its end than positioned by affine transformations.
This all things will give acceptable level of performance for real time application and wide capabilities of human-machine interaction because OS will handle any OpenGL window as native with all OS events support.

SDL_FillRect and SDL_RenderDrawLine are fast enough for this purpose.

Related

D3D9 CubeMap texture

I am making a texture cubemap, and the image is output on all 6 sides. How to print a split image on 6 sides? I want to make it without using shaders and I want to know a site where I can study directX Are there any sites you can recommend?
this is my code.
ㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁㅁ
struct CUBEVERTEX
{
float x, y, z;
float tu, tv;
};
void SkyBox::onInit(float scale)
{
CUBEVERTEX vertice[] =
{
{-1.0f, 1.0f, -1.0f, 0.0f, 0.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, -1.0f, -1.0f, 0.0f, 1.0f },
{-1.0f, 1.0f, -1.0f, 0.0f, 0.0f },
{ 1.0f, 1.0f, 1.0f, 0.0f, 0.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, -1.0f, 1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
{-1.0f, -1.0f, -1.0f, 0.0f, 0.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, -1.0f, 1.0f, 0.0f, 1.0f },
{-1.0f, -1.0f, -1.0f, 0.0f, 0.0f },
{-1.0f, 1.0f, 1.0f, 0.0f, 0.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, 1.0f, -1.0f, 0.0f, 1.0f },
{-1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
{-1.0f, 1.0f, 1.0f, 0.0f, 0.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, -1.0f, 1.0f, 0.0f, 1.0f },
{-1.0f, 1.0f, 1.0f, 0.0f, 0.0f },
{ 1.0f, 1.0f, -1.0f, 0.0f, 0.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, -1.0f, -1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, -1.0f, 0.0f, 0.0f }
};
m_pd3dDevice->CreateVertexBuffer(sizeof(vertice), 0, D3DFVF_CUBEVERTEX, D3DPOOL_DEFAULT,
&m_pVB, 0);
void* pVertice;
m_pVB->Lock(0, sizeof(vertice), &pVertice, 0);
memcpy(pVertice, vertice, sizeof(vertice));
m_pVB->Unlock();
}
void SkyBox::render()
{
D3DXMATRIX matWorld;
D3DXMatrixIdentity(&matWorld);
m_pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
m_pd3dDevice->SetTexture(0, texture);
m_pd3dDevice->SetStreamSource(0, m_pVB, 0, sizeof(CUBEVERTEX));
m_pd3dDevice->SetFVF(D3DFVF_CUBEVERTEX);
m_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 12);
}
Rendering a cubemap directly as a skybox in Direct3D 9 is not achievable, especially with a "no shaders" requirement. In Direct3D 9, you need to create the resource as a cubemap to use in environment scenarios, and then create SIX individual 2D textures to render it as a skybox--which means having two copies of each cubemap face in memory.
In Direct3D 10 or later, you can create a resource and then create two shader resource views: One as a cubemap and another resource as a 2D texture array. This results in one copy of each cubemap face in memory. You can then using shaders render the individual faces of the 2D texture array on a skybox.
Here's an example implementation using DirectX 12 Skybox that leverages the DirectX Tool Kit for DX12. Same technique will work for Direct3D 11 as long as you require Direct3D Hardware Feature Level 10.0 or better.
Unless you are specifically using Windows XP, there's no reason you should learn Direct3D 9 at this point. Direct3D 11 is the 'mainstream' graphics API you should look at. See Microsoft Docs and DirectX Tool Kit.

Directx11 Project will not display graphical output

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.

Change color of point on mouse click and back to original on release

I am working on an OpenGL code using shaders where one of the requirements is to change the color of a point to white (or anything) on a mouse click and change it back to its original color once released. Is there any function that can retrieve the vertices of the point being clicked and change its color? There are eight points that form a circle whose vertices are
(0,√2), (1,1), (√2, 0), (1,-1), (0,-√2), (-1,-1), (-√2,0), (-1,1) (basically a circle with a radius of √2 units)
I have initially defined the points as given below
Vertex Vertices[] =
{
{ { 0.0f, 1.414214f, 0.0f, 1.0f },{ 0.5f, 0.0f, 0.0f, 1.0f } }, // 0
{ { -1.0f, 1.0f, 0.0f, 1.0f },{ 0.0f, 1.0f, 0.0f, 1.0f } }, // 1
{ { -1.414214f, 0.0f, 0.0f, 1.0f },{ 0.0f, 0.5f, 0.0f, 1.0f } }, // 2
{ { -1.0f, -1.0f, 0.0f, 1.0f },{ 0.0f, 0.0f, 1.0f, 1.0f } }, // 3
{ { 0.0f, -1.414214f, 0.0f, 1.0f },{ 0.5f, 0.5f, 1.0f, 1.0f } }, // 4
{ { 1.0f, -1.0f, 0.0f, 1.0f },{ 1.0f, 1.0f, 1.0f, 1.0f } }, // 5
{ { 1.414214f, 0.0f, 0.0f, 1.0f },{ 0.5f, 1.0f, 1.0f, 1.0f } }, // 6
{ { 1.0f, 1.0f, 0.0f, 1.0f },{ 1.0f, 0.0f, 0.0f, 1.0f } }, // 7
};

Rendering multiple triangles with a single vertex buffer

Previously I was using a separate vertex and index buffer for each mesh, but I'd like to try using a single large vertex buffer to reduce DrawIndexed() calls. Let's say I have the following arrays:
SimpleVertex vertices[] =
{
{ XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.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(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.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, 0.0f, 0.0f, 1.0f) },
};
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,
};
This works great for a single indexed cube. But, what if I wish to draw two cubes? How do I set up the index buffer to handle that? I'm confused as to whether the indices are local to each cube and thus should just repeat every 36 indices, or if they should be incremented as such:
SimpleVertex vertices[] =
{
//first cube
{ XMFLOAT3(-1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(1.0f, 1.0f, -1.0f), XMFLOAT4(0.0f, 1.0f, 0.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(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(1.0f, -1.0f, -1.0f), XMFLOAT4(1.0f, 1.0f, 0.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, 0.0f, 0.0f, 1.0f) },
//second cube
{ XMFLOAT3(-2.0f, 2.0f, -2.0f), XMFLOAT4(0.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(2.0f, 2.0f, -2.0f), XMFLOAT4(0.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(2.0f, 2.0f, 2.0f), XMFLOAT4(0.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-2.0f, 2.0f, 2.0f), XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f) },
{ XMFLOAT3(-2.0f, -2.0f, -2.0f), XMFLOAT4(1.0f, 0.0f, 1.0f, 1.0f) },
{ XMFLOAT3(2.0f, -2.0f, -2.0f), XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f) },
{ XMFLOAT3(2.0f, -2.0f, 2.0f), XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f) },
{ XMFLOAT3(-2.0f, -2.0f, 2.0f), XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f) },
};
WORD indices[] =
{
//First cube
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,
//second cube
11,9,8,
10,9,11,
8,13,12,
9,13,8,
11,12,15,
8,12,11,
9,14,13,
10,14,9,
10,15,14,
11,15,10,
14,12,13,
15,12,14,
};
So basically, I'm trying to understand how to draw one large index buffer with multiple objects. Am I thinking about this correctly or should I have the buffer re-use the same index buffer over and over?
I'm aware of using Instancing, but there are times where the geometry changes, so I need to avoid it in this case.
Decided to just start writing code to attack the theory blind. Turns out you do indeed need to increment the index array to treat a large vertex array as one mesh. I wrote a function to illustrate this for those interested:
UINT* VertexCompiler::BuildIndexArray()
{
UINT* indices;
int indexCount = 0;
for (int i = 0; i < (int)mVertexObjects.size(); i++)
indexCount += mVertexObjects[i].NumIndices;
mIndexCount = indexCount;
indices = new UINT[indexCount];
int numObjects = (int)mVertexObjects.size();
int index = 0;
for (int i = 0; i < numObjects; i++)
{
for (int j = 0; j < (int)mVertexObjects[i].NumIndices; j++)
{
indices[index] = mVertexObjects[i].Indices[j] + (mVertexObjects[i].NumVertices * i);
index++;
}
}
return indices;
}
Be sure to delete the pointer to indices after you're finished with it. Usually it's poor design to allocate memory inside of a function and delete it outside, but this is just for demonstration purposes. Typically you should allocate the index array outside and pass it as a pointer to the function.
One important thing to note is the use of UINT. Most textbooks and articles on the subject allocate smaller index buffers with WORD. Your incremented index array will overflow at index value 65535 using WORD memory allocations. So, if you're rendering a large number of vertices where the index would exceed 16 bits, use UINT and don't forget to switch to DXGI_FORMAT_R32_UINT instead of DXGI_FORMAT_R16_UINT.
E.g.
IASetIndexBuffer(indicesBuffer, DXGI_FORMAT_R32_UINT, 0);

Efficient means of drawing a lined border for a solid shape

I currently have the following vertex data (for a pyramid) laid out like so:
float4 vertexData[ 18 ] =
{
// front
{ 1.0f, 0.0f, 1.0f, 1.0f }, // front right
{ 0.0f, 1.0f, 0.0f, 1.0f }, // top
{ -1.0, 0.0f, 1.0f, 1.0f }, // front left
// right
{ 1.0f, 0.0f, 1.0f, 1.0f }, // right front
{ 0.0f, 1.0f, 0.0f, 1.0f }, // top
{ 1.0f, 0.0f, -1.0f, 1.0f }, // right back
// back
{ 1.0f, 0.0f, -1.0f, 1.0f }, // back right
{ 0.0f, 1.0f, 0.0f, 1.0f }, // top
{ -1.0, 0.0f, -1.0f, 1.0f }, // back left
// left
{ -1.0f, 0.0f, -1.0f, 1.0f }, // left back
{ 0.0f, 1.0f, 0.0f, 1.0f }, // top
{ -1.0f, 0.0f, 1.0f, 1.0f }, // left front
// bottom back major
{ -1.0f, 0.0f, 1.0f, 1.0f }, // bottom left front
{ -1.0f, 0.0f, -1.0f, 1.0f }, // bottom left back
{ 1.0f, 0.0f, -1.0f, 1.0f }, // bottom right back
// bottom front major
{ 1.0f, 0.0f, -1.0f, 1.0f }, // bottom right back
{ 1.0f, 0.0f, 1.0f, 1.0f }, // bottom right front
{ -1.0f, 0.0f, 1.0f, 1.0f }, // bottom left front
};
I'd like to basically take my pyramid, and use shaders (if possible) to compute the edges between two vertices and then send what would be a "line" of sorts to the fragment shader.
I know I could probably just use "GL_LINES", and set a new uniform color, but I would think this wouldn't be very efficient. Maybe I'm wrong, though?
Either way, the main reason why I was originally thinking shaders is because they'd be a cool means of doing this: I could write a program which could add some interesting effects for the borders. In terms of how to do this via one shader program, though, I'm completely stumped.
Any ideas on a good approach for this?
What you call is cel-shading. One of the most popular tutorials for this can be found here: http://nehe.gamedev.net/tutorial/cel_shading/25001/
Using GL_LINES is not inefficient. Use a VBO to store the vertex data on the GPU, then you can draw several times. And you could even draw the GL_LINES with your custom shader. In the tutorial it is basically done the same way. For the contours to not bleed into the solid object backgrounds you need a small depth offset (avoid z-buffer fighting).
it is definetely related to cartoon (cell) shading.
There are several ways to do it:
use geometry shaders (like here http://www.gamasutra.com/view/feature/1644/sponsored_feature_inking_the_.php)
do a postprocessing like here: http://xnameetingpoint.weebly.com/shader7f31.html
interesting method (distant to edges): http://cgg-journal.com/2008-2/06/index.html