So an update I went and got my old ATI HD6950 just to se if I could narrow this down to what the actual problem is. And this is what I have found out this far:
- The drivers does NOT crash with ATI HD4870.
- The driver crash when sf::Window::display() is being called. Not allways, only after that the following code has run:
float time = static_cast<float>(mTimer.restart().asMilliseconds()) / 10.f;
std::vector<parallaxTexture*> positionSorted;
int viewX = MathHelper::getViewOffset().x;
float deltaX = (viewX - mOldX + (mAlwaysDeltaX * time)) * mDepthMultiplier + (mAlwaysDeltaX * time);
//first place the position of the layer tiles
size_t leftmost = 0;
for (size_t i = 0; i < pTextures.size(); ++i)
{
pTextures[i].position = sf::Vector2f(pTextures[i].position.x + deltaX * mScale.x, pTextures[i].position.y);
float left = pTextures[i].position.x;
float viewRight = viewX + mDisplay->GetWindow()->getView().getSize().x;
float moveX = pTextures.size() * mDesiredSize.x;
float right = pTextures[i].position.x + mDesiredSize.x;
float viewLeft = viewX;
if (left > viewRight && (deltaX > 0 || mOldX > (viewX - deltaX)))
{
pTextures[i].position = sf::Vector2f(pTextures[i].position.x - moveX, pTextures[i].position.y);
pTextures[i].effects.doReset();
}
else if (right < viewLeft && (deltaX < 0 || mOldX < (viewX - deltaX)))
{
pTextures[i].position = sf::Vector2f(pTextures[i].position.x + moveX, pTextures[i].position.y);
pTextures[i].effects.doReset();
}
//push the sprite into a new vector that will be sorted.
positionSorted.push_back(&pTextures[i]);
}
//sort the positionSorted vector (this sorts the sprites by position, with the left most being at the first position)
std::sort(positionSorted.begin(), positionSorted.end(), sortByPosition);
sf::FloatRect window(MathHelper::getViewOffset().x, MathHelper::getViewOffset().y, 1600, 900);
//new code, doesn't work yet, waiting for fix.
sf::VertexArray vArray(sf::Quads);
for (size_t i = 0; i < positionSorted.size(); ++i)
{
sf::Vector2f position((positionSorted.front()->position.x) + (mTexture->getSize().x * i * mScale.x), positionSorted[i]->position.y);
sf::FloatRect spriteRect((position.x), (position.y), mDesiredSize.x, mDesiredSize.y);
sf::FloatRect intersection;
if (window.intersects(spriteRect, intersection))
{
intersection.top = position.y;
sf::FloatRect textureRect;
textureRect.top = 0;
textureRect.height = mTexture->getSize().y;
if (position.x - window.left < 0)
{
textureRect.left = MathHelper::getInRangeFloat(-(position.x - window.left) / mScale.x, mTexture->getSize().x);
textureRect.width = intersection.width / mScale.x;
}
else
{
textureRect.left = MathHelper::getInRange(0 , mTexture->getSize().x);
textureRect.width = intersection.width / mScale.x;
}
vArray.append(
sf::Vertex(
sf::Vector2f(intersection.left, intersection.top),
sf::Vector2f(textureRect.left, textureRect.top)
));
vArray.append(
sf::Vertex(
sf::Vector2f(intersection.left + intersection.width, intersection.top),
sf::Vector2f(textureRect.left + textureRect.width, textureRect.top)
));
vArray.append(
sf::Vertex(
sf::Vector2f(intersection.left + intersection.width, intersection.top + intersection.height),
sf::Vector2f(textureRect.left + textureRect.width, textureRect.top + textureRect.height)
));
vArray.append(
sf::Vertex(
sf::Vector2f(intersection.left, intersection.top + intersection.height),
sf::Vector2f(textureRect.left, textureRect.top + textureRect.height)
));
positionSorted[i]->effects.render(*canvas, mLayer+1, positionSorted[i]->position);
}
}
sf::RenderStates state;
state.shader = mShader;
state.texture = mTexture;
canvas->addVertexArray(vArray, state, mLayer+1);
mOldX = viewX;
And yes, it is the latest available drivers
EDIT: This is the only place in the whole game that uses sf::VertexArray might have something to do with that?
EDIT2: Tried the only game I have installed that I know uses OpenGL, Amnesia.. And it does not crash the drivers
So yea you are right, it is a shader problem.
So yea here is our vertex shader:
//Vertex Program
void main( void )
{
// transform the vertex position
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// transform the texture coordinates
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
// forward the vertex color
gl_FrontColor = gl_Color;
}
And then we have 3 difrent shader fragment shaders depending on how much we scale the textures.
//Fragment Program
uniform sampler2D texture;
void main (void)
{
vec4 textColor = texture2D( texture, gl_TexCoord[0].st);
gl_FragColor = textColor;
}
The last shader does the exact same thing as this one just another 10times or so..
//Fragment Program
uniform sampler2D texture;
uniform vec2 texelSize;
void main (void)
{
vec4 textColor;
textColor += texture2D( texture, gl_TexCoord[0].st + vec2(0.0 * texelSize.x, 0.0 * texelSize.y)) * 0.2;
textColor += texture2D( texture, gl_TexCoord[0].st + vec2(-1.0 * texelSize.x, -1.0 * texelSize.y)) * 0.125;
textColor += texture2D( texture, gl_TexCoord[0].st + vec2(1.0 * texelSize.x, -1.0 * texelSize.y)) * 0.125;
textColor += texture2D( texture, gl_TexCoord[0].st + vec2(-1.0 * texelSize.x, 1.0 * texelSize.y)) * 0.125;
textColor += texture2D( texture, gl_TexCoord[0].st + vec2(1.0 * texelSize.x, 1.0 * texelSize.y)) * 0.125;
textColor += texture2D( texture, gl_TexCoord[0].st + vec2(0.0 * texelSize.x, -1.0 * texelSize.y)) * 0.125;
textColor += texture2D( texture, gl_TexCoord[0].st + vec2(1.0 * texelSize.x, 0.0 * texelSize.y)) * 0.125;
textColor += texture2D( texture, gl_TexCoord[0].st + vec2(-1.0 * texelSize.x, 0.0 * texelSize.y)) * 0.125;
textColor += texture2D( texture, gl_TexCoord[0].st + vec2(1.0 * texelSize.x, 0.0 * texelSize.y)) * 0.125;
gl_FragColor = textColor;
}
If I comment out "state.shader = mShader;" it runs ok and doesnt crash how ever if I set it to load any of the above fragment shader it crashes
EDIT: I'll just update with the code loading the shader incase that is the problem.
Also, have tested the shader in RenderMonkey.. works fine there without any warnings
mShader = new sf::Shader();
mShader->loadFromFile("filtering.vert", sf::Shader::Type::Vertex);
float totalScale = (mScale.x + mScale.y) / 2;
if (totalScale < 1.1f)
{
mShader->loadFromFile("filtering_0.frag", sf::Shader::Type::Fragment);
}
else if (totalScale < 2.1f)
{
mShader->loadFromFile("filtering_1.frag", sf::Shader::Type::Fragment);
mShader->setParameter("texelSize", mTexelSize);
}
else
{
mShader->loadFromFile("filtering_2.frag", sf::Shader::Type::Fragment);
mShader->setParameter("texelSize", mTexelSize);
}
mShader->setParameter("texture", *mTexture);
LAST EDIT: I updated SFML to the nightly build I found on eXpl0it3r's homepage and now it works..
So I have actually no idea what was wrong :)
Thx expl0it3r!
link if you have same problem: http://sfml.my-gate.net/nightly/ (http://sfml.my-gate.net/nightly/)