Obviously there must be an error in my vec4 class, right? I cannot seem find it, if there is one, so I was wondering if anyone here would like to take a look?
My program displays a simple animated box, but it's supposed to be blue, not red!
I have narrowed the problem down a little and it seems it is happening when I replace "D3DXVECTOR3" in my vertex list with "vec4" for the position. My replacement color vector for D3DXCOLOR works properly.
[size="4"]vec4.h
#ifndef VEC4_H
#define VEC4_H
class vec4
{
float x, y, z, alpha;
public:
vec4( const float& xCoord, const float& yCoord, const float& zCoord = 0.0f, const float& alphaVal = 1.0f );
vec4( const vec4& v );
vec4& operator=( const vec4& v );
~vec4();
float getX();
void setX( const float& xCoord );
float getY();
void setY( const float& yCoord );
float getZ();
void setZ( const float& zCoord );
float getAlpha();
void setAlpha( const float& alphaVal );
void scalarMult( const float& s );
vec4 operator+( const vec4& v )const;
};
#endif
[size="4"]vec4.cpp
#ifndef VEC4_CPP
#define VEC4_CPP
#include "vec4.h"
vec4::vec4( const float& xCoord, const float& yCoord, const float& zCoord, const float& alphaVal )
{
x = xCoord;
y = yCoord;
z = zCoord;
alpha = alphaVal;
}
vec4::vec4( const vec4& v )
{
x = v.x;
y = v.y;
z = v.z;
alpha = v.alpha;
}
vec4& vec4::operator=( const vec4& v )
{
x = v.x;
y = v.y;
z = v.z;
alpha = v.alpha;
return *this;
}
vec4::~vec4()
{
}
float vec4::getX()
{
return x;
}
void vec4::setX( const float& xCoord )
{
x = xCoord;
}
float vec4::getY()
{
return y;
}
void vec4::setY( const float& yCoord )
{
y = yCoord;
}
float vec4::getZ()
{
return z;
}
void vec4::setZ( const float& zCoord )
{
z = zCoord;
}
float vec4::getAlpha()
{
return alpha;
}
void vec4::setAlpha( const float& alphaVal )
{
alpha = alphaVal;
}
void vec4::scalarMult( const float& s )
{
x = x*s;
y = y*s;
z = z*s;
}
vec4 vec4::operator+( const vec4& v )const
{
return vec4( x + v.x, y + v.y, z + v.z );
}
#endif
[size="4"]d3d.h
#ifndef D3D_H
#define D3D_H
#include <D3D10.h>
#include <D3DX10.h>
#include "vec4.h"
#pragma comment (lib, "d3d10.lib")
#pragma comment (lib, "d3dx10.lib")
struct VERTEX
{
vec4 Position;
vec4 Color;
};
class D3D
{
int w, h; // width, height of window
ID3D10Device* dev;
IDXGISwapChain* sc;
ID3D10RenderTargetView* rtv;
ID3D10Buffer* pBuff;
ID3D10Buffer* pIndexBuff;
ID3D10Effect* pEff;
ID3D10EffectTechnique* pTech;
ID3D10EffectPass* pPass;
ID3D10InputLayout* pLayout;
ID3D10EffectScalarVariable* pVariable;
public:
D3D( int width, int height );
void init( HWND hwnd );
void pipe();
void geo();
void render_frame();
void clean();
};
#endif
[size="4"]d3d.cpp
#include "d3d.h"
D3D::D3D( int width, int height )
{
w = width;
h = height;
}
//################################################################################################
void D3D::init( HWND hwnd )
{
DXGI_SWAP_CHAIN_DESC scd;
scd.BufferCount = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferDesc.Height = h;
scd.BufferDesc.RefreshRate.Denominator = 1;
scd.BufferDesc.RefreshRate.Numerator = 60;
scd.BufferDesc.Scaling = DXGI_MODE_SCALING_CENTERED;
scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_PROGRESSIVE;
scd.BufferDesc.Width = w;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
scd.OutputWindow = hwnd;
scd.SampleDesc.Count = 1;
scd.SampleDesc.Quality = 0;
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
scd.Windowed = true;
D3D10CreateDeviceAndSwapChain( NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, NULL, D3D10_SDK_VERSION, &scd, &sc, &dev );
ID3D10Texture2D* pBackBuffer;
sc->GetBuffer( 0, __uuidof( ID3D10Texture2D ), ( LPVOID* )&pBackBuffer );
dev->CreateRenderTargetView( pBackBuffer, NULL, &rtv );
pBackBuffer->Release();
dev->OMSetRenderTargets( 1, &rtv, NULL );
D3D10_VIEWPORT viewport;
viewport.Height = h;
viewport.MaxDepth = 0;
viewport.MinDepth = 0;
viewport.TopLeftX = 0;
viewport.TopLeftY = 0;
viewport.Width = w;
dev->RSSetViewports( 1, &viewport );
}
//################################################################################################
void D3D::geo()
{
VERTEX vvertices[] =
{
// position // color
{ vec4( -0.8f, -0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ vec4( -0.8f, 0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ vec4( 0.8f, 0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ vec4( -0.8f, -0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ vec4( 0.8f, 0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) },
{ vec4( 0.8f, -0.8f, 0.0f ), vec4( 0.0f, 0.0f, 1.0f, 1.0f ) }
};
D3D10_BUFFER_DESC vbd;
vbd.BindFlags = D3D10_BIND_VERTEX_BUFFER;
vbd.ByteWidth = sizeof( VERTEX ) * 6;
vbd.CPUAccessFlags = NULL;
vbd.MiscFlags = NULL;
vbd.Usage = D3D10_USAGE_IMMUTABLE;
D3D10_SUBRESOURCE_DATA vinitData;
vinitData.pSysMem = vvertices;
dev->CreateBuffer( &vbd, &vinitData, &pBuff );
int ivertices[6] = {
0, 1, 2,
0, 4, 5
};
D3D10_BUFFER_DESC ibd;
ibd.BindFlags = D3D10_BIND_INDEX_BUFFER;
ibd.ByteWidth = sizeof( int ) * 6;
ibd.CPUAccessFlags = NULL;
ibd.MiscFlags = NULL;
ibd.Usage = D3D10_USAGE_IMMUTABLE;
D3D10_SUBRESOURCE_DATA iinitData;
iinitData.pSysMem = ivertices;
dev->CreateBuffer( &ibd, &iinitData, &pIndexBuff );
// use if not immutable
//void* pVoid;
//pBuff->Map( D3D10_MAP_WRITE_DISCARD, NULL, &pVoid );
//memcpy( pVoid, vertices, sizeof( vertices ) );
//pBuff->Unmap();
}
//################################################################################################
void D3D::pipe()
{
D3D10_PASS_DESC passdesc;
D3DX10CreateEffectFromFile( "effect.fx", NULL, NULL, "fx_4_0", NULL, NULL, dev, NULL, NULL, &pEff, NULL, NULL );
pTech = pEff->GetTechniqueByIndex( 0 );
pPass = pTech->GetPassByIndex( 0 );
pPass->GetDesc( &passdesc );
D3D10_INPUT_ELEMENT_DESC layout[2];
layout[0].AlignedByteOffset = D3D10_APPEND_ALIGNED_ELEMENT;
layout[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
layout[0].InputSlot = 0;
layout[0].InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA;
layout[0].InstanceDataStepRate = 0;
layout[0].SemanticIndex = 0;
layout[0].SemanticName = "POSITION";
layout[1].AlignedByteOffset = D3D10_APPEND_ALIGNED_ELEMENT;
layout[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;
layout[1].InputSlot = 0;
layout[1].InputSlotClass = D3D10_INPUT_PER_VERTEX_DATA;
layout[1].InstanceDataStepRate = 0;
layout[1].SemanticIndex = 0;
layout[1].SemanticName = "COLOR";
dev->CreateInputLayout( layout, 2, passdesc.pIAInputSignature, passdesc.IAInputSignatureSize, &pLayout );
pVariable = pEff->GetVariableByName( "timeVar" )->AsScalar();
}
//################################################################################################
void D3D::render_frame()
{
FLOAT color[4] = { 1.0f, 1.0f, 1.0f, 1.0f };
dev->ClearRenderTargetView( rtv, color );
dev->IASetInputLayout( pLayout );
dev->IASetPrimitiveTopology( D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST );
UINT stride = sizeof( VERTEX );
UINT offset = 0;
static float time = 0.0f;
time += 0.0001f;
dev->IASetVertexBuffers( 0, 1, &pBuff, &stride, & offset );
dev->IASetIndexBuffer( pIndexBuff, DXGI_FORMAT_R32_UINT, 0 );
pVariable->SetFloat( time );
pPass->Apply( NULL );
dev->DrawIndexed( 6, 0, 0 );
sc->Present( NULL, NULL );
}
//################################################################################################
void D3D::clean()
{
if( pLayout )
pLayout->Release();
if( pEff )
pEff->Release();
if( pBuff )
pBuff->Release();
if( rtv )
rtv->Release();
if( dev )
dev->Release();
if( sc )
sc->Release();
}
[size="4"]effect.fx
float timeVar;
// a struct for the vertex shader return value
struct VSOut
{
float4 Col : COLOR; // vertex color
float4 Pos : SV_POSITION; // vertex screen coordinates
};
// the vertex shader
VSOut VS(float4 Col : COLOR, float4 Pos : POSITION)
{
VSOut Output;
Output.Pos = Pos; // set the vertex position to the input's position
Output.Pos.x *= sin( timeVar ); // shrink the vertex on the x-axis
Output.Pos.y *= sin( timeVar );
Output.Col = Col; // set the vertex color to the input's color
return Output; // send the modified vertex data to the Rasterizer Stage
}
// the pixel shader
float4 PS(float4 Col : COLOR) : SV_TARGET
{
return Col; // set the pixel color to the color passed in by the Rasterizer Stage
}
// the primary technique
technique10 Technique_0
{
// the primary pass
pass Pass_0
{
SetVertexShader(CompileShader(vs_4_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0, PS()));
}
}