DirectX 11 LINELIST_TOPOLOGY uncompleted 2D rectangle at left-top coordinates - c++

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:)

Related

How to rotate camera view with glm?

I'm trying to rotate my camera with the purpose of see an object rotating around my cam with a rotation Matrix that I develop the problem is that it doesn't works.
So I try with the glm::rotation matrix and put the values
m_View = glm::rotate(m_View, a * glm::radians(180.0f), glm::vec3(0.0f, 1.0f, 0.0f))
but it does not works either:
void CCam::setView()
{
Front = glm::normalize(Eye - At);
Right = glm::normalize(glm::cross(Up, Front));
up = glm::cross(Front, Right); // Up Verdadero
m_View = glm::lookAt(
Eye, // Camera Position
(Eye + Front), // Where the camera looks
up // This is another way to say camera is not rotated
);
newAt = glm::vec4(At, 1.0f);
//m_View = m_View * GLMatrixRotationY(a);
m_View = glm::rotate(m_View, a * glm::radians(180.0f), glm::vec3(0.0f, 1.0f, 0.0f));
}
glm::mat4 CCam::GLMatrixRotationX(float Angle)
{
matrizRotacionX = glm::mat4(
1, 0, 0, 0,
0, cos(Angle), -sin(Angle), 0,
0, sin(Angle), cos(Angle), 0,
0, 0, 0, 1
);
return matrizRotacionX;
}
I expect to see my mesh rotating around the camera but I only got the cam rotating around the mesh.

Setting Constant Buffer Directx

So, I'm trying to get my constant buffer in my shader to have a projection matrix that is orthogonal...
Can anyone tell me why I'm rendering nothing now that I tried to do this?
I assumed I needed to make two mapped subresources, and two buffers, one for vertex and the other for constant, maybe this is wrong?
Here is my code:
Vertex OurVertices[] =
{
{ D3DXVECTOR2(-0.5f,-0.5f), D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f) },
{ D3DXVECTOR2(-0.5f,0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) },
{ D3DXVECTOR2(0.5f,0.5f), D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f) },
{ D3DXVECTOR2(-0.5f,-0.5f), D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f) },
{ D3DXVECTOR2(0.5f,0.5f), D3DXCOLOR(0.0f, 1.0f, 0.0f, 1.0f) },
{ D3DXVECTOR2(0.5f,-0.5f), D3DXCOLOR(0.0f, 0.0f, 1.0f, 1.0f) }
};
// create the vertex buffer
D3D11_BUFFER_DESC vertexBufferDesc;
ZeroMemory(&vertexBufferDesc, sizeof(vertexBufferDesc));
vertexBufferDesc.Usage = D3D11_USAGE_DYNAMIC; // write access access by CPU and GPU
vertexBufferDesc.ByteWidth = sizeof(Vertex) * 6; // size is the VERTEX struct * 3
vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; // use as a vertex buffer
vertexBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; // allow CPU to write in buffer
dev->CreateBuffer(&vertexBufferDesc, NULL, &pVBuffer); // create the buffer
D3D11_MAPPED_SUBRESOURCE ms_Vertex;
devcon->Map(pVBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &ms_Vertex);
memcpy(ms_Vertex.pData, OurVertices, sizeof(OurVertices)); // copy the data
devcon->Unmap(pVBuffer, NULL); // unmap the buffer
devcon->VSSetConstantBuffers(NULL, 1, &pVBuffer); // Finanly set the constant buffer in the vertex shader with the updated values.
MatrixBufferType* dataPtr;
D3D11_BUFFER_DESC constantBufferDesc; // create the constant buffer
ZeroMemory(&constantBufferDesc, sizeof(constantBufferDesc));
constantBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
constantBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
constantBufferDesc.ByteWidth = sizeof(MatrixBufferType);
constantBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
constantBufferDesc.MiscFlags = 0;
constantBufferDesc.StructureByteStride = 0;
dev->CreateBuffer(&constantBufferDesc, NULL, &pCBuffer); // create the buffer
D3D11_MAPPED_SUBRESOURCE ms_CBuffer;
devcon->Map(pCBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &ms_CBuffer);
D3DXMatrixOrthoLH(&m_orthoMatrix, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 1);
D3DXMatrixTranspose(&m_orthoMatrix, &m_orthoMatrix);
dataPtr = (MatrixBufferType*)ms_CBuffer.pData;
dataPtr->projection = m_orthoMatrix;
memcpy(ms_CBuffer.pData, &dataPtr, sizeof(MatrixBufferType));
devcon->Unmap(pCBuffer, NULL);
devcon->VSSetConstantBuffers(NULL, 1, &pCBuffer); // Finally set the constant buffer in the vertex shader with the updated values.
So, attempting to put my projection matrix to use in my shader code:
cbuffer ConstantBuffer
{
matrix world;
matrix view;
matrix projection;
};
VOut VShader(float4 position : POSITION, float4 color : COLOR)
{
VOut output;
output.position = position;
output.position = mul(output.position, projection);
output.color = color;
return output;
}
Causes my quad which was originally rendering, to disappear.
This leads me to believe I'm doing something wrong, I just don't know what yet.

understanding OpenGL ES crash causes and ways to debug one

Leaning how to use OpenGL ES under cocos2d-x.
Help me to understand while the below function crashes with EXC_BAD_ACCESS on noise->visit(); which probably means that my OpenGL state is screwed-up by the time the command is executed.
My method:
Sprite* GameLevelLayer::spriteWithColor(Color4F bgColor, float textureWidth, float textureHeight)
{
// 1: Create new RenderTexture
auto rt = RenderTexture::create(textureWidth, textureHeight);
// 2: Call RenderTexture:begin
rt->beginWithClear(bgColor.r, bgColor.g, bgColor.b, bgColor.a);
// 3: Draw into the texture
//// gradient
gradient_command.init(rt->getGlobalZOrder());
gradient_command.func = std::bind(&GameLevelLayer::onDrawGradient, this, textureWidth, textureHeight);
auto renderer = Director::getInstance()->getRenderer();
renderer->addCommand(&gradient_command);
//// noise cloud
BlendFunc blendFunc;
blendFunc.src = GL_DST_COLOR;
blendFunc.dst = GL_ZERO;
auto noise = Sprite::create("Noise.png");
noise->setBlendFunc(blendFunc);
noise->setPosition(Vec2(textureWidth / 2, textureHeight / 2));
// XXX
noise->visit();
// 4: Call RenderTexture:end
rt->end();
// 5: Create a new Sprite from the texture
return Sprite::createWithTexture(rt->getSprite()->getTexture());
}
and the gradient:
void GameLevelLayer::onDrawGradient(float textureWidth, float textureHeight)
{
setGLProgram(ShaderCache::getInstance()->getGLProgram(GLProgram::SHADER_NAME_POSITION_COLOR));
getGLProgram()->use();
getGLProgram()->setUniformsForBuiltins();
float gradientAlpha = 0.8f;
std::vector<Vec2> vertices;
std::vector<Color4F> colors;
vertices.push_back(Vec2(0, 0));
colors.push_back(Color4F(0.0f, 0.0f, 0.0f, 0.0f ));
vertices.push_back(Vec2(textureWidth, 0));
colors.push_back(Color4F(0.0f, 0.0f, 0.0f, 0.0f ));
vertices.push_back(Vec2(0, textureHeight));
colors.push_back(Color4F(0.0f, 0.0f, 0.0f, gradientAlpha ));
vertices.push_back(Vec2(textureWidth, textureHeight));
colors.push_back(Color4F(0.0f, 0.0f, 0.0f, gradientAlpha ));
GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR);
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices.data());
glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, colors.data());
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)vertices.size());
}
Is this because I am using parameters of a wrong size, somewhere? How does one go about debugging something like this?

Draw triangle using expandable array in DirectX 9

I'm trying to draw a triangle which did work with the following code using C++ and DirectX:
Renderer.h
#pragma once
#include "DirectX.h"
#include "Camera.h"
#include "OBJMesh.h"
class Renderer : public DirectX
{
public:
Renderer(std::string windowTitle, int x, int y, unsigned int windowWidth, unsigned int windowHeight, bool fullscreen);
~Renderer();
void Update();
void Render();
protected:
OBJMesh* modelMesh;
Camera* camera;
VERTEX vertices[3];
};
Renderer.cpp
#include "Renderer.h"
Renderer::Renderer(std::string windowTitle, int x, int y, unsigned int windowWidth, unsigned int windowHeight, bool fullscreen) : DirectX(windowTitle, x, y, windowWidth, windowHeight, fullscreen)
{
//camera = new Camera(Vector3(0.0f, -100.0f, 5000.0f), 0.0f, 0.0f);
camera = new Camera(0.0f, 0.0f, D3DXVECTOR3(0.0f, 0.0f, 10.0f));
OBJMesh* modelMesh = new OBJMesh("../Models/Tank/destroyedTank.obj");
VERTEX v1, v2, v3;
v1.x = 0.0f;
v1.y = -1.0f;
v1.z = 0.5f;
v1.color = D3DCOLOR_XRGB(0, 0, 255);
v2.x = 1.0f;
v2.y = 1.0f;
v2.z = 0.5f;
v2.color = D3DCOLOR_XRGB(0, 255, 0);
v3.x = -1.0f;
v3.y = 1.0f;
v3.z = 0.5f;
v3.color = D3DCOLOR_XRGB(255, 0, 0);
vertices[0] = v1;
vertices[1] = v2;
vertices[2] = v3;
device->CreateVertexBuffer(3 * sizeof(VERTEX), 0, VERTEXFORMAT, D3DPOOL_MANAGED, &vertexBuffer, NULL);
VOID* lockingAd;
vertexBuffer->Lock(0, 0, (void**)&lockingAd, 0);
memcpy(lockingAd, vertices, sizeof(vertices));
vertexBuffer->Unlock();
device->SetRenderState(D3DRS_LIGHTING, FALSE); //turn off lighting - DirectX needs to know this :(
device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); //turns off face culling (for now)
}
Renderer::~Renderer()
{
delete camera;
}
void Renderer::Update()
{
window->Update();
float msec = Window::GetGameTimer()->GetFrameTime();
camera->Update(msec);
}
void Renderer::Render()
{
device->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(40, 40, 40), 1.0f, 0);
device->BeginScene(); //Must be used as it tells DirectX we're starting to draw stuff.
D3DXMATRIX worldMat;
D3DXMatrixTranslation(&worldMat, 0.0f, 0.0f, 0.0f);
device->SetTransform(D3DTS_WORLD, &worldMat);
device->SetTransform(D3DTS_VIEW, &camera->BuildViewMatrix());
D3DXMATRIX projMatrix;
D3DXMatrixPerspectiveFovLH( &projMatrix,
D3DXToRadian(45),
(float)width/(float)height,
1.0f,
10000.0f);
device->SetTransform(D3DTS_PROJECTION, &projMatrix);
device->SetFVF(VERTEXFORMAT);
device->SetStreamSource(0, vertexBuffer, 0, sizeof(VERTEX));
device->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 1);
device->EndScene(); //Thank you for waiting, I have finished drawing stuff on the screen, please handle the rest Mr DirectX.
device->Present(NULL, NULL, NULL, NULL);
}
However, when I change the vertices array to VERTEX* vertices in my header file and vertices = new VERTEX[3] in my cpp file, it doesn't draw anything... why's that? How can I fix this?
I'm not sure if this is your problem, but this looks like it could be the offending line:
memcpy( lockingAd, vertices, sizeof(vertices) );
Here, this will do different things if vertices is of type VERTEX[3] and VERTEX*. In the first case the sizeof will return the size of the array, whereas in the second case it will simply return the size of a pointer on your machine, to fix this (if you have a fixed number of elements 3) you should change it to the following:
memcpy( lockingAd, vertices, sizeof(VERTEX) * 3 );

Direct3D11(C++): Updating Texture coordinates in constant buffer?

I'm trying to make a rather basic 2D Engine with Direct3D.
I made a LoadImage() function which stores all the rather static behaviour of the image in an object. (Shaders, Vertexbuffers, Samplers etc)
I am planning to do the positioning of the vertices with matrices in constant buffers.
However, I would also like to have a DrawImage() function, which would have a parameter to tell what part of the texture should be drawn (clipped), so I would have to update the texture coordinates.
Since the vertexbuffer is already pre-defined, I wondered if there is a way to update texture coordinates via a constantbuffer that would be sent to the vertexshader?
I hope my question is clear enough, if you have any doubts look at the code below.
bool GameManager::GMLoadImage(Image* pImage, const char* pkcFilePath, ImageDesc* pImDesc)
{
pImage = new Image();
ID3D11ShaderResourceView* pColorMap = (pImage)->GetpColorMap();
/// CREATE SHADER RESOURCE VIEW (from file) ///
HRESULT result = D3DX11CreateShaderResourceViewFromFileA(m_pDevice,
pkcFilePath,
0,
0,
&pColorMap,
0);
if (FAILED(result)) {
MessageBoxA(NULL,"Error loading ShaderResourceView from file","Error",MB_OK);
return false;
}
/// RECEIVE TEXTURE DESC ///
ID3D11Resource* pColorTex;
pColorMap->GetResource(&pColorTex);
((ID3D11Texture2D*)pColorTex)->GetDesc(&((pImage)->GetColorTexDesc()));
pColorTex->Release();
/// CREATE VERTEX BUFFER ///
D3D11_TEXTURE2D_DESC colorTexDesc = pImage->GetColorTexDesc();
float halfWidth = static_cast<float>(colorTexDesc.Width)/2.0f;
float halfHeight = static_cast<float>(colorTexDesc.Height)/2.0f;
Vertex.PosTex vertices[]=
{
{XMFLOAT3( halfWidth, halfHeight, 1.0f ), XMFLOAT2( 1.0f, 0.0f )},
{XMFLOAT3( halfWidth, -halfHeight, 1.0f ), XMFLOAT2( 1.0f, 1.0f )},
{XMFLOAT3( -halfWidth, -halfHeight, 1.0f ), XMFLOAT2( 0.0f, 1.0f )},
{XMFLOAT3( -halfWidth, -halfHeight, 1.0f ), XMFLOAT2( 0.0f, 1.0f )},
{XMFLOAT3( -halfWidth, halfHeight, 1.0f ), XMFLOAT2( 0.0f, 0.0f )},
{XMFLOAT3( halfWidth, halfHeight, 1.0f ), XMFLOAT2( 1.0f, 0.0f )}
};
D3D11_BUFFER_DESC vertexDesc;
ZeroMemory(&vertexDesc,sizeof(vertexDesc));
vertexDesc.Usage = D3D11_USAGE_DEFAULT;
vertexDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vertexDesc.ByteWidth = sizeof(Vertex.PosTex)*6;
D3D11_SUBRESOURCE_DATA resourceData;
resourceData.pSysMem = vertices;
ID3D11Buffer* pVBuffer = pImage->GetpVertexBuffer();
result = m_pDevice->CreateBuffer(&vertexDesc,&resourceData,&pVBuffer);
if (FAILED(result))
{
MessageBoxA(NULL,"Error Creating VBuffer","Error",MB_OK);
return false;
}
/// SET POINTER TO IMAGEDESC
ImageDesc* pThisImDesc = pImage->GetpImageDesc();
pThisImDesc = pImDesc;
return true;
}
bool GameManager::GMDrawImage(Image* pImage, const CLIPRECT& rkClip)
{
ImageDesc* thisImDesc = pImage->GetpImageDesc();
if ( (thisImDesc != m_pImDesc) ) {
m_pImDesc = thisImDesc;
m_pContext->IASetInputLayout(m_pImDesc->pInputLayout);
m_pContext->IASetPrimitiveTopology(m_pImDesc->Topology);
m_pContext->VSSetShader(m_pImDesc->pSolidColorVS,0,0);
m_pContext->PSSetShader(m_pImDesc->pSolidColorPS,0,0);
m_pContext->PSSetSamplers(0,1,&m_pImDesc->pSampler);
m_pContext->OMSetBlendState(m_pImDesc->pBlendState,NULL,0xFFFFFFFF);
}
UINT stride = m_pImDesc->VertexSize;
UINT offset = 0;
ID3D11Buffer* pVBuffer = pImage->GetpVertexBuffer();
ID3D11ShaderResourceView* pColorMap = pImage->GetpColorMap();
m_pContext->IASetVertexBuffers(0,1,&pVBuffer,&stride,&offset);
m_pContext->PSSetShaderResources(0,1,&pColorMap);
//set constant buffers?
m_pContext->Draw(6,0);
}
Yes, as long as your texture coordinates are hardcoded to 0.0 through 1.0 in your vertex buffer, you can use a texture transformation matrix. It's a 3x3 matrix that will transform your 2D texture coordinates.
For instance, if you want to use the bottom-right quadrant of your texture (assuming top-left is origin), you could use the following matrix:
0.5 0.0 0.0
0.0 0.5 0.0
0.5 0.5 1.0
Then, in the vertex shader, you multiply the texture coordinates by that matrix like so:
float3 coord = float3(In.texCoord, 1.0);
coord *= textureTransform;
Out.texCoord = coord.xy / coord.z;
In.texCoord and Out.texCoord being float2 input and output texture coordinates respectively.
The division by Z is optional if you are only doing affine transformations (translations, scaling, rotations and skews) so feel free to remove it if not needed.
To generalize the matrix:
Sx 0.0 0.0
0.0 Sy 0.0
Tx Ty 1.0
Where Txy is the position of the clip area and Sxy the size of the clip area, in texture coordinates.