X-Git-Url: http://deadsoftware.ru/gitweb?a=blobdiff_plain;f=src%2Fnogl%2FnoGLALSW.inc;h=b9f1ddd960d79fb4dfc274ec739ead974103bc94;hb=f2421615862d0a6c093c6fc3117849010d26557b;hp=60b207228bcd321fc1c9848af9cb9a78e847f7fe;hpb=1d24275aa4b72cac9efc1e14ba377307f89d7728;p=d2df-sdl.git diff --git a/src/nogl/noGLALSW.inc b/src/nogl/noGLALSW.inc index 60b2072..b9f1ddd 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,11 +32,19 @@ implementation tex: TArrayTexture; ctex: Integer; ccol: Integer; + clearColor: cint; + stack: array [0..StackSize - 1] of record + x, y: Integer; + end; + stack_ptr: Integer; + vpx, vpy: Integer; + pointSize: Integer; + matrixMode: GLenum; function AddTexture: Integer; var i: Integer; begin - for i := 0 to High(tex) do + for i := 1 to High(tex) do if not tex[i].used then begin tex[i].used := true; @@ -51,13 +63,22 @@ implementation begin assert(i >= 0); assert(i <= High(tex)); - assert(tex[i].used); + assert((i = 0) or 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); @@ -82,18 +103,21 @@ implementation function glGetString(name: GLenum): PChar; begin - result := '' + if name = GL_EXTENSIONS then (* separated by space *) + result := 'GL_ARB_texture_non_power_of_two' + else + result := nil 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); @@ -106,10 +130,14 @@ implementation procedure glPointSize(size: GLfloat); begin + ASSERT(size >= 0); + if size <= 1.0 then pointSize := ceil(size) + else pointSize := floor(size) end; procedure glLineWidth(width: GLfloat); begin + (* width > 1 used in rare cases, not critical *) end; procedure glGetIntegerv(pname: GLenum; params: PGLint); @@ -136,28 +164,64 @@ 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 := vpx + stack[stack_ptr].x; + offy := vpy + stack[stack_ptr].y; + case cmds.mode of GL_POINTS: begin - (* implement case for texture coords? *) - 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 2 - 1 do - putpixel(sdl2allegro_screen, cmds.v[i * 2], 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) - end + (* implement case for texture coords? *) + if pointSize = 1 then + begin + 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 2 - 1 do + 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, offx + cmds.v[i * 2], offy + cmds.v[i * 2 + 1], ccol) + end + end + else if pointSize > 1 then + begin + x0 := offx - pointSize div 2; + y0 := offy - pointSize div 2; + x1 := offx - (pointSize - 1) div 2; + y1 := offy - (pointSize - 1) div 2; + 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 2 - 1 do + begin + w := cmds.v[i * 2 + 0]; + h := cmds.v[i * 2 + 1]; + rectfill(sdl2allegro_screen, x0 + w, y0 + h, x1 + w, y1 + h, cmds.c[i]) + end + end + else + begin + for i := 0 to Length(cmds.v) div 2 - 1 do + begin + w := cmds.v[i * 2 + 0]; + h := cmds.v[i * 2 + 1]; + rectfill(sdl2allegro_screen, x0 + w, y0 + h, x1 + w, y1 + h, ccol) + end + end + end end; GL_LINES: begin @@ -167,43 +231,116 @@ 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; + + if fliph then + begin + tmp := s0; + s0 := w - s1; + s1 := w - tmp; + end; + if flipv then + begin + tmp := t0; + t0 := h - t1; + t1 := h - tmp; + 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); + + 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 +355,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,43 +401,88 @@ implementation procedure glLoadIdentity; begin + if matrixMode <> GL_MODELVIEW then Exit; + with stack[stack_ptr] do + begin + x := 0; + y := 0; + (* TODO Rotation and scale *) + end end; procedure glMatrixMode(mode: GLenum); begin + (* GL_PROJECTION -> verify or ignore *) + (* GL_MODELVIEW -> apply *) + ASSERT((mode = GL_PROJECTION) or (mode = GL_MODELVIEW)); + matrixMode := mode; end; procedure glLoadMatrixd(const m: PGLdouble); begin - //m[x,y] + if matrixMode <> GL_MODELVIEW then Exit; + + (* + e_LogWritefln('glLoadMatrix:', []); + e_LogWritefln('| %s %s %s %s |', [m[0], m[1], m[2], m[3]]); + e_LogWritefln('| %s %s %s %s |', [m[4], m[5], m[6], m[7]]); + e_LogWritefln('| %s %s %s %s |', [m[8], m[9], m[10], m[11]]); + e_LogWritefln('| %s %s %s %s |', [m[12], m[13], m[14], m[15]]); + *) + with stack[stack_ptr] do + begin + x := Trunc(m[3]); + y := Trunc(m[7]); + ASSERT(m[11] = 0); + (* TODO Rotation and Scale *) + end end; procedure glPushMatrix; begin + if matrixMode <> GL_MODELVIEW then Exit; + stack[stack_ptr + 1] := stack[stack_ptr]; + INC(stack_ptr); end; procedure glPopMatrix; begin + if matrixMode <> GL_MODELVIEW then Exit; + DEC(stack_ptr) end; procedure glTranslatef(x, y, z: GLfloat); begin + if matrixMode <> GL_MODELVIEW then Exit; + 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 + if matrixMode <> GL_MODELVIEW then Exit; + ASSERT(x = 0); (* 3D not supported *) + ASSERT(y = 0); (* 3D not supported *) + (* TODO a := deg(angle * z) *) end; procedure glScalef(x, y, z: GLfloat); begin + if matrixMode <> GL_MODELVIEW then Exit; + (* 3D not supported, but z can be any *) + (* TODO Scale *) end; procedure glViewport(x, y: GLint; width, height: GLsizei); begin + vpx := x; vpy := y; + set_clip_rect(sdl2allegro_screen, x, y, x + width, y + height); end; procedure glScissor(x, y: GLint; width, height: GLsizei); begin + //set_clip_rect(sdl2allegro_screen, x, y, width, height) end; procedure glStencilMask(mask: GLuint); @@ -345,7 +527,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, trans: cint; begin assert(target = GL_TEXTURE_2D); assert(level = 0); @@ -360,9 +542,7 @@ implementation if tex[ctex].bmp <> nil then destroy_bitmap(tex[ctex].bmp); - //tex[ctex].bmp := create_video_bitmap(width, height); - //if tex[ctex].bmp = nil then - tex[ctex].bmp := create_system_bitmap(width, height); + tex[ctex].bmp := create_system_bitmap(width, height); if tex[ctex].bmp = nil then tex[ctex].bmp := create_bitmap(width, height); assert(tex[ctex].bmp <> nil); @@ -372,11 +552,20 @@ implementation p := pixels; if format = GL_RGBA then begin + if DEFAULT_DEPTH <= 8 then + trans := 0 + else + trans := makeacol(255, 0, 255, 0); + for j := 0 to height - 1 do 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] = 0 then + color := trans + 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 +580,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, trans: Cint; begin assert(target = GL_TEXTURE_2D); assert(level = 0); @@ -410,11 +599,20 @@ implementation p := pixels; if format = GL_RGBA then begin + if DEFAULT_DEPTH <= 8 then + trans := 0 + else + trans := makeacol(255, 0, 255, 0); + for j := 0 to height - 1 do 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] = 0 then + color := trans + else + color := makeacol(p[adr], p[adr + 1], p[adr + 2], p[adr + 3]); + putpixel(tex[ctex].bmp, i, j, color) end end else