Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update gl.cpp #2

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
7 changes: 7 additions & 0 deletions fix.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ template <unsigned int s, typename T=int_fast32_t> class Fix
return ret;
}

static Fix<s, T> abs() {
Fix<s, T> ret;
ret.value = this->value;
if (ret > 0) return ret;
return -ret;
}

void print() const
{
char str[32];
Expand Down
79 changes: 56 additions & 23 deletions gl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@
#ifdef _TINSPIRE
#include <libndls.h>
#else
#include <SDL/SDL.h>
#include <assert.h>
#include <signal.h>
static SDL_Surface *scr;
#include <SDL.h>
#ifndef _TINSPIRE
#ifndef _WIN32
#include <signal.h> // for SDL outside of windows
#endif
#endif
static SDL_Window* sdl_window;
static SDL_Renderer* sdl_renderer;

static SDL_Texture* sdl_texture; // send to gpu
#endif

#include "gl.h"
Expand All @@ -24,11 +31,13 @@ static COLOR *screen;
static GLFix *z_buffer;
static GLFix near_plane = 256;
static const TEXTURE *texture;
static unsigned int vertices_count = 0;
static VERTEX vertices[4];
static unsigned int vertices_count = 0; // For glAddVertex calls
static VERTEX vertices[4]; // // For glAddVertex calls
static GLDrawMode draw_mode = GL_TRIANGLES;
static bool force_color = false, is_monochrome;
static COLOR *screen_inverted; //For monochrome calcs
#ifdef _TINSPIRE
static COLOR *screen_inverted; //For monochrome calcs
#endif
#ifdef FPS_COUNTER
volatile unsigned int fps;
#endif
Expand Down Expand Up @@ -62,10 +71,21 @@ void nglInit()
else
lcd_init(SCR_320x240_565);
#else
SDL_Init(SDL_INIT_VIDEO);
scr = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 16, SDL_SWSURFACE);
signal(SIGINT, SIG_DFL);
assert(scr);
SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN, &sdl_window, &sdl_renderer);

sdl_texture = SDL_CreateTexture(sdl_renderer,
SDL_PIXELFORMAT_RGB565,
SDL_TEXTUREACCESS_STREAMING,
SCREEN_WIDTH, SCREEN_HEIGHT);

SDL_SetWindowTitle(sdl_window, "nGL");

#ifndef _WIN32
signal(SIGINT, SIG_DFL);
#endif
assert(sdl_renderer);
assert(sdl_window);
assert(sdl_texture);
#endif

#ifdef SAFE_MODE
Expand All @@ -79,12 +99,15 @@ void nglUninit()
delete[] transformation;
delete[] z_buffer;

delete[] screen_inverted;
#ifdef _TINSPIRE
delete[] screen_inverted;
#endif

#ifdef _TINSPIRE
lcd_init(SCR_TYPE_INVALID);
#else
//TODO
//SDL_DestroyRenderer(sdl_renderer);
SDL_Quit();
#endif
}

Expand Down Expand Up @@ -238,10 +261,10 @@ void nglDisplay()
else
lcd_blit(screen, SCR_320x240_565);
#else
SDL_LockSurface(scr);
std::copy(screen, screen + SCREEN_HEIGHT*SCREEN_WIDTH, reinterpret_cast<COLOR*>(scr->pixels));
SDL_UnlockSurface(scr);
SDL_UpdateRect(scr, 0, 0, 0, 0);
SDL_UpdateTexture(sdl_texture, NULL, screen, SCREEN_WIDTH*sizeof(COLOR));
SDL_RenderClear(sdl_renderer);
SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL);
SDL_RenderPresent(sdl_renderer);
#endif

#ifdef FPS_COUNTER
Expand Down Expand Up @@ -354,29 +377,36 @@ GLFix nglZBufferAt(const unsigned int x, const unsigned int y)
return z_buffer[x + y * SCREEN_WIDTH];
}

constexpr GLFix ABS(GLFix a) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This belongs into fix.h, as method

return a >= GLFix(0) ? a : -a;
}

//Doesn't interpolate colors even if enabled
void nglDrawLine3D(const VERTEX *v1, const VERTEX *v2)
{
//TODO: Z-Clipping
// Z-Clipping!
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proper Z clipping would involve only drawing the part of the line which fits into the view (z between NEAR_PLANE and inf). This is currently just a band-aid to avoid a division by zero, so the //TODO comment should stay.

if(v1->z < near_plane || v2->z < near_plane)
return;

VERTEX v1_p = *v1, v2_p = *v2;
nglPerspective(&v1_p);
Vogtinator marked this conversation as resolved.
Show resolved Hide resolved
nglPerspective(&v2_p);

const GLFix diff_x = v2_p.x - v1_p.x;
const GLFix dy = (v2_p.y - v1_p.y) / diff_x;
const GLFix diff_y = v2_p.y - v1_p.y;

const COLOR c = v1_p.c;

//Height > width? -> Interpolate X
if(dy > GLFix(1) || dy < GLFix(-1))
//if(dy > GLFix(1) || dy < GLFix(-1))

// if check passes diff_y should always be non zero
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can be more confident here:

Suggested change
// if check passes diff_y should always be non zero
// if check passes, diff_y is non zero

if (ABS(diff_x) < ABS(diff_y))
{
if(v2_p.y < v1_p.y)
std::swap(v1_p, v2_p);

const GLFix diff_y = v2_p.y - v1_p.y;

const GLFix dx = (v2_p.x - v1_p.x) / diff_y;
const GLFix dx = diff_x / diff_y;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's correct to use those values after the std::swap above. The swap is there to guarantee that v1_p has a lower Y than v2_p, so you would have to change the sign of all the diff_ values as well. Otherwise drawn lines face the wrong direction.

It's easier to just always compute the diffs after the swap though - subtraction is cheap.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using diff_x / diff_y is fine here. In the case where the points have to be swapped, diff_y is negative and the division returns the correct result. It's important to not mix diffs before and after the swap though, which is the case in line 403 for instance.

const GLFix dz = (v2_p.z - v1_p.z) / diff_y;

int end_y = v2_p.y;
Expand All @@ -394,10 +424,13 @@ void nglDrawLine3D(const VERTEX *v1, const VERTEX *v2)
}
else
{
const GLFix dy = diff_x != GLFix(0) ? (diff_y / diff_x) : diff_y;

if(v2_p.x < v1_p.x)
std::swap(v1_p, v2_p);

const GLFix dz = (v2_p.z - v1_p.z) / diff_x;
// still need ternary check (for const) since diff_x could be 0
const GLFix dz = diff_x != GLFix(0) ? (v2_p.z - v1_p.z) / diff_x : (v2_p.z - v1_p.z);

int end_x = v2_p.x;

Expand Down
5 changes: 5 additions & 0 deletions triangle.inc.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
//This file will be included in gl.cpp for various different versions

#ifdef _WIN32
#define __builtin_expect(exp, c) (exp)
#endif

#ifdef TRANSPARENCY
static void nglDrawTransparentTriangleXZClipped(const VERTEX *low, const VERTEX *middle, const VERTEX *high)
{
Expand Down