X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fnogl%2FnoGLALSW.inc;h=853c22495095f6c1f2ce94b996490eb92b48f72e;hb=be2f0e35ae7b7688559621e4b8cb2d9a75a43d23;hp=60b207228bcd321fc1c9848af9cb9a78e847f7fe;hpb=1d24275aa4b72cac9efc1e14ba377307f89d7728;p=d2df-sdl.git diff --git a/src/nogl/noGLALSW.inc b/src/nogl/noGLALSW.inc index 60b2072..853c224 100644 --- a/src/nogl/noGLALSW.inc +++ b/src/nogl/noGLALSW.inc @@ -7,15 +7,19 @@ implementation 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 @@ -28,6 +32,11 @@ implementation 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; @@ -51,13 +60,22 @@ implementation begin assert(i >= 0); assert(i <= High(tex)); - assert(tex[i].used); + //assert(tex[i].used); (* free unallocated texture *) 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); @@ -86,14 +104,14 @@ implementation 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); @@ -136,13 +154,20 @@ implementation 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 @@ -151,12 +176,12 @@ implementation 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: @@ -167,43 +192,104 @@ implementation 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 @@ -218,44 +304,44 @@ implementation 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); @@ -264,6 +350,11 @@ implementation procedure glLoadIdentity; begin + with stack[stack_ptr] do + begin + x := 0; + y := 0; + end end; procedure glMatrixMode(mode: GLenum); @@ -277,22 +368,32 @@ implementation 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); @@ -345,7 +446,7 @@ implementation 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); @@ -360,6 +461,7 @@ implementation 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); @@ -376,7 +478,11 @@ implementation 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 @@ -391,7 +497,7 @@ implementation 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); @@ -414,7 +520,11 @@ implementation 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