diff --git a/src/nogl/noGLALSW.inc b/src/nogl/noGLALSW.inc
index 60b207228bcd321fc1c9848af9cb9a78e847f7fe..55ee112fe1bfbd05dfcd820cefca48fd799b9f34 100644 (file)
--- a/src/nogl/noGLALSW.inc
+++ b/src/nogl/noGLALSW.inc
const
ValPerVertex = 2;
- ValPerColor = 4;
+ ValPerColor = 1; (* colors stored in one integer *)
ValPerCoord = 2;
+ StackSize = 16;
type
- TArrayFloat = array of Integer;
+ TArrayFloat = array of GLfloat;
+ TArrayInteger = array of Integer;
TCmds = record
mode: GLenum;
- v, c, t: TArrayFloat;
+ v: TArrayInteger;
+ c: TArrayInteger;
+ t: TArrayFloat;
end;
TArrayTexture = array of record
tex: TArrayTexture;
ctex: Integer;
ccol: Integer;
+ clearColor: cint;
+ stack: array [0..StackSize - 1] of record
+ x, y: Integer;
+ end;
+ stack_ptr: Integer;
function AddTexture: Integer;
var i: Integer;
assert(tex[i].used);
tex[i].used := false;
if tex[i].bmp <> nil then
- destroy_bitmap(tex[i].bmp)
+ destroy_bitmap(tex[i].bmp);
+ tex[i].bmp := nil
end;
- procedure Add (var x: TArrayFloat; f: Integer);
+ procedure Addi (var x: TArrayInteger; f: Integer);
+ var i: Integer;
+ begin
+ i := Length(x);
+ SetLength(x, i + 1);
+ x[i] := f;
+ end;
+
+ procedure Addf (var x: TArrayFloat; f: GLfloat);
var i: Integer;
begin
i := Length(x);
end;
procedure glClearColor(red, green, blue, alpha: GLclampf);
- var color: Integer;
begin
- color := makeacol(floor(red * 255), floor(green * 255), floor(blue * 255), floor(alpha * 255));
- clear_to_color(sdl2allegro_screen, color)
+ clearColor := makeacol(floor(red * 255), floor(green * 255), floor(blue * 255), floor(alpha * 255));
end;
procedure glClear(mask: GLbitfield);
begin
+ if (mask and GL_COLOR_BUFFER_BIT) <> 0 then
+ clear_to_color(sdl2allegro_screen, clearColor)
end;
procedure glAlphaFunc(func: GLenum; ref: GLclampf);
end;
procedure glEnd;
- var i, x, y, w, h: Integer;
+ var
+ i, j, k, w, h, x0, y0, x1, y1, offx, offy, tmp, s0, t0, s1, t1: Integer;
+ oldx0, oldy0, oldx1, oldy1: cint;
+ flipv, fliph: Boolean;
+ draw_sprite_proc: procedure (bmp, sprite: Allegro.PBITMAP; x, y: cint); cdecl;
begin
assert(cmds.mode <> GL_INVALID_ENUM);
assert(Length(cmds.v) mod ValPerVertex = 0);
assert(Length(cmds.c) mod ValPerColor = 0);
assert(Length(cmds.t) mod ValPerCoord = 0);
+ offx := stack[stack_ptr].x;
+ offy := stack[stack_ptr].y;
+
case cmds.mode of
GL_POINTS:
begin
begin
assert(Length(cmds.c) * 2 = Length(cmds.v)); (* not enough colors *)
for i := 0 to Length(cmds.v) div 2 - 1 do
- putpixel(sdl2allegro_screen, cmds.v[i * 2], cmds.v[i * 2 + 1], cmds.c[i])
+ putpixel(sdl2allegro_screen, offx + cmds.v[i * 2], offy + cmds.v[i * 2 + 1], cmds.c[i])
end
else
begin
for i := 0 to Length(cmds.v) div 2 - 1 do
- putpixel(sdl2allegro_screen, cmds.v[i * 2], cmds.v[i * 2 + 1], ccol)
+ putpixel(sdl2allegro_screen, offx + cmds.v[i * 2], offy + cmds.v[i * 2 + 1], ccol)
end
end;
GL_LINES:
begin
assert(Length(cmds.c) * 2 = Length(cmds.v));
for i := 0 to Length(cmds.v) div 4 - 1 do
- fastline(sdl2allegro_screen, cmds.v[i * 4], cmds.v[i * 4 + 1], cmds.v[i * 4 + 2], cmds.v[i * 4 + 3], cmds.c[i * 2])
+ fastline(sdl2allegro_screen, offx + cmds.v[i * 4], offy + cmds.v[i * 4 + 1], offx + cmds.v[i * 4 + 2], offy + cmds.v[i * 4 + 3], cmds.c[i * 2])
end
else
begin
for i := 0 to Length(cmds.v) div 4 - 1 do
- fastline(sdl2allegro_screen, cmds.v[i * 4], cmds.v[i * 4 + 1], cmds.v[i * 4 + 2], cmds.v[i * 4 + 3], ccol)
+ fastline(sdl2allegro_screen, offx + cmds.v[i * 4], offy + cmds.v[i * 4 + 1], offx + cmds.v[i * 4 + 2], offy + cmds.v[i * 4 + 3], ccol)
end
end;
GL_QUADS:
begin
- assert(Length(cmds.v) mod 8 = 0); (* broken quad *)
+ ASSERT(Length(cmds.v) mod 8 = 0); (* broken quad *)
if Length(cmds.t) <> 0 then
begin
- assert(Length(cmds.t) = Length(cmds.v)); (* not enough texture coords *)
- assert(ctex >= 0);
- assert(ctex <= High(tex));
+ ASSERT(Length(cmds.t) = Length(cmds.v)); (* not enough texture coords *)
+ ASSERT(ctex >= 0);
+ ASSERT(ctex <= High(tex));
+ ASSERT(tex[ctex].bmp <> nil);
for i := 0 to Length(cmds.v) div 8 - 1 do
begin
- x := cmds.v[i * 8];
- y := cmds.v[i * 8 + 1];
- w := abs(cmds.v[i * 4 + 5] - x);
- h := abs(cmds.v[i * 4 + 6] - y);
- //e_LogWriteFLn('Textured Quad %s %s', [w, h]);
- draw_sprite(sdl2allegro_screen, tex[ctex].bmp, x, y);
- //rect(sdl2allegro_screen, x, y, w, h, makecol(255, 0, 0))
+ flipv := False; fliph := False;
+ x0 := cmds.v[i * 8 + 0]; y0 := cmds.v[i * 8 + 1];
+ x1 := cmds.v[i * 8 + 4]; y1 := cmds.v[i * 8 + 5];
+ if x1 < x0 then
+ begin
+ tmp := x0;
+ x0 := x1;
+ x1 := tmp;
+ fliph := not fliph
+ end;
+ if y1 < y0 then
+ begin
+ tmp := y0;
+ y0 := y1;
+ y1 := tmp;
+ flipv := not flipv
+ end;
+
+ w := tex[ctex].bmp.w;
+ h := tex[ctex].bmp.h;
+ s0 := Trunc(cmds.t[i * 8 + 0] * w);
+ t0 := Trunc(cmds.t[i * 8 + 1] * h);
+ s1 := Trunc(cmds.t[i * 8 + 4] * w);
+ t1 := Trunc(cmds.t[i * 8 + 5] * h);
+
+ if s1 < s0 then
+ begin
+ tmp := s0;
+ s0 := s1;
+ s1 := tmp;
+ fliph := not fliph
+ end;
+ if t1 < t0 then
+ begin
+ tmp := t0;
+ t0 := t1;
+ t1 := tmp;
+ flipv := not flipv
+ end;
+
+ s0 := s0 mod w;
+ t0 := t0 mod h;
+ s1 := s1 mod w;
+ t1 := t1 mod h;
+
+ if flipv and fliph then
+ draw_sprite_proc := Allegro.draw_sprite_vh_flip
+ else if flipv then
+ draw_sprite_proc := Allegro.draw_sprite_v_flip
+ else if fliph then
+ draw_sprite_proc := Allegro.draw_sprite_h_flip
+ else
+ draw_sprite_proc := Allegro.draw_sprite;
+
+ oldx0 := 0; oldy0 := 0; oldx1 := 0; oldy1 := 0;
+ get_clip_rect(sdl2allegro_screen, oldx0, oldy0, oldx1, oldy1);
+ set_clip_rect(sdl2allegro_screen, max(oldx0, offx + x0), max(oldy0, offy + y0), min(oldx1, offx + x1), min(oldy1, offy + y1));
+
+ for j := 0 to (y1 - y0 + h - 1) div h - 1 do
+ for k := 0 to (x1 - x0 + w - 1) div w - 1 do
+ draw_sprite_proc(sdl2allegro_screen, tex[ctex].bmp, offx + x0 + k * w - s0, offy + y0 + j * h - t0);
+ //blit(tex[ctex].bmp, sdl2allegro_screen, 0, 0, offx + x0 + k * w - s0, offy + y0 + j * h - t0, w, h);
+
+ set_clip_rect(sdl2allegro_screen, oldx0, oldy0, oldx1, oldy1);
+
+ //rect(sdl2allegro_screen, offx + x0, offy + y0, offx + x1, offy + y1, makecol(255, 0, 0));
+ //rect(sdl2allegro_screen, offx + oldx0, offy + oldy0, offx + oldx1, offy + oldx1, makecol(0, 255, 0));
end
end
else if Length(cmds.c) <> 0 then
begin
assert(Length(cmds.c) * 2 = Length(cmds.v)); (* not enough colors *)
for i := 0 to Length(cmds.v) div 8 - 1 do
- rectfill(sdl2allegro_screen, cmds.v[i * 8], cmds.v[i * 8 + 1], cmds.v[i * 4 + 5], cmds.v[i * 4 + 6], cmds.c[i * 4])
+ rectfill(sdl2allegro_screen, offx + cmds.v[i * 8], offy + cmds.v[i * 8 + 1], offx + cmds.v[i * 8 + 4], offy + cmds.v[i * 8 + 5], cmds.c[i * 4])
end
else
begin
for i := 0 to Length(cmds.v) div 8 - 1 do
- rectfill(sdl2allegro_screen, cmds.v[i * 8], cmds.v[i * 8 + 1], cmds.v[i * 4 + 5], cmds.v[i * 4 + 6], ccol)
+ rectfill(sdl2allegro_screen, offx + cmds.v[i * 8], offy + cmds.v[i * 8 + 1], offx + cmds.v[i * 8 + 4], offy + cmds.v[i * 8 + 5], ccol)
end
end;
else
procedure glVertex2f(x, y: GLfloat);
begin
- Add(cmds.v, ceil(x));
- Add(cmds.v, ceil(y))
+ Addi(cmds.v, ceil(x));
+ Addi(cmds.v, ceil(y))
end;
procedure glVertex2i(x, y: GLint);
begin
- Add(cmds.v, x);
- Add(cmds.v, y)
+ Addi(cmds.v, x);
+ Addi(cmds.v, y)
end;
procedure glColor4f(red, green, blue, alpha: GLfloat);
begin
ccol := makeacol(floor(red * 255), floor(green * 255), floor(blue * 255), floor(alpha * 255));
- Add(cmds.c, ccol)
+ Addi(cmds.c, ccol)
end;
procedure glColor4ub(red, green, blue, alpha: GLubyte);
begin
ccol := makeacol(red, green, blue, alpha);
- Add(cmds.c, ccol)
+ Addi(cmds.c, ccol)
end;
procedure glColor3ub(red, green, blue: GLubyte);
begin
ccol := makecol(red, green, blue);
- Add(cmds.c, ccol)
+ Addi(cmds.c, ccol)
end;
procedure glTexCoord2f(s, t: GLfloat);
begin
- Add(cmds.t, floor(s));
- Add(cmds.t, floor(t));
+ Addf(cmds.t, s);
+ Addf(cmds.t, t);
end;
procedure glTexCoord2i(s, t: GLint);
begin
- Add(cmds.t, s);
- Add(cmds.t, t);
+ Addf(cmds.t, s);
+ Addf(cmds.t, t);
end;
procedure glReadPixels(x, y: GLint; width, height: GLsizei; format, atype: GLenum; pixels: Pointer);
procedure glLoadIdentity;
begin
+ with stack[stack_ptr] do
+ begin
+ x := 0;
+ y := 0;
+ end
end;
procedure glMatrixMode(mode: GLenum);
procedure glPushMatrix;
begin
+ stack[stack_ptr + 1] := stack[stack_ptr];
+ INC(stack_ptr);
end;
procedure glPopMatrix;
begin
+ DEC(stack_ptr)
end;
procedure glTranslatef(x, y, z: GLfloat);
begin
+ ASSERT(z = 0); (* 3D not supported *)
+ stack[stack_ptr].x := Trunc(x);
+ stack[stack_ptr].y := Trunc(y);
end;
procedure glRotatef(angle, x, y, z: GLfloat);
begin
+ //ASSERT(z = 0); (* 3D not supported *)
+ (* TODO Rotation *)
end;
procedure glScalef(x, y, z: GLfloat);
begin
+ //ASSERT(z = 1); (* 3D not supported *)
+ (* TODO Scale *)
end;
procedure glViewport(x, y: GLint; width, height: GLsizei);
end;
procedure glTexImage2D(target: GLenum; level, internalformat: GLint; width, height: GLsizei; border: GLint; format, atype: GLenum; const pixels: Pointer);
- var i, j, adr: Integer; p: PByte;
+ var i, j, adr: Integer; p: PByte; color: cint;
begin
assert(target = GL_TEXTURE_2D);
assert(level = 0);
if tex[ctex].bmp <> nil then
destroy_bitmap(tex[ctex].bmp);
+ // Video bitmap can lead to bad textures under dos
//tex[ctex].bmp := create_video_bitmap(width, height);
//if tex[ctex].bmp = nil then
tex[ctex].bmp := create_system_bitmap(width, height);
for i := 0 to width - 1 do
begin
adr := j * width * 4 + i * 4;
- putpixel(tex[ctex].bmp, i, height - j, makeacol(p[adr], p[adr + 1], p[adr + 2], p[adr + 3]))
+ if p[adr + 3] <> $FF then
+ color := 0
+ else
+ color := makeacol(p[adr], p[adr + 1], p[adr + 2], p[adr + 3]);
+ putpixel(tex[ctex].bmp, i, j, color)
end
end
else
end;
procedure glTexSubImage2D(target: GLenum; level, xoffset, yoffset: GLint; width, height: GLsizei; format, atype: GLenum; const pixels: Pointer);
- var i, j, adr: Integer; p: PByte;
+ var i, j, adr: Integer; p: PByte; color: Cint;
begin
assert(target = GL_TEXTURE_2D);
assert(level = 0);
for i := 0 to width - 1 do
begin
adr := j * width * 4 + i * 4;
- putpixel(tex[ctex].bmp, i, height - j, makeacol(p[adr], p[adr + 1], p[adr + 2], p[adr + 3]))
+ if p[adr + 3] <> $FF then
+ color := 0
+ else
+ color := makeacol(p[adr], p[adr + 1], p[adr + 2], p[adr + 3]);
+ putpixel(tex[ctex].bmp, i, j, color)
end
end
else