I'm currently writing a software renderer. I managed to implement texture mapping and it works fine. Only issue is, that the edges between the pixels are sometimes jagged in x direction as you can see here:
Could this be caused by a lack of precision? If so, how can I improve it? What I'm doing is simply stepping along the edges of a triangle and interpolating the UVs for each scanline.
EDIT: Here's my code for edge stepping and drawing of scanlines. The Edge class has a method step which increments the interpolants for each scanline.
edge.h
Edge(const Vertex& minY, const Vertex& maxY){
float dy = maxY.position.y - minY.position.y;
yStart = static_cast<int>(ceil(minY.position.y));
yEnd = static_cast<int>(ceil(maxY.position.y));
float prestep = yStart - minY.position.y;
xStep = (maxY.position.x - minY.position.x) / dy;
x = minY.position.x + xStep * prestep;
wStep = (1.0f / maxY.position.w - 1.0f / minY.position.w) / dy;
w = 1.0f / minY.position.w + wStep * prestep;
texCoordsStep = (maxY.textureCoordinates / maxY.position.w - minY.textureCoordinates / minY.position.w) / dy;
texCoords = minY.textureCoordinates / minY.position.w + texCoordsStep * prestep;
}
renderTarget.cpp
void RenderTarget::DrawScanLine(const Edge& left, const Edge& right, int y){
int xStart = static_cast<int>(ceil(left.GetCurX()));
int xEnd = static_cast<int>(ceil(right.GetCurX()));
float dx = static_cast<float>(xEnd - xStart);
float prestep = xStart - left.GetCurX();
float w = left.GetCurW();
float wStep = (right.GetCurW() - w) / dx;
glm::vec2 texCoordsStep = (right.GetCurTexCoords() - left.GetCurTexCoords()) / dx;
glm::vec2 texCoords = left.GetCurTexCoords() + texCoordsStep * prestep;
Uint32* p = pixels + xStart + y * surface->w;
for(int x = xStart; x < xEnd; x++){
float z = 1.0f / w; //value for perspective correction
int s = static_cast<int>(texCoords.s * z * texture->surface->w) & texture->surface->w - 1;
int t = static_cast<int>(texCoords.t * z * texture->surface->h) & texture->surface->h - 1;
*p = texture->pixels[s + t * texture->surface->w]; //copying the texture's pixel to the framebuffer
p++;
w += wStep;
texCoords += texCoordsStep;
color += colorStep;
}
}