Inexplicable error

Started by
18 comments, last by L. Spiro 12 years, 6 months ago
Hi, me again, this time with the weirdest error I have ever encountered.
Here's the code


struct Button
{
std::string text;
gml::Vector2 position;
Button(std::string t, gml::Vector2 pos) : text(t), position(pos) {}
};
class MainMenuControl : GameObject
{
std::vector<Button> buttons;
Font* font;
public:
void Create(Scene* scene)
{
font = new Font(scene->pGraphics);
font->Load("Arial Black", 32);
buttons.push_back(Button("Start Game", gml::Vector2(100, 100)));
buttons.push_back(Button("Options", gml::Vector2(100, 132)));
buttons.push_back(Button("Exit", gml::Vector2(100, 164)));
}
void Update(Scene* scene)
{
}
void Render(Scene* scene)
{
gml::Matrix view = gml::Matrix::CreateLookAt(gml::Vector3(512, 288, 10), gml::Vector3(512, 288, 0), gml::Vector3(0, 1, 0));
gml::Matrix proj = gml::Matrix::CreateOrtho(-512, 512, -288, 288, 1, 1024);
gml::Matrix world;

for (int i = 0; i < buttons.size(); i++)
{
world = gml::Matrix::CreateTranslation(buttons.position.x, buttons.position.z, 0);
font->DrawString(buttons.text, world * view * proj);
}
}
void Destroy(Scene* scene)
{
delete font;
}
};


Here's the effect file, loaded as an ID3DXEffect and used by Font::DrawString

float4x4 WorldViewProj;
sampler TexSamp : register(s0) = sampler_state { MinFilter = Point; MagFilter = Point; MipFilter = None; };

void VertexShaderFunc(in float3 iPos : POSITION0, in float2 iTex : TEXCOORD0,
out float4 oPos : POSITION0, out float2 oTex : TEXCOORD0)
{
oPos = mul(float4(iPos.xyz, 1), WorldViewProj);
oTex = iTex;
}
void PixelShaderFunc(in float2 iTex : TEXCOORD0,
out float4 oCol : COLOR0)
{
oCol = tex2D(TexSamp, iTex);
}

technique t0
{
pass p0
{
VertexShader = compile vs_2_0 VertexShaderFunc();
PixelShader = compile ps_2_0 PixelShaderFunc();
AlphaBlendEnable = true;
SrcBlend = SrcAlpha;
DestBlend = InvSrcAlpha;
}
}


And here's the result. (attached as PNG)
[attachment=5807:Capture.PNG]
How on earth is this happening? The "Options" and "Exit" buttons clearly have larger Y-coordinates than "Start Game"!
I have tested and tested and tested all my matrix creation functions, (the same thing happens with D3DXMATRIX).
Font is my own implementation, I will post it up if required.
Advertisement
Having the origin (0,0) be in the lower left rather than the upper left of the screen is quite common. It's all in how your projection matrix is created.
I wrote the code that created the projection matrix, and I know 3D math. Trust me, this is not the problem. If you look at the order in which the buttons are inserted into the list, this could still not explain the order in which they are appearing onscreen.

I think the problem could be in the replacement of the worldViewProj matrix in the effect/vertex shader constants, but I don't know about how this works.
What does the gml::Vector2 implementation look like?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

I looked at the constructor for that, no luck
gml::Vector2


struct Vector2
{
float x;
float y;

Vector2();
Vector2(Vector2& v);
Vector2(float _x, float _y);

Vector2 operator+(Vector2& v);
Vector2 operator-(Vector2& v);
Vector2 operator*(Vector2& v);
Vector2 operator*(float f);
Vector2 operator/(Vector2& v);
Vector2 operator/(float f);

Vector2 operator+=(Vector2& v);
Vector2 operator-=(Vector2& v);
Vector2 operator*=(Vector2& v);
Vector2 operator*=(float f);
Vector2 operator/=(Vector2& v);
Vector2 operator/=(float f);

float Length();
float LengthSquared();
Vector2 Lerp(Vector2& v, float f);
void Normalize();
};




Vector2::Vector2()
{
x = 0;
y = 0;
}
Vector2::Vector2(Vector2& v)
{
x = v.x;
y = v.y;
}
Vector2::Vector2(float _x, float _y)
{
x = _x;
y = _y;
}
//
Vector2 Vector2::operator+(Vector2& v)
{
return Vector2(x + v.x, y + v.y);
}
Vector2 Vector2::operator-(Vector2& v)
{
return Vector2(x - v.x, y - v.y);
}
Vector2 Vector2::operator*(Vector2& v)
{
return Vector2(x * v.x, y * v.y);
}
Vector2 Vector2::operator*(float f)
{
return Vector2(x * f, y * f);
}
Vector2 Vector2::operator/(Vector2& v)
{
return Vector2(x / v.x, y / v.y);
}
Vector2 Vector2::operator/(float f)
{
return Vector2(x / f, y / f);
}
//
Vector2 Vector2::operator+=(Vector2& v)
{
x += v.x;
y += v.y;
return *this;
}
Vector2 Vector2::operator-=(Vector2& v)
{
x -= v.x;
y -= v.y;
return *this;
}
Vector2 Vector2::operator*=(Vector2& v)
{
x *= v.x;
y *= v.y;
return *this;
}
Vector2 Vector2::operator*=(float f)
{
x *= f;
y *= f;
return *this;
}
Vector2 Vector2::operator/=(Vector2& v)
{
x /= v.x;
y /= v.y;
return *this;
}
Vector2 Vector2::operator/=(float f)
{
x /= f;
y /= f;
return *this;
}
//
float Vector2::Length()
{
return sqrtf(x*x+y*y);
}
float Vector2::LengthSquared()
{
return x*x + y*y;
}
Vector2 Vector2::Lerp(Vector2& v, float f)
{
return Vector2(x+(v.x-x)*f, y+(v.y-y)*f);
}
void Vector2::Normalize()
{
float l = Length();
x /= l;
y /= l;
}


All implementations present and correct. Perhaps not as fast as assembly or SSE2 or whatever it is the hardcore people use, but all working.
Something doesn't add up. You refer to buttons.position.z in your Render() code, but Vector2 doesn't even have a member called z.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Eh?
My bad, that should be y. It was just a typo. Same result with it fixed.
I assume you've run under a debugger and confirmed that (1) the numbers in the list are correct and (2) the numbers produced by your matrix math are correct?

Have you stripped the code down to a minimal example that reproduces the problem? Alternatively, can you reproduce this kind of error in any other situations?


[edit] And maybe at the risk of probing a bit too hard - since the code you posted is definitely not the code you're running (it shouldn't even compile with z instead of y), are you absolutely sure that there are no other differences between what you're actually running and what is posted?

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Easiest thing would be to try adding more buttons, or changing their positions, to see how that affects the layout.
[Window Detective] - Windows UI spy utility for programmers
Explicitly define the = operator for your Button structure.
A sneaky suspicious tells me that will solve all of your problems and remove your invalid-access waiting to happen.


L. Spiro

I restore Nintendo 64 video-game OST’s into HD! https://www.youtube.com/channel/UCCtX_wedtZ5BoyQBXEhnVZw/playlists?view=1&sort=lad&flow=grid

This topic is closed to new replies.

Advertisement