Хаос Шаоса

Использование и разработка софта (преимущественно на ПЦ)

Moderator: Shaos

User avatar
Alikberov
Doomed
Posts: 347
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re: Хаос Шаоса

Post by Alikberov »

Shaos wrote:Не - 50FPS конечно же не выйдет :)

Хотя у меня когда-то были мысли сделать "сопроцессор" для ретрокомпьютеров на PIC16 (он тоже 8-битный, но с частотами до 20 МГц и 4-мя тактами на команду), который бы "помогал" в некоторых матрасчётах слабенькому ретропроцу...
Как-то занимался темой быстрого построения линии в РК по Брезенхэму. Однако, не справился с символами псевдографики.
Помните (мышь работает)?
User avatar
Alikberov
Doomed
Posts: 347
Joined: 14 Oct 2019 18:10
Location: Tashkent

Скрипт генерации имитации плоской проекции "гор"

Post by Alikberov »

Нашёл исходный код свой. :roll:
(Сколько своих аккаунтов шерстить надо!)
You do not have the required permissions to view the files attached to this post.
User avatar
Shaos
Admin
Posts: 24012
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Хаос Шаоса

Post by Shaos »

Сдаётся мне чувак из книжки спёр мои картинки зеркально отразив :lol:
Shaos wrote:По просьбе Axora вспомнил и запрограммировал алгоритм генерации скал для газеты Абзац:

Image
Image
Image
Image
P.S. Хотя там же написано 1986? :roll:

P.P.S. Не - просто похоже очень :lol:
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24012
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re:

Post by Shaos »

Shaos wrote:По просьбе Axora вспомнил и запрограммировал алгоритм генерации скал для газеты Абзац:




Нашёл свой сишный исходник от декабря 2005 года :)

 gory1.c

Code: Select all

/* 
   gory1.c - Mountain Image Generator (15 Dec 2005 - 17 Dec 2005)
   Author: Alexander Shabarshin (alexander@shabarshin.com)
   http://chaos.shabarshin.com
   
   Compilation:
     gcc gory1.c -o gory1 -lSDL -ljpeg -lm
   Usage: 
     ./gory1
*/

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <setjmp.h>
#include <SDL/SDL.h>
#include <jpeglib.h>

#define MAXPIX 400000

int DDX = 1024;
int DDY = 768;
int quality = 90;

int black = 0x000000;
int grey  = 0x808080;
int white = 0xFFFFFF;
int red   = 0xFF0000;
int green = 0x00FF00;
int blue  = 0x0000FF;

SDL_Surface* screen;

struct my_error_mgr {
  struct jpeg_error_mgr pub;	/* "public" fields */
  jmp_buf setjmp_buffer;	/* for return to caller */
};

typedef struct my_error_mgr * my_error_ptr;

/*
 * Here's the routine that will replace the standard error_exit method:
 */

METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
  /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
  my_error_ptr myerr = (my_error_ptr) cinfo->err;

  /* Always display the message. */
  /* We could postpone this until after returning, if we chose. */
  (*cinfo->err->output_message) (cinfo);

  /* Return control to the setjmp point */
  longjmp(myerr->setjmp_buffer, 1);
}

int putpixel(int x, int y, int c)
{
 int *bits;
 SDL_Surface* s; 
 if(x<0 || x>=DDX || y<0 || y>=DDY) return 0;
 s = screen;
 if(SDL_MUSTLOCK(s) && SDL_LockSurface(s)<0) return 0;
 bits = (int*)(&((unsigned char*)s->pixels)[y*s->pitch+x*4]);
 *bits = c;
 if(SDL_MUSTLOCK(s)) SDL_UnlockSurface(s);
 return 1;
}

int getpixel(int x, int y)
{
 int *bits,c;
 SDL_Surface* s; 
 if(x<0 || x>=DDX || y<0 || y>=DDY) return 0;
 s = screen;
 if(SDL_MUSTLOCK(s) && SDL_LockSurface(s)<0) return 0;
 bits = (int*)(&((unsigned char*)s->pixels)[y*s->pitch+x*4]);
 c = *bits;
 if(SDL_MUSTLOCK(s)) SDL_UnlockSurface(s);
 return c;
}

void drawbar(int x, int y, int w, int h, int c)
{
 int i,j;
 for(j=y;j<y+h;j++)
 {
  if(j<0) continue;
  if(j>=DDY) break;
  for(i=x;i<x+w;i++)
  {
   if(i<0) continue;
   if(i>=DDX) break;
   putpixel(i,j,c);
  }
 }  
}

void drawhline(int x, int y, int l, int c)
{
 int i;
/* printf("drawhline(%i,%i,%i,%i)\n",x,y,l,c); */
 for(i=0;i<l;i++) putpixel(x+i,y,c);
}

void drawvline(int x, int y, int l, int c)
{
 int j;
/* printf("drawvline(%i,%i,%i,%i)\n",x,y,l,c); */
 for(j=0;j<l;j++) putpixel(x,y+j,c);
}

void drawrect(int x, int y, int w, int h, int c)
{
 drawhline(x,y,w,c);
 drawhline(x,y+h-1,w,c);
 drawvline(x,y,h,c);
 drawvline(x+w-1,y,h,c);
}

void drawline(int x, int y, int vx, int vy, int c)
{
 int ax,ay,n=0;
 long xlong,ylong,xxlong,yylong,hstep,vstep,l;
 if(vy==0)
 {
   if(vx>0) drawhline(x,y,vx,c);
   else drawhline(x+vx,y,-vx,c);
   return;
 }  
 if(vx==0)
 {
   if(vy>0) drawvline(x,y,vy,c);
   else drawvline(x,y+vy,-vy,c);
   return;
 }  
 if(vx>0) ax=vx;
 else ax=-vx;
 if(vy>0) ay=vy;
 else ay=-vy;
 if(ax<=1 && ay<=1) 
 {
   putpixel(x,y,c);
   return;
 }
 if(ax>ay) 
      l=ax<<1;
 else l=ay<<1;
 xlong = ((long)x)<<16;
 ylong = ((long)y)<<16;
 xxlong = ((long)(x+vx))<<16;
 yylong = ((long)(y+vy))<<16;
 hstep = (vx<<16)/l;
 vstep = (vy<<16)/l;
/*
 printf("\ndrawline(%i,%i,%i,%i,0x%8.8X)\n",x,y,vx,vy,c);
 printf("xlong=0x%8.8X\n",xlong);
 printf("ylong=0x%8.8X\n",ylong);
 printf("xxlong=0x%8.8X (%i)\n",xxlong,xxlong>>16);
 printf("yylong=0x%8.8X (%i)\n",yylong,yylong>>16);
 printf("hstep=0x%8.8X\n",hstep);
 printf("vstep=0x%8.8X\n",vstep);
*/ 
 while(1)
 { if(n++>=1000) break;
   putpixel(xlong>>16,ylong>>16,c);
   xlong += hstep;
   ylong += vstep;
/*   
   printf("%i) xlong=0x%8.8X (%i)\n",n,xlong,xlong>>16);
   printf("%i) ylong=0x%8.8X (%i)\n",n,ylong,ylong>>16);
*/   
   if(abs((xlong&0xFFFF0000)-xxlong)<=0x10000 &&
      abs((ylong&0xFFFF0000)-yylong)<=0x10000
     ) break;
 }
}

void line(int x1, int y1, int x2, int y2, int c)
{
 drawline(x1,y1,x2-x1,y2-y1,c);
}

typedef struct _pixel
{
  short x,y,z;
} pixel;

typedef struct _triangle
{
  short l,t,r;
} triangle;

triangle *tri;
pixel *pix;
int mtri,ntri,npix;

void drawtri(int t, int x, int y, int c)
{
  int x1,x2,x3,y1,y2,y3,z1,z2,z3;
  int i,k1,k2,ax[3],ay[3],xmin,ymin,xmax,ymax,yy,i1,i2,num;
  float fx1,fx2,tmp,dx1,dx2;
  long a1,a2,a3,a4,a5,a6,vx,vy,vz,cc;
  pixel *pl,*pt,*pr;
  triangle *tr;
  tr = &tri[t];
  pl = &pix[tr->l];
  pt = &pix[tr->t];
  pr = &pix[tr->r];
  z1 = pl->z;
  y1 = pl->y + y - z1;
  x1 = pl->x + x;
  z2 = pt->z;
  y2 = pt->y + y - z2;
  x2 = pt->x + x;
  z3 = pr->z;
  y3 = pr->y + y - z3;
  x3 = pr->x + x;
  if(c>=0)
  {
    line(x1,y1,x2,y2,c);
    line(x2,y2,x3,y3,c);
    line(x3,y3,x1,y1,c);
  }
  else
  {
    num = 3;
    if(pt->y < pl->y)
    {
     a1 = pl->x - pt->x;
     a2 = pl->y - pt->y;
     a3 = pl->z - pt->z;
     a4 = pr->x - pt->x;
     a5 = pr->y - pt->y;
     a6 = pr->z - pt->z;
     ax[0] = x1;
     ax[1] = x3;
     ax[2] = x2;
     ay[0] = y1;
     ay[1] = y3;
     ay[2] = y2;
    }
    else
    {
     a1 = pr->x - pt->x;
     a2 = pr->y - pt->y;
     a3 = pr->z - pt->z;
     a4 = pl->x - pt->x;
     a5 = pl->y - pt->y;
     a6 = pl->z - pt->z;
     ax[0] = x1;
     ax[1] = x2;
     ax[2] = x3;
     ay[0] = y1;
     ay[1] = y2;
     ay[2] = y3;
    } 
    vx = a2*a6 - a3*a5;
    vy = a3*a4 - a1*a6;
    vz = a1*a5 - a2*a4;  
    cc = acos(vx/sqrt(vx*vx+vy*vy+vz*vz))*128/3.14159;
    cc = cc|(cc<<8)|(cc<<16);
    xmin = 10000;
    ymin = 10000;
    xmax = -10000;
    ymax = -10000;
    for(i=0;i<num;i++)
    {
      if(ax[i]<xmin){xmin=ax[i];}
      if(ay[i]<ymin){ymin=ay[i];k1=i;}
      if(ax[i]>xmax){xmax=ax[i];}
      if(ay[i]>ymax){ymax=ay[i];k2=i;}
    }
    yy = ay[k1];
    i1 = i2 = k1;
//    putpixel(ax[k1],yy,cc);
    while(1)
    {
       if(yy==ay[k2]) break;
       if(ay[i1]==yy)
       {
          fx1 = ax[i1];
          y1 = ay[i1];
          if(++i1>=num) i1=0;
          tmp = ay[i1]-y1;
          if(tmp==0) continue;
          dx1 = (ax[i1]-fx1)/tmp;
       }
       if(ay[i2]==yy)
       {
          fx2 = ax[i2];
          y2 = ay[i2];
          if(--i2<0) i2=num-1;
          tmp = ay[i2]-y2;
          if(tmp==0) continue;
          dx2 = (ax[i2]-fx2)/tmp;
       }
       yy++;
       drawhline((int)fx1,yy,(int)(fx2-fx1+1),cc);
       fx1+=dx1;
       fx2+=dx2;
    }
  }    
}

void gentri(int m,int n)
{
  int i,j,hh,h2;
  for(i=m;i<n;i++)
  {
    hh = (pix[tri[i].r].x - pix[tri[i].l].x)/3;
    h2 = hh/3;
    pix[npix].x = (pix[tri[i].t].x + pix[tri[i].l].x) >> 1;
    pix[npix].y = (pix[tri[i].t].y + pix[tri[i].l].y) >> 1;
    for(j=0;j<npix;j++)
    {
      if(pix[j].x==pix[npix].x && pix[j].y==pix[npix].y)
      {
          pix[npix].z = pix[j].z;
	  break;
      }
    }
    if(j==npix) 
       pix[npix].z = ((pix[tri[i].t].z + pix[tri[i].l].z) >> 1) - h2 + (rand()%hh);
    npix++;
    pix[npix].x = (pix[tri[i].r].x + pix[tri[i].t].x) >> 1;
    pix[npix].y = (pix[tri[i].r].y + pix[tri[i].t].y) >> 1;
    for(j=0;j<npix;j++)
    {
      if(pix[j].x==pix[npix].x && pix[j].y==pix[npix].y)
      {
          pix[npix].z = pix[j].z;
	  break;
      }
    }
    if(j==npix) 
       pix[npix].z = ((pix[tri[i].r].z + pix[tri[i].t].z) >> 1) - h2 + (rand()%hh);
    npix++;
    pix[npix].x = (pix[tri[i].r].x + pix[tri[i].l].x) >> 1;
    pix[npix].y = (pix[tri[i].r].y + pix[tri[i].l].y) >> 1;
    for(j=0;j<npix;j++)
    {
      if(pix[j].x==pix[npix].x && pix[j].y==pix[npix].y)
      {
          pix[npix].z = pix[j].z;
	  break;
      }
    }
    if(j==npix) 
       pix[npix].z = ((pix[tri[i].r].z + pix[tri[i].l].z) >> 1) - h2 + (rand()%hh);  
    npix++;
    tri[ntri].l = npix - 3;
    tri[ntri].t = tri[i].t;
    tri[ntri].r = npix - 2;
    ntri++;
    tri[ntri].l = tri[i].l;
    tri[ntri].t = npix - 3;
    tri[ntri].r = npix - 1;
    ntri++;
    tri[ntri].l = npix - 3;
    tri[ntri].t = npix - 1;
    tri[ntri].r = npix - 2;
    ntri++;
    tri[ntri].l = npix - 1;
    tri[ntri].t = npix - 2;
    tri[ntri].r = tri[i].r;
    ntri++;
  }
}

void sortri(int m,int n)
{
  int i,y1,y2,l,t,r,k=1;
  while(k)
  {
    k = 0;
    for(i=m;i<n-1;i++)
    {
      if(pix[tri[i].t].y < pix[tri[i].l].y) y1=pix[tri[i].t].y;
      else y1=pix[tri[i].l].y;
      if(pix[tri[i+1].t].y < pix[tri[i+1].l].y) y2=pix[tri[i+1].t].y;
      else y2=pix[tri[i+1].l].y;
      if(y2<y1) 
      {
        k = 1;
	l = tri[i].l;
	t = tri[i].t;
	r = tri[i].r;
	tri[i].l = tri[i+1].l;
	tri[i].t = tri[i+1].t;
	tri[i].r = tri[i+1].r;
	tri[i+1].l = l;
	tri[i+1].t = t;
	tri[i+1].r = r;
      }
    }
  }
}

int main(int argc,char **argv)
{
   char imagefile[32];
   unsigned char *keys,*image_buffer;
   SDL_Color color;
   SDL_Event event;
   struct jpeg_compress_struct cinfo;
   struct jpeg_error_mgr jerr;
   FILE * outfile;		/* target file */
   JSAMPROW row_pointer[1];	/* pointer to JSAMPLE row[s] */
   int row_stride;		/* physical row width in image buffer */
   int image_height;	/* Number of rows in image */
   int image_width;	/* Number of columns in image */
   int number = 0;
   int done = 0;
   int i,j,k;
   int x,y,z;
   int dx,dy,x0,y0,w,w2,h;
   
   srand((unsigned int)time(NULL));
   if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER)<0)
   {
    printf("Unable to initialise SDL: %s\n",SDL_GetError());
    exit(1);
   }
   atexit(SDL_Quit);
   screen = SDL_SetVideoMode(DDX,DDY,32,SDL_HWSURFACE|SDL_DOUBLEBUF);
   if(screen==NULL)
   {
    printf("Unable to set video: %s\n", SDL_GetError());
    exit(1);
   }
   
   dx = DDX>>1;
   dy = DDY>>1;
   x0 = 20;
   w = dx-(x0<<1);
   w2 = w>>1;
   h = ((long)w2*56759)>>16;
   y0 = (dy-h)>>1;
   
   tri = (triangle*)malloc(MAXPIX*sizeof(triangle));
   pix = (pixel*)malloc(MAXPIX*sizeof(pixel));
   if(tri==NULL||pix==NULL) return 0;
   mtri = 0;
   ntri = 1;
   npix = 3;
   pix[0].x = x0;
   pix[0].y = y0+h;
   pix[0].z = 0;
   pix[1].x = x0+w2;
   pix[1].y = y0;
   pix[1].z = 0;
   pix[2].x = x0+w;
   pix[2].y = y0+h;
   pix[2].z = 0;
   tri[0].l = 0;
   tri[0].t = 1;
   tri[0].r = 2;

   while(1)
   {
     if(ntri*16>MAXPIX) break;
     if(done==2) break;

     drawbar(0,0,DDX,DDY,0x000000);
     drawrect(0,0,dx,dy,grey);
     drawrect(dx,0,dx,dy,grey);
     drawrect(0,dy,dx,dy,grey);
     drawrect(dx,dy,dx,dy,grey);

     printf("m=%i n=%i\n",mtri,ntri);
     for(i=mtri;i<ntri;i++) drawtri(i,0,0,white);
     sortri(mtri,ntri);
     for(i=mtri;i<ntri;i++) drawtri(i,dx,0,-1);
     k = ntri;
     gentri(mtri,ntri);
     mtri = k;

     printf("m=%i n=%i\n",mtri,ntri);
     for(i=mtri;i<ntri;i++) drawtri(i,0,dy,white);
     sortri(mtri,ntri);
     for(i=mtri;i<ntri;i++) drawtri(i,dx,dy,-1);
     k = ntri;
     gentri(mtri,ntri);
     mtri = k;

     SDL_Flip(screen);
     done = 0;
     while(!done)
     {while(SDL_PollEvent(&event)) 
      {if(event.type == SDL_QUIT) done=2;
       if(event.type == SDL_KEYDOWN) 
       {if(event.key.keysym.sym == SDLK_ESCAPE) done=2;
        if(event.key.keysym.sym == SDLK_SPACE) done=1;
       }
      }
     } 
//     if(done==2) break;
   
/* <><><><><><><><><><> JPEG <><><><><><><><><><><> */

  sprintf(imagefile,"gory1_%i.jpeg",++number);
  printf("Save '%s'\n",imagefile);
  image_width = DDX;
  image_height = DDY;
  image_buffer = (unsigned char*)malloc(DDX*3);
  if(image_buffer==NULL) return 0;

  /* Step 1: allocate and initialize JPEG compression object */

  /* We have to set up the error handler first, in case the initialization
   * step fails.  (Unlikely, but it could happen if you are out of memory.)
   * This routine fills in the contents of struct jerr, and returns jerr's
   * address which we place into the link field in cinfo.
   */
  cinfo.err = jpeg_std_error(&jerr);
  /* Now we can initialize the JPEG compression object. */
  jpeg_create_compress(&cinfo);

  /* Step 2: specify data destination (eg, a file) */
  /* Note: steps 2 and 3 can be done in either order. */

  /* Here we use the library-supplied code to send compressed data to a
   * stdio stream.  You can also write your own code to do something else.
   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
   * requires it in order to write binary files.
   */
  if ((outfile = fopen(imagefile, "wb")) == NULL) {
    fprintf(stderr, "can't open %s\n", imagefile);
    exit(1);
  }
  jpeg_stdio_dest(&cinfo, outfile);

  /* Step 3: set parameters for compression */

  /* First we supply a description of the input image.
   * Four fields of the cinfo struct must be filled in:
   */
  cinfo.image_width = image_width; 	/* image width and height, in pixels */
  cinfo.image_height = image_height;
  cinfo.input_components = 3;		/* # of color components per pixel */
  cinfo.in_color_space = JCS_RGB; 	/* colorspace of input image */
  /* Now use the library's routine to set default compression parameters.
   * (You must set at least cinfo.in_color_space before calling this,
   * since the defaults depend on the source color space.)
   */
  jpeg_set_defaults(&cinfo);
  /* Now you can set any non-default parameters you wish to.
   * Here we just illustrate the use of quality (quantization table) scaling:
   */
  jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */ );

  /* Step 4: Start compressor */

  /* TRUE ensures that we will write a complete interchange-JPEG file.
   * Pass TRUE unless you are very sure of what you're doing.
   */
  jpeg_start_compress(&cinfo, TRUE);

  /* Step 5: while (scan lines remain to be written) */
  /*           jpeg_write_scanlines(...); */

  /* Here we use the library's state variable cinfo.next_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   * To keep things simple, we pass one scanline per call; you can pass
   * more if you wish, though.
   */
  row_stride = image_width * 3;	/* JSAMPLEs per row in image_buffer */

  y = 0;
  while (cinfo.next_scanline < cinfo.image_height) {
    /* jpeg_write_scanlines expects an array of pointers to scanlines.
     * Here the array is only one element long, but you could pass
     * more than one scanline at a time if that's more convenient.
     */
     
    i = 0;
    for(x=0;x<DDX;x++){
           k = getpixel(x,y);
           image_buffer[i++] = (k>>16)&255;
           image_buffer[i++] = (k>>8)&255;
           image_buffer[i++] = k&255;
    }
    y++;
     
    row_pointer[0] = (JSAMPLE*)image_buffer;
    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
  }

  /* Step 6: Finish compression */

  jpeg_finish_compress(&cinfo);
  /* After finish_compress, we can close the output file. */
  fclose(outfile);

  /* Step 7: release JPEG compression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_compress(&cinfo);

  /* And we're done! */

  free(image_buffer);
  
  }
  
  free(tri);
  free(pix);
  
  return 1;
}

Он не только генерирует итерации, но и сохраняет картинки в JPEG 1024x768 - до сих пор собирается и работает :mrgreen:
gory1_1.jpeg
gory1_2.jpeg
gory1_3.jpeg
gory1_4.jpeg
P.S. Теперь я могу сам сгенерировать задник для Виртбурга в любом разрешении 8)

P.P.S. Облака по тому же алгоритму генерируются, но там теней нету - только белизна в зависимости от "высоты"...
You do not have the required permissions to view the files attached to this post.
Я тут за главного - если что шлите мыло на me собака shaos точка net