Skip to content

Instantly share code, notes, and snippets.

@iodiot
Created October 4, 2012 13:17
Show Gist options
  • Save iodiot/3833466 to your computer and use it in GitHub Desktop.
Save iodiot/3833466 to your computer and use it in GitHub Desktop.
void Renderer::RenderWall(Vector2 v1, Vector2 v2, TileType::e tile, double texCoord1, double texCoord2)
{
if (tile == TileType::None) return;
static const double zClip = 0.2;
static const double eps = 0.000001;
uint tint = core->level->GetTileTint(TexType::Walls, tile);
// Obscure walls parallel to OX
bool side = fabs((v2 - v1).y) >= eps;
if (!side)
tint = Color::FastChannelsMul(tint, 0.7);
// Translate input vectors into view frame
v1 -= cameraPosition;
v2 -= cameraPosition;
// Rotate input vectors
v1.Rotate(cameraRotation);
v2.Rotate(cameraRotation);
double x1 = v1.x;
double z1 = v1.y;
double x2 = v2.x;
double z2 = v2.y;
// Near plane clipping
if (z1 < zClip && z2 < zClip) return;
if (z1 < zClip) {
double p = (zClip - z1) / (z2 - z1);
z1 = zClip;
x1 = x1 + (x2 - x1) * p;
texCoord1 = texCoord1 + (texCoord2 - texCoord1) * p;
}
if (z2 < zClip) {
double p = (zClip - z1) / (z2 - z1);
z2 = zClip;
x2 = x1 + (x2 - x1) * p;
texCoord2 = texCoord1 + (texCoord2 - texCoord1) * p;
}
// Projection
int startX = width / 2 - int(nearPlaneDistance * x1 / z1);
int endX = width / 2 - int(nearPlaneDistance * x2 / z2);
if (startX >= endX) return;
int lineHeight1 = int(fabs(double(height) / z1));
int lineHeight2 = int(fabs(double(height) / z2));
int dx = endX - startX;
for (int x = max(0, startX); x < min(width, endX); ++x)
{
double d = double(x - startX) / double(dx);
double texModifier = 1.0 / z1 + (1.0 / z2 - 1.0 / z1) * d;
// Depth test
double lineDepth = z1 + d * (z2 - z1);
if (zBuffer[x] > lineDepth)
zBuffer[x] = lineDepth;
else
continue;
// Interpolate line height
int lineHeight = int(lineHeight1 + d * (lineHeight2 - lineHeight1));
int startY = height / 2 - lineHeight / 2 + cameraShift;
int endY = height / 2 + lineHeight / 2 + cameraShift;
int dy = endY - startY;
// Interpolate tex coord
double texCoord = (texCoord1 / z1 + d * (texCoord2 / z2 - texCoord1 / z1)) / texModifier;
int texX = int(texCoord * double(Consts::TileSize));
for (int y = max(0, startY); y < min(height, endY); ++y)
{
int texY = int(double(y - startY) / double(dy) * double(Consts::TileSize));
PixelShader(buffer[x + y * width], GetTexel(core->art->walls, tile, texX, texY), lineDepth, tint);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment