Skip to content

Commit

Permalink
renderer: initial texture mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
Helco committed Nov 20, 2018
1 parent 41ff124 commit 9a56777
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 10 deletions.
2 changes: 1 addition & 1 deletion pcmockup/pebblewindow.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ static void prv_pebbleWindow_convertPebbleToTexture(PebbleWindow* this)
itTexPixel = (uint32_t*)texPixels;
for (int x = 0; x < this->pebbleSize.w; x++)
{
itPebblePixel = pebblePixels + x * this->pebbleSize.h + y;
itPebblePixel = pebblePixels + x * this->pebbleSize.h + (this->pebbleSize.h - 1 - y);
SDL_Color color = prv_convertGColorTo32Bit(*itPebblePixel);
*itTexPixel = SDL_MapRGBA(this->texturePixelFormat,
color.r, color.g, color.b, color.a);
Expand Down
67 changes: 61 additions & 6 deletions renderer/renderer.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Renderer* renderer_init()
this->wall.floorColor = GColorFromRGB(0, 0, 255);
this->wall.wallColor = GColorFromRGB(0, 255, 0);
this->wall.ceilColor = GColorFromRGB(255, 0, 0);
this->wall.tex = (TexCoord) { real_zero, real_from_int(3) };

this->wall2.start = xz(real_from_int(0), real_from_int(50));
this->wall2.end = xz(real_from_int(0), real_from_int(-30));
Expand All @@ -35,7 +36,7 @@ Renderer* renderer_init()
this->wall3.ceilColor = GColorFromRGB(255, 0, 0);

this->location.position = xz(real_from_int(20), real_from_int(20));
this->location.angle = real_degToRad(real_from_int(0));
this->location.angle = real_degToRad(real_from_int(90));
this->location.height = real_zero;

this->halfFov = real_degToRad(real_from_int(30));
Expand Down Expand Up @@ -128,7 +129,12 @@ void renderer_project(const Renderer* me, const Wall* wall, const lineSeg_t* tra
#undef div_and_int
}

void renderer_clipByFov(const Renderer* me, lineSeg_t* wallSeg)
real_t real_clamp(real_t min, real_t value, real_t max)
{
return real_max(min, real_min(value, max));
}

void renderer_clipByFov(const Renderer* me, lineSeg_t* wallSeg, TexCoord* texCoord)
{
xz_t leftIntersection, rightIntersection;
bool_t intersectsLeft = xz_lineIntersect(*wallSeg, me->leftFovSeg, &leftIntersection);
Expand All @@ -151,16 +157,51 @@ void renderer_clipByFov(const Renderer* me, lineSeg_t* wallSeg)
? leftIntersection
: rightIntersection;
}

real_t texCoordAmpl = real_abs(real_sub(texCoord->start, texCoord->end));
real_t texCoordStart = real_min(texCoord->start, texCoord->end);
if (real_compare(rightIntersection.z, real_zero) > 0 && inWallSegRight)
texCoord->start = real_add(real_mul(wallPhaseRight, texCoordAmpl), texCoordStart);
if (real_compare(leftIntersection.z, real_zero) > 0 && inWallSegLeft)
texCoord->end = real_add(real_mul(wallPhaseLeft, texCoordAmpl), texCoordStart);
}

typedef struct {
GColor* colors;
int width, height;
} Bild;

static const Bild* genBild()
{
static GColor pixels[64*64];
static Bild bild;
bild.width = 64;
bild.height = 64;
bild.colors = pixels;
for (int i = 0; i <64*64; i++)
{
int x = i % 64;
int y = i / 64;
int c = x ^ y;
pixels[i].r = (c >> 0) & 2;
pixels[i].g = (c >> 2) & 2;
pixels[i].b = (c >> 4) & 2;
pixels[i].a = 3;
}
return &bild;
}

void renderer_renderWall(Renderer* this, GColor* framebuffer, const Wall* wall)
{
const Bild* bild = genBild();

lineSeg_t wallSeg;
renderer_transformWall(this, wall, &wallSeg);
if (wallSeg.start.xz.z < 0 && wallSeg.end.xz.z < 0)
return;

renderer_clipByFov(this, &wallSeg);
TexCoord texCoord = wall->tex;
renderer_clipByFov(this, &wallSeg, &texCoord);

WallSection p;
renderer_project(this, wall, &wallSeg, &p);
Expand All @@ -173,11 +214,25 @@ void renderer_renderWall(Renderer* this, GColor* framebuffer, const Wall* wall)
int yCurStart = (x - p.left.x) * (p.right.yStart - p.left.yStart) / (p.right.x - p.left.x) + p.left.yStart;
int yCurEnd = (x - p.left.x) * (p.right.yEnd - p.left.yEnd) / (p.right.x - p.left.x) + p.left.yEnd;

int texCol = real_to_int(real_mul(
(x - max(0, p.left.x)) * (texCoord.end - texCoord.start) / (min(RENDERER_WIDTH - 1, p.right.x) - max(0, p.left.x) + 1) + texCoord.start,
real_from_int(bild->width)));
real_t texRow = yCurStart >= 0 ? real_zero
: real_mul(real_div(real_from_int(-yCurStart), real_from_int(yCurEnd - yCurStart)), real_from_int(bild->height));
real_t texRowIncr = real_div(real_from_int(bild->height), real_from_int(yCurEnd - yCurStart + 1));

int y;
for (y = 0; y < max(0, yCurStart); y++)
*(curPixel++) = wall->floorColor;
for (; y <= min(RENDERER_HEIGHT - 1, yCurEnd); y++)
*(curPixel++) = wall->wallColor;
{
int texRowI = real_to_int(texRow);
*(curPixel++) = bild->colors[
(texRowI % bild->height) * bild->width +
(texCol % bild->width)
];
texRow += texRowIncr;
}
for (; y < RENDERER_HEIGHT; y++)
*(curPixel++) = wall->ceilColor;
}
Expand All @@ -193,8 +248,8 @@ void renderer_render(Renderer* renderer, GColor* framebuffer)
{
memset(framebuffer, 0, RENDERER_WIDTH * RENDERER_HEIGHT);
renderer_renderWall(renderer, framebuffer, &renderer->wall);
renderer_renderWall(renderer, framebuffer, &renderer->wall2);
renderer_renderWall(renderer, framebuffer, &renderer->wall3);
//renderer_renderWall(renderer, framebuffer, &renderer->wall2);
//renderer_renderWall(renderer, framebuffer, &renderer->wall3);
};

void renderer_rotateRight(Renderer* renderer)
Expand Down
60 changes: 57 additions & 3 deletions renderer/renderer_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@

int renderer_getDebugCount(Renderer* renderer)
{
return 2;
return 3;
}

const char* renderer_getDebugName(Renderer* renderer, int index)
{
if (index < 0 || index > 1)
if (index < 0 || index > 2)
return "";
static const char* const NAMES[] = {
"world-space",
"player-space"
"player-space",
"texture"
};
return NAMES[index];
}
Expand Down Expand Up @@ -61,8 +62,59 @@ xz_t angleToVector(real_t angle, real_t length)
), length);
}

typedef struct {
GColor* colors;
int width, height;
} Bild;

static const Bild* genBild()
{
static GColor pixels[64*64];
static Bild bild;
bild.width = 64;
bild.height = 64;
bild.colors = pixels;
for (int i = 0; i <64*64; i++)
{
int x = i % 64;
int y = i / 64;
int c = x ^ y;
pixels[i].r = (c >> 0) & 2;
pixels[i].g = (c >> 2) & 2;
pixels[i].b = (c >> 4) & 2;
pixels[i].a = 3;
}
return &bild;
}

void renderer_renderDebugTexture(Renderer* me, const DebugInfo* debug)
{
const int pxsize = 8;
const Bild* bild = genBild();
for (int i = 0; i <bild->width * bild->height; i++)
{
int tx = i % bild->width;
int ty = i / bild->width;
int px = tx * pxsize + real_to_int(debug->offset.x);
int py = ty * pxsize + real_to_int(debug->offset.z);
SDL_Rect rct = { px, py, pxsize, pxsize };

GColor c = bild->colors[i];
const int c2bt8b = (255 / 3);
SDL_SetRenderDrawColor(debug->ren,
c.r * c2bt8b, c.g * c2bt8b, c.b * c2bt8b, c.a * c2bt8b
);
SDL_RenderFillRect(debug->ren, &rct);
}
}

void renderer_renderDebug(Renderer* me, const DebugInfo* debug)
{
if (debug->index == 2)
{
renderer_renderDebugTexture(me, debug);
return;
}
const Wall* walls[] = {
&me->wall,
&me->wall2,
Expand All @@ -89,6 +141,8 @@ void renderer_renderDebug(Renderer* me, const DebugInfo* debug)
renderer_renderDebugLine(me, debug, fovLine);
fovLine.end.xz = xz_add(me->location.position, angleToVector(me->location.angle - me->halfFov, 70));
renderer_renderDebugLine(me, debug, fovLine);


}

#endif
6 changes: 6 additions & 0 deletions renderer/renderer_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
#define RENDERER_INTERNAL_H
#include "renderer.h"

typedef struct TexCoord
{
real_t start, end;
} TexCoord;

typedef struct Wall
{
xz_t start, end;
TexCoord tex;
real_t height, heightOffset;
GColor wallColor, floorColor, ceilColor;
} Wall;
Expand Down

0 comments on commit 9a56777

Please sign in to comment.