mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-20 20:29:58 +01:00
Init
This commit is contained in:
commit
ee0f4f0f2c
3 changed files with 287 additions and 0 deletions
5
make.sh
Executable file
5
make.sh
Executable file
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
PROGRAM=testSDL
|
||||
|
||||
clear; clear; g++ -x c -g -fmax-errors=5 -pedantic -Wall -Wextra -o $PROGRAM $PROGRAM.c -lSDL2 2>&1 >/dev/null && ./$PROGRAM
|
196
s3l.h
Normal file
196
s3l.h
Normal file
|
@ -0,0 +1,196 @@
|
|||
#ifndef S3L_H
|
||||
#define S3L_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int16_t S3L_COORD;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
} S3L_PixelInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int16_t steps;
|
||||
int16_t err;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
|
||||
int16_t *majorCoord;
|
||||
int16_t *minorCoord;
|
||||
int16_t majorIncrement;
|
||||
int16_t minorIncrement;
|
||||
int16_t majorDiff;
|
||||
int16_t minorDiff;
|
||||
} S3L_BresenhamState;
|
||||
|
||||
static inline int16_t S3L_abs(int16_t value)
|
||||
{
|
||||
return value >= 0 ? value : -1 * value;
|
||||
}
|
||||
|
||||
void S3L_bresenhamInit(S3L_BresenhamState *state, int16_t x0, int16_t y0, int16_t x1, int16_t y1)
|
||||
{
|
||||
int16_t dx = x1 - x0;
|
||||
int16_t dy = y1 - y0;
|
||||
|
||||
int16_t absDx = S3L_abs(dx);
|
||||
int16_t absDy = S3L_abs(dy);
|
||||
|
||||
if (absDx >= absDy)
|
||||
{
|
||||
state->majorCoord = &(state->x);
|
||||
state->minorCoord = &(state->y);
|
||||
|
||||
state->minorDiff = 2 * absDy;
|
||||
state->majorDiff = 2 * absDx;
|
||||
state->err = 2 * dy - dx;
|
||||
|
||||
state->majorIncrement = dx >= 0 ? 1 : -1;
|
||||
state->minorIncrement = dy >= 0 ? 1 : -1;
|
||||
|
||||
state->steps = absDx;
|
||||
}
|
||||
else
|
||||
{
|
||||
state->majorCoord = &(state->y);
|
||||
state->minorCoord = &(state->x);
|
||||
|
||||
state->minorDiff = 2 * absDx;
|
||||
state->majorDiff = 2 * absDy;
|
||||
state->err = 2 * dx - dy;
|
||||
|
||||
state->majorIncrement = dy >= 0 ? 1 : -1;
|
||||
state->minorIncrement = dx >= 0 ? 1 : -1;
|
||||
|
||||
state->steps = absDy;
|
||||
}
|
||||
|
||||
state->x = x0;
|
||||
state->y = y0;
|
||||
}
|
||||
|
||||
int S3L_bresenhamStep(S3L_BresenhamState *state)
|
||||
{
|
||||
state->steps--;
|
||||
|
||||
(*state->majorCoord) += state->majorIncrement;
|
||||
|
||||
if (state->err > 0)
|
||||
{
|
||||
(*state->minorCoord) += state->minorIncrement;
|
||||
state->err -= state->majorDiff;
|
||||
}
|
||||
|
||||
state->err += state->minorDiff;
|
||||
|
||||
return state->steps >= 0;
|
||||
}
|
||||
|
||||
void S3L_drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2)
|
||||
{
|
||||
S3L_COORD
|
||||
tPointX, tPointY, // top triangle point coords
|
||||
lPointX, lPointY, // left triangle point coords
|
||||
rPointX, rPointY; // right triangle point coords
|
||||
|
||||
// Sort the points.
|
||||
|
||||
#define handleLR(a,b)\
|
||||
if (x##a <= x##b)\
|
||||
{\
|
||||
lPointX = x##a; lPointY = y##a;\
|
||||
rPointX = x##b; rPointY = y##b;\
|
||||
}\
|
||||
else\
|
||||
{\
|
||||
lPointX = x##b; lPointY = y##b;\
|
||||
rPointX = x##a; rPointY = y##a;\
|
||||
}
|
||||
|
||||
if (y0 <= y1)
|
||||
{
|
||||
if (y0 <= y2)
|
||||
{
|
||||
tPointX = x0;
|
||||
tPointY = y0;
|
||||
handleLR(1,2)
|
||||
}
|
||||
else
|
||||
{
|
||||
tPointX = x2;
|
||||
tPointY = y2;
|
||||
handleLR(0,1)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y1 <= y2)
|
||||
{
|
||||
tPointX = x1;
|
||||
tPointY = y1;
|
||||
handleLR(0,2)
|
||||
}
|
||||
else
|
||||
{
|
||||
tPointX = x2;
|
||||
tPointY = y2;
|
||||
handleLR(0,1)
|
||||
}
|
||||
}
|
||||
|
||||
// Now drive the triangle line by line.
|
||||
|
||||
#undef handleLR
|
||||
|
||||
S3L_COORD currentY = tPointY;
|
||||
|
||||
/* We'll be using a slight modification of Bresenham line algorithm (a one
|
||||
that draws a _non-continous_ line). */
|
||||
|
||||
#define initSide(s)\
|
||||
int16_t s##X = tPointX;\
|
||||
int16_t s##Dx = s##PointX - tPointX;\
|
||||
int16_t s##Dy = s##PointY - tPointY;\
|
||||
int16_t s##Inc = s##Dx >= 0 ? 1 : -1;\
|
||||
int16_t s##Err = 2 * s##Dx - s##Dy;\
|
||||
int16_t s##ErrAdd = 2 * S3L_abs(s##Dx);\
|
||||
int16_t s##ErrSub = 2 * S3L_abs(s##Dy);
|
||||
|
||||
#define stepSide(s)\
|
||||
while (s##Err > 0)\
|
||||
{\
|
||||
s##X += s##Inc;\
|
||||
s##Err -= s##ErrSub;\
|
||||
}\
|
||||
s##Err += s##ErrAdd;
|
||||
|
||||
initSide(r)
|
||||
initSide(l)
|
||||
|
||||
S3L_PixelInfo p;
|
||||
|
||||
while (currentY <= rPointY)
|
||||
{
|
||||
p.y = currentY;
|
||||
|
||||
for (S3L_COORD x = lX; x <= rX; ++x)
|
||||
{
|
||||
p.x = x;
|
||||
S3L_PIXEL_FUNCTION(&p);
|
||||
}
|
||||
|
||||
stepSide(r)
|
||||
stepSide(l)
|
||||
|
||||
++currentY;
|
||||
}
|
||||
|
||||
#undef initSide
|
||||
#undef stepSide
|
||||
|
||||
}
|
||||
|
||||
#endif
|
86
testSDL.c
Normal file
86
testSDL.c
Normal file
|
@ -0,0 +1,86 @@
|
|||
#include <SDL2/SDL.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
|
||||
#define S3L_PIXEL_FUNCTION drawPixel
|
||||
|
||||
#include "s3l.h"
|
||||
|
||||
#define SCREEN_WIDTH 640
|
||||
#define SCREEN_HEIGHT 480
|
||||
|
||||
uint32_t pixels[SCREEN_WIDTH * SCREEN_HEIGHT];
|
||||
|
||||
uint32_t frame = 0;
|
||||
|
||||
void clearScreen()
|
||||
{
|
||||
memset(pixels,0,SCREEN_WIDTH * SCREEN_HEIGHT * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static inline void setPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
uint32_t r = red & 0x000000FF;
|
||||
r = r << 16;
|
||||
|
||||
uint32_t g = green & 0x000000FF;
|
||||
g = g << 8;
|
||||
|
||||
uint32_t b = blue & 0x000000FF;
|
||||
|
||||
pixels[y * SCREEN_WIDTH + x] = r | g | b;
|
||||
}
|
||||
|
||||
void drawPixel(S3L_PixelInfo *p)
|
||||
{
|
||||
setPixel(p->x,p->y,255,255,0);
|
||||
}
|
||||
|
||||
void draw()
|
||||
{
|
||||
clearScreen();
|
||||
|
||||
setPixel(90,50,255,0,0);
|
||||
setPixel(100,10,255,0,0);
|
||||
setPixel(300,80,255,0,0);
|
||||
|
||||
S3L_drawTriangle(90,50,100,10,300,80);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
SDL_Window *window = SDL_CreateWindow("test", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
|
||||
SDL_Renderer *renderer = SDL_CreateRenderer(window,-1,0);
|
||||
SDL_Texture *texture = SDL_CreateTexture(renderer,SDL_PIXELFORMAT_RGBX8888, SDL_TEXTUREACCESS_STATIC, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||
SDL_Surface *screenSurface = SDL_GetWindowSurface(window);
|
||||
SDL_Event event;
|
||||
|
||||
int running = 1;
|
||||
|
||||
while (running)
|
||||
{
|
||||
draw();
|
||||
SDL_UpdateTexture(texture,NULL,pixels,SCREEN_WIDTH * sizeof(uint32_t));
|
||||
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
running = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RenderClear(renderer);
|
||||
SDL_RenderCopy(renderer,texture,NULL,NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
|
||||
frame++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue