Colors are inverted after creating my own vector class?

Started by
1 comment, last by PhillipClark 12 years, 8 months ago
My title says it all. I didn't change my original code at all. I only replaced the D3DXVECTOR3 class with my vec4 class. The colors of my primitives became incorect, and I am at a loss as to why.

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()));
}
}
Advertisement
I don't ever use DirectX, but just a general observation: you are attempting to replace a 3-float vector type with a 4-float vector type. Is this really what you want to do, and have you adjusted your code to take this into account accordingly?

Edit: Specifically, you may need to adjust your vertex layouts. I Googled DXGI_FORMAT which lists an alternative[font="Consolas, Courier, monospace"] of [/font][font="Consolas, Courier, monospace"]DXGI_FORMAT_R32G32B32A32_FLOAT[/font][font="Consolas, Courier, monospace"] that might be more appropriate in place of [/font][font="CourierNew, monospace"]DXGI_FORMAT_R32G32B32_FLOAT[/font][font="Consolas, Courier, monospace"] in your vertex layout declaration. Having an incorrect value describing the layout of your data could be providing an offset error.[/font]
I have the constructor default the z and alpha values if they are not inputted, so it should be able to support 2, 3, and 4D vectors in that sense. Maybe. O.o I'm probably wrong here.

[EDIT]
In response to your [EDIT]: That was one of the things I was thinking about, but I had no clue how to go about it. Thanks for the clarification. I'm a real noob when it comes to the format stuff.

It is now working correctly! Thank you!

This topic is closed to new replies.

Advertisement