I'm having trouble with my OpenGL game where I can't get the camera to move.
I am unable to use GLFW, GLUT and glulookat(). Here is my code, what's wrong?
P.S everything works except the camera movement meaning the game plays and works perfectly, just cant move the camera.
My Camera Code:
#include "SpriteRenderer.h"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
class Camera
{
private:
Shader shader;
GLfloat angle = -90.f;
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f),
cameraPosition = glm::vec3(0.0f, 0.0f, 0.1f),
cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
glm::mat4 viewMatrix;
// recompute the view matrix from the camera variables
void updateMatrix()
{
viewMatrix = glm::lookAt(cameraPosition, cameraPosition + cameraFront, cameraUp);
}
// default constructor
void defaultNew()
{
cameraPosition = glm::vec3(0.0f, 0.0f, 0.1f);
cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
updateMatrix();
}
public:
Camera() { defaultNew(); }
Camera(Shader &shader) { this->shader = shader; defaultNew(); }
glm::mat4 GetViewMatrix() const
{
// if your view matrix is always up-to-date, just return it directly
return viewMatrix;
}
// get functions
glm::vec3 GetCameraPosition() const { return cameraPosition; }
// .. same for Front and Up
// set functions
// call updateMatrix every time you update a variable
void SetCameraPosition(glm::vec3 pos)
{
cameraPosition = pos;
updateMatrix();
}
// .. same for Front and Up
// no need to use this-> all the time
virtual void Draw()
{
this->shader.Use();
this->shader.SetMatrix4("view", viewMatrix);
}
};
My Shader Code:
Shader &Use(){ glUseProgram(this->ID); return *this; }
void SetMatrix4(const GLchar *name, const glm::mat4 &matrix, GLboolean useShader = false)
{ if (useShader)this->Use(); glUniformMatrix4fv(glGetUniformLocation(this->ID, name), 1, GL_FALSE, glm::value_ptr(matrix)); }
My Game Code:
Camera *View;
projection2 = glm::perspective(glm::radians(44.0f), (float)this->Width / (float)this->Width, 0.1f, 100.0f);
AssetController::LoadShader("../src/Shaders/Light.vert", "../src/Shaders/Light.frag", "light");
AssetController::GetShader("light").SetMatrix4("projection", projection2);
View = new Camera(AssetController::GetShader("light"));
(...)
GLfloat velocity = playerSpeed * deltaTime;
glm::vec3 camPosition;
// Update Players Position
if (movingLeft)
{
if (Player->Position.x >= 0)
{
Player->Position.x -= velocity;
if (Ball->Stuck)
Ball->Position.x -= velocity;
camPosition = View->GetCameraPosition();
camPosition.x -= velocity / 2;
View->SetCameraPosition(camPosition);
}
}
else if (movingRight)
{
if (Player->Position.x <= this->Width - Player->Size.x)
{
Player->Position.x += velocity;
if (Ball->Stuck)
Ball->Position.x += velocity;
camPosition = View->GetCameraPosition();
camPosition.x += velocity / 2;
View->SetCameraPosition(camPosition);
}
}
(...)
GameOver->Draw(*Renderer);
View->Draw();
My Shaders:
.vert:
#version 440 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;
out vec2 TexCoord;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
gl_Position = projection * view * model * vec4(aPos, 1.0f);
TexCoord = vec2(aTexCoord.x, aTexCoord.y);
}
.frag:
#version 440 core
out vec4 FragColor;
in vec2 TexCoord;
// texture samplers
uniform sampler2D texture1;
uniform sampler2D texture2;
void main()
{
// linearly interpolate between both textures (80% container, 20% awesomeface)
FragColor = mix(texture(texture1, TexCoord), texture(texture2, TexCoord), 0.2);
}
The problem is that you only update local position variable cameraPosition, and not the view matrix, which is passed to OpenGL during rendering.
It is also a bad habit to make the camera variables and matrix public, as they can potentially be modified incorrectly or out-of-sync (as you are doing). Instead, you could write a pair of get/set functions:
class Camera
{
private:
Shader shader;
GLfloat angle = -90.f;
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f),
cameraPosition = glm::vec3(0.0f, 0.0f, 0.1f),
cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
glm::mat4 viewMatrix;
// recompute the view matrix from the camera variables
void updateMatrix()
{
viewMatrix = glm::lookAt(cameraPosition, cameraPosition + cameraFront, cameraUp);
}
// default constructor
void defaultNew()
{
cameraPosition = glm::vec3(0.0f, 0.0f, 0.1f);
cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
updateMatrix();
}
public:
Camera() {
defaultNew();
}
Camera(Shader &shader) {
this->shader = shader;
defaultNew();
}
glm::mat4 GetViewMatrix() const
{
// if your view matrix is always up-to-date, just return it directly
return viewMatrix;
}
// get functions
glm::vec3 GetCameraPosition() const { return cameraPosition; }
// .. same for Front and Up
// set functions
// call updateMatrix every time you update a variable
void SetCameraPosition(glm::vec3 p)
{
cameraPosition = p;
updateMatrix();
}
// .. same for Front and Up
// no need to use this-> all the time
virtual void Draw()
{
shader.Use();
shader.SetMatrix4("view", viewMatrix);
}
};
And then when you update the camera position, simply use these functions instead of the exposed variables:
view->SetCameraPosition(view->GetCameraPosition() + velocity / 2.0f);
This will make sure that the draw calls always use the updated view matrix instead of the initial one (which was the case before and the source of your troubles).
i've been following tutorials on directx 11 with a book and am now trying to give my code some lighting effects with a shader. But the problem is that it only shows the back buffer and doens't seem te make use of the lighting shader file at all. I am trying to light up a cube. Thanks for the help already.
HLSL:
struct DirectionalLight
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float3 Direction;
float pad;
};
struct PointLight
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float3 Position;
float Range;
float3 Att;
float pad;
};
struct SpotLight
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float3 Position;
float Range;
float3 Direction;
float Spot;
float3 Att;
float pad;
};
struct Material
{
float4 Ambient;
float4 Diffuse;
float4 Specular;
float4 Reflect;
};
void ComputeDirectionalLight( Material mat, DirectionalLight L, float3 normal, float3 toEye, out float4 ambient, out float4 diffuse, out float4 spec)
{
ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
spec = float4(0.0f, 0.0f, 0.0f, 0.0f);
float3 lightVec = -L.Direction;
ambient = mat.Ambient * L.Ambient;
float diffuseFactor = dot(lightVec, normal);
[flatten]
if( diffuseFactor > 0.0f )
{
float3 v = reflect(-lightVec, normal);
float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w);
diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
}
}
void ComputePointLight(Material mat, PointLight L, float3 pos, float3 normal, float3 toEye, out float4 ambient, out float4 diffuse, out float4 spec)
{
ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
spec = float4(0.0f, 0.0f, 0.0f, 0.0f);
float3 LightVec = L.Position - pos;
float d = length(LightVec);
if( d > L.Range )
return;
LightVec /= d;
ambient = mat.Ambient * L.Ambient;
float diffuseFactor = dot(LightVec, normal);
[flatten]
if(diffuseFactor > 0.0f)
{
float3 v = reflect(-LightVec, normal);
float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w);
diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
}
float att = 1.0f / dot(L.Att, float3(1.0f, d, d*d));
diffuse *= att;
spec *= att;
}
void ComputeSpotLight(Material mat, SpotLight L, float3 pos, float3 normal, float3 toEye, out float4 ambient, out float4 diffuse, out float4 spec)
{
ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
spec = float4(0.0f, 0.0f, 0.0f, 0.f);
float3 LightVec = L.Position - pos;
float d = length(LightVec);
if( d > L.Range )
return;
LightVec /= d;
ambient = mat.Ambient * L.Ambient;
float diffuseFactor = dot(LightVec, normal);
[flatten]
if( diffuseFactor > 0.0f )
{
float3 v = reflect(-LightVec, normal);
float specFactor = pow(max(dot(v, toEye), 0.0f), mat.Specular.w);
diffuse = diffuseFactor * mat.Diffuse * L.Diffuse;
spec = specFactor * mat.Specular * L.Specular;
}
float spot = pow(max(dot(-LightVec, L.Direction), 0.0f), L.Spot);
float att = spot / dot(L.Att, float3(1.0f, d, d*d));
ambient *= spot;
diffuse *= att;
spec *= att;
}
cbuffer cbPerFrame
{
DirectionalLight gDirLight;
PointLight gPointLight;
SpotLight gSpotLight;
float3 gEyePosW;
};
cbuffer cbPerObject
{
float4x4 gWorld;
float4x4 gWorldInvTranspose;
float4x4 gWorldViewProj;
Material gMaterial;
};
struct VertexIn
{
float3 PosL : POSITION;
float3 NormalL : NORMAL;
};
struct VertexOut
{
float4 PosH : SV_POSITION;
float3 PosW : POSITION;
float3 NormalW: NORMAL;
};
VertexOut VS(VertexIn vin)
{
VertexOut vout;
vout.PosW = mul(float4(vin.PosL, 1.0f), gWorld).xyz;
vout.NormalW = mul(vin.NormalL, (float3x3)gWorldInvTranspose);
vout.PosH = mul(float4(vin.PosL, 1.0f), gWorldViewProj);
return vout;
}
float4 PS(VertexOut pin) : SV_Target
{
pin.NormalW = normalize(pin.NormalW);
float3 toEyeW = normalize(gEyePosW - pin.PosW);
float4 ambient = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 diffuse = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 spec = float4(0.0f, 0.0f, 0.0f, 0.0f);
float4 A, D, S;
ComputeDirectionalLight(gMaterial, gDirLight, pin.NormalW, toEyeW, A, D, S);
ambient += A;
diffuse += D;
spec += S;
ComputePointLight(gMaterial, gPointLight, pin.PosW, pin.NormalW, toEyeW, A, D, S);
ambient += A;
diffuse += D;
spec += S;
ComputeSpotLight(gMaterial, gSpotLight, pin.PosW, pin.NormalW, toEyeW, A, D, S);
ambient += A;
diffuse += D;
spec += S;
float4 litColor = ambient + diffuse + spec;
litColor.a = gMaterial.Diffuse.a;
return litColor;
}
Code in my cpp file:
struct Vertex
{
XMFLOAT3 Pos;
XMFLOAT3 Normal;
};
struct CBUFFER{ XMMATRIX gWorldViewProj; };
class BoxApp : public Framework_App
{
public:
BoxApp(HINSTANCE hInstance);
~BoxApp();
bool Init();
void OnResize();
void UpdateScene(float dt);
void DrawScene();
void OnMouseDown(WPARAM BtnState, int x, int y);
void OnMouseUp(WPARAM BtnState, int x, int y);
void OnMouseMove(WPARAM BtnState, int x, int y);
private:
void BuildGeometryBuffers();
void BuildFX();
private:
ID3D11Buffer* mBoxVB;
ID3D11Buffer* mBoxIB;
ID3D11Buffer* mBoxCB = nullptr;
ID3D11VertexShader* pVS;
ID3D11PixelShader* pPS;
ID3D11InputLayout* mInputLayout;
XMFLOAT4X4 mWorld;
XMFLOAT4X4 mView;
XMFLOAT4X4 mProj;
XMFLOAT3 mEyePosW;
XMFLOAT3 GetNormal(float x, float z)const;
//licht variablen
DirectionalLight mDirLight;
PointLight mPointLight;
SpotLight mSpotLight;
Material mLandmat;
Material mWavesmat;
float mTheta;
float mPhi;
float mRadius;
float GetHeight(float x, float z)const;
POINT mLastMousePos;
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance,
PSTR cmdLine, int showCmd)
{
BoxApp theApp(hInstance);
if (!theApp.Init())
return 0;
return theApp.App_Run();
}
BoxApp::BoxApp(HINSTANCE hInstance)
: Framework_App(hInstance), mBoxVB(0), mBoxIB(0), mBoxCB(0) ,pVS(0), pPS(0), mInputLayout(0), mEyePosW(0.0f, 0.0f, 0.0f),
mTheta(1.5f*MathTools::HalfTau), mPhi(0.25f*MathTools::HalfTau), mRadius(5.0f)
{
mLastMousePos.x = 0;
mLastMousePos.y = 0;
XMMATRIX I = XMMatrixIdentity();
XMStoreFloat4x4(&mWorld, I);
XMStoreFloat4x4(&mView, I);
XMStoreFloat4x4(&mProj, I);
//directional light
mDirLight.Ambient = XMFLOAT4(0.2f, 0.2f, 0.2f, 1.0f);
mDirLight.Diffuse = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mDirLight.Specular = XMFLOAT4(0.5f, 0.5f, 0.5f, 1.0f);
mDirLight.Direction = XMFLOAT3(0.57735f, -0.57735f, 0.57735f);
//point light
mPointLight.Ambient = XMFLOAT4(0.3f, 0.3, 0.3f, 1.0f);
mPointLight.Diffuse = XMFLOAT4(0.7f, 0.7f, 0.7f, 1.0f);
mPointLight.Specular = XMFLOAT4(0.7f, 0.7f, 0.7f, 1.0f);
mPointLight.Att = XMFLOAT3(0.0f, 0.1f, 0.0f);
mPointLight.Range = 25.0f;
//spot light
mSpotLight.Ambient = XMFLOAT4(0.0f, 0.0f, 0.0f, 1.0f);
mSpotLight.Diffuse = XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f);
mSpotLight.Specular = XMFLOAT4(1.0f, 1.0f, 1.0f, 1.0f);
mSpotLight.Att = XMFLOAT3(1.0f, 0.0f, 0.0f);
mSpotLight.Spot = 96.0f;
mSpotLight.Range = 1000.0f;
//materials
mLandmat.Ambient = XMFLOAT4(0.48f, 0.77f, 0.46f, 1.0f);
mLandmat.Diffuse = XMFLOAT4(0.48f, 0.77f, 0.46f, 1.0f);
mLandmat.Specular = XMFLOAT4(0.2f, 0.2f, 0.2f, 16.0f);
}
BoxApp::~BoxApp()
{
ReleaseCOM(mBoxVB);
ReleaseCOM(mBoxIB);
ReleaseCOM(mBoxCB);
ReleaseCOM(pVS);
ReleaseCOM(pPS);
ReleaseCOM(mInputLayout);
}
bool BoxApp::Init()
{
if (!Framework_App::App_Init())
return false;
BuildGeometryBuffers();
BuildFX();
return true;
}
void BoxApp::OnResize()
{
Framework_App::OnResize();
// The window resized, so update the aspect ratio and recompute the projection matrix.
XMMATRIX P = XMMatrixPerspectiveFovLH(0.25f*MathTools::HalfTau, AspectRatio(), 1.0f, 1000.0f);
XMStoreFloat4x4(&mProj, P);
}
void BoxApp::UpdateScene(float dt)
{
// Convert Spherical to Cartesian coordinates.
float x = mRadius*sinf(mPhi)*cosf(mTheta);
float z = mRadius*sinf(mPhi)*sinf(mTheta);
float y = mRadius*cosf(mPhi);
mEyePosW = XMFLOAT3(x, y ,z);
// Build the view matrix.
XMVECTOR pos = XMVectorSet(x, y, z, 1.0f);
XMVECTOR target = XMVectorZero();
XMVECTOR up = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMMATRIX V = XMMatrixLookAtLH(pos, target, up);
XMStoreFloat4x4(&mView, V);
//update lights
mPointLight.Position.x = 70.0f*cosf(0.2f*mTimer.Totaltime());
mPointLight.Position.z = 70.0f*sinf(0.2f*mTimer.Totaltime());
mPointLight.Position.y = MathTools::Max(GetHeight(mPointLight.Position.x, mPointLight.Position.z), -3.0f) + 10.0f;
mSpotLight.Position = mEyePosW;
XMStoreFloat3(&mSpotLight.Direction, XMVector3Normalize(target - pos));
}
void BoxApp::DrawScene()
{
MainDevContext->ClearRenderTargetView(mRenderTargetView, reinterpret_cast<const float*>(&Colors::LightSteelBlue));
MainDevContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
MainDevContext->IASetInputLayout(mInputLayout);
MainDevContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
UINT stride = sizeof(Vertex);
UINT offset = 0;
MainDevContext->IASetVertexBuffers(0, 1, &mBoxVB, &stride, &offset);
MainDevContext->IASetIndexBuffer(mBoxIB, DXGI_FORMAT_R32_UINT, 0);
// Set constants
XMMATRIX world = XMLoadFloat4x4(&mWorld);
XMMATRIX view = XMLoadFloat4x4(&mView);
XMMATRIX proj = XMLoadFloat4x4(&mProj);
XMMATRIX worldViewProj = world*view*proj;
XMMATRIX worldViewProjTRNS = XMMatrixTranspose(worldViewProj);
CBUFFER cBuffer;
cBuffer.gWorldViewProj = worldViewProjTRNS;
MainDevContext->UpdateSubresource(mBoxCB, 0, 0, &cBuffer, 0, 0);
MainDevContext->DrawIndexed(36, 0, 0);
mSwapChain->Present(0, 0);
}
void BoxApp::OnMouseDown(WPARAM BtnState, int x, int y)
{
mLastMousePos.x = x;
mLastMousePos.y = y;
SetCapture(FrmeWrkMainWnd);
}
void BoxApp::OnMouseUp(WPARAM BtnState, int x, int y)
{
ReleaseCapture();
}
void BoxApp::OnMouseMove(WPARAM BtnState, int x, int y)
{
if ((BtnState & MK_LBUTTON) != 0)
{
// Make each pixel correspond to a quarter of a degree.
float dx = XMConvertToRadians(0.25f*static_cast<float>(x - mLastMousePos.x));
float dy = XMConvertToRadians(0.25f*static_cast<float>(y - mLastMousePos.y));
// Update angles based on input to orbit camera around box.
mTheta += dx;
mPhi += dy;
// Restrict the angle mPhi.
mPhi = MathTools::Clamp(mPhi, 0.1f, MathTools::HalfTau - 0.1f);
}
else if ((BtnState & MK_RBUTTON) != 0)
{
// Make each pixel correspond to 0.005 unit in the scene.
float dx = 0.005f*static_cast<float>(x - mLastMousePos.x);
float dy = 0.005f*static_cast<float>(y - mLastMousePos.y);
// Update the camera radius based on input.
mRadius += dx - dy;
// Restrict the radius.
mRadius = MathTools::Clamp(mRadius, 3.0f, 15.0f);
}
mLastMousePos.x = x;
mLastMousePos.y = y;
}
void BoxApp::BuildGeometryBuffers()
{
// Create vertex buffer
Vertex vertices[] =
{
{ XMFLOAT3(-1.0f, -1.0f, -1.0f), (const float*)&Colors::White },
{ XMFLOAT3(-1.0f, +1.0f, -1.0f), (const float*)&Colors::Black },
{ XMFLOAT3(+1.0f, +1.0f, -1.0f), (const float*)&Colors::Red },
{ XMFLOAT3(+1.0f, -1.0f, -1.0f), (const float*)&Colors::Green },
{ XMFLOAT3(-1.0f, -1.0f, +1.0f), (const float*)&Colors::Blue },
{ XMFLOAT3(-1.0f, +1.0f, +1.0f), (const float*)&Colors::Yellow },
{ XMFLOAT3(+1.0f, +1.0f, +1.0f), (const float*)&Colors::Cyan },
{ XMFLOAT3(+1.0f, -1.0f, +1.0f), (const float*)&Colors::Magneta }
};
D3D11_BUFFER_DESC vbd;
vbd.Usage = D3D11_USAGE_IMMUTABLE;
vbd.ByteWidth = sizeof(Vertex)* 8;
vbd.BindFlags = D3D11_BIND_VERTEX_BUFFER;
vbd.CPUAccessFlags = 0;
vbd.MiscFlags = 0;
vbd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = vertices;
MainD3DDevice->CreateBuffer(&vbd, &vinitData, &mBoxVB);
// Create the index buffer
UINT indices[] = {
// front face
0, 1, 2,
0, 2, 3,
// back face
4, 6, 5,
4, 7, 6,
// left face
4, 5, 1,
4, 1, 0,
// right face
3, 2, 6,
3, 6, 7,
// top face
1, 5, 6,
1, 6, 2,
// bottom face
4, 0, 3,
4, 3, 7
};
D3D11_BUFFER_DESC ibd;
ibd.Usage = D3D11_USAGE_IMMUTABLE;
ibd.ByteWidth = sizeof(UINT)* 36;
ibd.BindFlags = D3D11_BIND_INDEX_BUFFER;
ibd.CPUAccessFlags = 0;
ibd.MiscFlags = 0;
ibd.StructureByteStride = 0;
D3D11_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = indices;
MainD3DDevice->CreateBuffer(&ibd, &iinitData, &mBoxIB);
}
float BoxApp::GetHeight(float x, float z)const
{
return 0.3f*(z*sinf(0.1f*x) + x*cosf(0.1*z));
}
XMFLOAT3 BoxApp::GetNormal(float x, float z)const
{
XMFLOAT3 n(-0.03f*z*cosf(0.1f*x) - 0.3f*cosf(0.1f*z), 1.0f, -0.3f*sinf(0.1f*x) - 0.03f*x*sinf(0.1f*z));
XMVECTOR unitNormal = XMVector3Normalize(XMLoadFloat3(&n));
XMStoreFloat3(&n, unitNormal);
return n;
}
void BoxApp::BuildFX()
{
ID3D10Blob* VS;
ID3D10Blob* PS;
D3DX11CompileFromFile((LPSTR)"mColor.shader",0,0, "VS", "vs_4_0", 0, 0, 0, &VS, 0, 0);
D3DX11CompileFromFile((LPSTR)"mColor.shader", 0, 0, "PS", "ps_4_0", 0, 0, 0, &PS, 0, 0);
MainD3DDevice->CreateVertexShader(VS->GetBufferPointer(), VS->GetBufferSize(), NULL, &pVS);
MainD3DDevice->CreatePixelShader(PS->GetBufferPointer(), PS->GetBufferSize(), NULL, &pPS);
MainDevContext->VSSetShader(pVS, 0, 0);
MainDevContext->PSSetShader(pPS, 0, 0);
D3D11_INPUT_ELEMENT_DESC vertexDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
MainD3DDevice->CreateInputLayout(vertexDesc, 2, VS->GetBufferPointer(), VS->GetBufferSize() ,&mInputLayout);
MainDevContext->IASetInputLayout(mInputLayout);
D3D11_BUFFER_DESC bd;
ZeroMemory(&bd, sizeof(bd));
bd.Usage = D3D11_USAGE_DEFAULT;
bd.ByteWidth = sizeof(CBUFFER);
bd.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
MainD3DDevice->CreateBuffer(&bd, nullptr, &mBoxCB);
MainDevContext->VSSetConstantBuffers(0, 1, &mBoxCB);
}
I Think you have alot of errors in this code.
Folow these tutorials aswell, It might be easier to get the whole view then:
http://web.archive.org/web/20140213145557/http://rastertek.com/tutdx11.html
One example, you run BuildFX() at the start, I am pretty sure you should set these two functions every frame
MainDevContext->VSSetShader(pVS, 0, 0);
MainDevContext->PSSetShader(pPS, 0, 0);
Have you succeded to Rendered a cube with pure colors yet? If so you should just build from there.
There is alot of code to mention but the last 5 functions i run every frame is those:
deviceContext->IASetInputLayout(m_layout);
deviceContext->VSSetShader(m_vertexShader, NULL, 0);
deviceContext->PSSetShader(m_pixelShader, NULL, 0);
deviceContext->PSSetSamplers(0, 1, &m_sampleState);
deviceContext->DrawIndexed(indexCount, 0, 0);
Read the link and reduce down your errors. I havent read all of your code.
I am currently trying to draw billboards and some geometry with "modern opengl approach". Problem is that I cannot force billboards to keep their positions in space.
I need to link text positions with positions of another objects. Coordinates of text position are (3,3,3) and same coordinates has end of black line. In some positions I have exactly what I need: text is drawn at the end of line, but in some - it is too far from the end of line.
My render code:
public void Draw()
{
//Set up matrices
projectionMatrix = Matrix4.CreateOrthographic(_width, _height, -10000, 10000);
modelMatrix = Matrix4.Identity;
viewMatrix = Matrix4.CreateRotationY((float)xrot) *
Matrix4.CreateRotationX((float)yrot) *
Matrix4.CreateScale((float)scale);
var viewPort = new Rectangle(-(_width / 2), -(_height / 2), _width, _height);
var viewportTransformationMatrix = ComputeViewportTransformationMatrix(viewPort, -100, 100);
var viewportOrthographicMatrix = ComputeViewportOrthographicMatrix(viewPort);
worldViewProj = modelMatrix * viewMatrix * projectionMatrix;
//DRAW AXISES
GL.UseProgram(axisesProgramID);
axisesProgram.Uniforms["worldViewProj"].SetValue(worldViewProj);
axisesVAO.Bind();
for (int i = 0; i < 4; i++)
{
GL.DrawArrays(PrimitiveType.Lines, i * 2, 2);
}
//DRAW TEXT WITH PRE-CREATED TEXTURE
GL.UseProgram(textProgramID);
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, textureID);
//set-up uniforms
textProgram.Uniforms["og_viewportOrthographicMatrix"].SetValue(viewportOrthographicMatrix);
textProgram.Uniforms["og_viewportTransformationMatrix"].SetValue(viewportTransformationMatrix);
textProgram.Uniforms["Position"].SetValue(new float[] { 3.0f, 3.0f, 3.0f });
textProgram.Uniforms["projectionMatrix"].SetValue(projectionMatrix);
textProgram.Uniforms["modelViewMatrix"].SetValue(modelViewMatrix);
textProgram.Uniforms["og_texture0"].SetValue(0);
GL.DrawArrays(PrimitiveType.Points, 0, 1);
GL.BindTexture(TextureTarget.Texture2D, 0);
}
public Matrix4 ComputeViewportTransformationMatrix(Rectangle viewport, float nearDepthRange, float farDepthRange)
{
double halfWidth = viewport.Width * 0.5;
double halfHeight = viewport.Height * 0.5;
double halfDepth = (farDepthRange - nearDepthRange) * 0.5;
//
// Bottom and top swapped: MS -> OpenGL
//
return new Matrix4(
(float)halfWidth, 0.0f, 0.0f, (float)viewport.Left + (float)halfWidth,
0.0f, (float)halfHeight, 0.0f, (float)viewport.Top + (float)halfHeight,
0.0f, 0.0f, (float)halfDepth, (float)nearDepthRange + (float)halfDepth,
0.0f, 0.0f, 0.0f, 1.0f);
}
public static Matrix4 ComputeViewportOrthographicMatrix(Rectangle viewport)
{
//
// Bottom and top swapped: MS -> OpenGL
//
return Matrix4.CreateOrthographicOffCenter(
(float)viewport.Left, (float)viewport.Right,
(float)viewport.Top, (float)viewport.Bottom,
0.0f, 1.0f);
}
My axises shaders are really simple path-through.
//VERTEX SHADER
#version 150 core
in vec3 in_Position;
in vec3 in_Color;
out vec4 color;
uniform mat4 worldViewProj;
void main(void) {
gl_Position = worldViewProj * vec4(in_Position, 1.0);
color = vec4(in_Color, 1.0f);
}
//FRAGMENT SHADER
#version 150 core
in vec4 color;
out vec4 out_Color;
void main(void)
{
out_Color = color;
}
Here are text (texture) shaders:
//VERTEX SHADER
#version 330
out float gsOrigin;
out vec2 gsPixelOffset;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 og_viewportTransformationMatrix;
uniform float origin = 6; // TODO: Why does this not work when float is int?
uniform vec2 pixelOffset = vec2(0,0);
uniform vec3 Position;
vec4 ModelToWindowCoordinates(
vec4 v,
mat4 modelViewPerspectiveMatrix,
mat4 viewportTransformationMatrix)
{
v = modelViewPerspectiveMatrix * v; // clip coordinates
v.xyz /= v.w; // normalized device coordinates
v.xyz = (viewportTransformationMatrix * vec4(v.xyz, 1.0)).xyz; // window coordinates
return v;
}
void main()
{
gl_Position = ModelToWindowCoordinates ( vec4(Position, 1.0f) , modelViewMatrix * projectionMatrix , og_viewportTransformationMatrix ) ;
gsOrigin = origin;
gsPixelOffset = pixelOffset;
}
//GEOMETRY SHADER
#version 330
layout(points) in;
layout(triangle_strip, max_vertices = 4) out;
in float gsOrigin[];
in vec2 gsPixelOffset[];
out vec2 fsTextureCoordinates;
uniform sampler2D og_texture0;
uniform float og_highResolutionSnapScale;
uniform mat4 og_viewportOrthographicMatrix;
void main()
{
float originScales[3] = float[](0.0, 1.0, -1.0);
vec2 halfSize = vec2(textureSize(og_texture0, 0)) * 0.5 * og_highResolutionSnapScale;
vec4 center = gl_in[0].gl_Position;
int horizontalOrigin = int(gsOrigin[0]) & 3; // bits 0-1
int verticalOrigin = (int(gsOrigin[0]) & 12) >> 2; // bits 2-3
center.xy += (vec2(originScales[horizontalOrigin], originScales[verticalOrigin]) * halfSize);
center.xy += (gsPixelOffset[0] * og_highResolutionSnapScale);
vec4 v0 = vec4(center.xy - halfSize, 0, 1.0);
vec4 v1 = vec4(center.xy + vec2(halfSize.x, -halfSize.y), 0, 1.0);
vec4 v2 = vec4(center.xy + vec2(-halfSize.x, halfSize.y), 0, 1.0);
vec4 v3 = vec4(center.xy + halfSize, 0, 1.0);
gl_Position = og_viewportOrthographicMatrix * v0;
fsTextureCoordinates = vec2(0.0, 0.0);
EmitVertex();
gl_Position = og_viewportOrthographicMatrix * v1;
fsTextureCoordinates = vec2(1.0, 0.0);
EmitVertex();
gl_Position = og_viewportOrthographicMatrix * v2;
fsTextureCoordinates = vec2(0.0, 1.0);
EmitVertex();
gl_Position = og_viewportOrthographicMatrix * v3;
fsTextureCoordinates = vec2(1.0, 1.0);
EmitVertex();
}
//FRAGMENT SHADER
#version 330
in vec2 fsTextureCoordinates;
out vec4 fragmentColor;
uniform sampler2D og_texture0;
uniform vec3 u_color;
void main()
{
vec4 color = texture(og_texture0, fsTextureCoordinates);
if (color.a == 0.0)
{
discard;
}
fragmentColor = vec4(color.rgb * u_color.rgb, color.a);
}
To me it looks like there is some basic coordinate system confusion. I have not checked everything here, but to me,
worldViewProj = modelMatrix * viewMatrix * projectionMatrix;
looks like the wrong way round, as vertices should be multiplied from the right like
projection*view*model*vertex
The same issue is within your shaders.
Also, i am not entirely sure, but it seems you are computing pixel coordinates for gl_Position in the shader (as you are applying some viewporttransform in the function ModelToWindowCoordinates). Since pixel coordinates may e.g. range from 0,0 to 1920,1080 they are not correct for gl_Position, which should be in clip coordinates.
I think you should read up a good tutorial about 3d billboarding and the math, for example
this one looks quite interesting. Then modify the sample code to fit your needs step by step.