Beispiel #1
0
int main()
{
    int exit = 0;
    MAP* map = load_map("zaza.wad");
    
    init();
    
    clock_t last_clock = clock();
    
    while(!exit)
    {
        clock_t now = clock();
        float dt = (float)(now - last_clock) / CLOCKS_PER_SEC;
        last_clock = now;
        
        VEC2F view_dir = vec2f(cos(ang), sin(ang));
        VEC2F view_dir_norm = vec2f(-view_dir.y, view_dir.x);
        
        if(key[KEY_ESC]) exit = 1;
        if(key[KEY_S]) vp = vec2f_sum(vp, vec2f_uscale(view_dir, -move_speed * dt));
        if(key[KEY_W]) vp = vec2f_sum(vp, vec2f_uscale(view_dir, move_speed * dt));
        if(key[KEY_A]) vp = vec2f_sum(vp, vec2f_uscale(view_dir_norm, -move_speed * dt));
        if(key[KEY_D]) vp = vec2f_sum(vp, vec2f_uscale(view_dir_norm, move_speed * dt));
        if(key[KEY_LEFT]) ang -= rot_speed * dt;
        if(key[KEY_RIGHT]) ang += rot_speed * dt;
        
        clear_to_color(buffer, makecol(64, 64, 64));
        
        SECTOR* s = find_sector(map, map->node_num - 1, vp);
        float h = s->floor_height + 45;
        
        int i = 0;
        
        for(i = 0; i < H_RES; ++i)
        {
            float t = i - H_RES / 2;
            float u = FOCAL_DIST;
            
            VEC2F ray_dir = vec2f_sum(vec2f_uscale(view_dir, u), vec2f_uscale(view_dir_norm, t)); //vec2f(view_dir.x * FOCAL_DIST + view_dir_norm.x * t, view_dir.y * FOCAL_DIST + view_dir_norm.y * t);
            float ray_len = sqrt(ray_dir.x * ray_dir.x + ray_dir.y * ray_dir.y);
            ray_dir.x /= ray_len;
            ray_dir.y /= ray_len;
            
            int minh = 0;
            int maxh = SCREEN_H;
            
            render_col(buffer, map, map->node_num - 1, vp, -h, ray_dir, i, &minh, &maxh);
            printf("\n");
            //line(buffer, SCREEN_W / 2, SCREEN_H / 2, SCREEN_W / 2 + ray_dir.x * 200, SCREEN_H / 2 + ray_dir.y * 200, makecol(255, 255, 255));
        }
        
        draw_sprite(buffer, mouse_sprite, mouse_x, mouse_y);
        blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
    }
    
    destroy_map(map);
    deinit();
    return 0;
}END_OF_MAIN()
Beispiel #2
0
/*
** Triangles passed to this function have already been clipped by
** the clip box.
*/
static void render_triangle_1(WILLUSBITMAP *bmap,TRIANGLE2D *srctri,
                              RENDER_COLOR *rcolor,
                              RENDER_COLOR *bgcolor,int render_type)

    {
    TRIANGLE2D *tri,_tri;
    int     row,bottom_row,top_row;

/*
{
int i;
printf("@render_triangle_1\n");
for (i=0;i<4;i++)
printf("%6.4f %6.4f\n",srctri->p[i%3].x*bmap->width,srctri->p[i%3].y*bmap->height);
printf("//nc\n");
}
*/
    if (render_type==RENDER_TYPE_SET)
        {
        render_triangle_2(bmap,srctri,rcolor);
        return;
        }
    tri=&_tri;
    if (tri2d_zero_area(srctri))
        return;
    (*tri)=(*srctri);
    tri2d_sort_ypoints(tri);
    bottom_row = render_row(bmap,tri->p[0].y);
    top_row = render_row(bmap,tri->p[2].y);
    for (row=bottom_row;row<=top_row;row++)
        {
        int     nx,i,j,k,col,left_col,right_col;
        double  y0,y1;
        static double x[9];

// printf("row=%d\n",row);
        y0 = (double)row/bmap->height;
        y1 = (double)(row+1)/bmap->height;
        i=0;
        /* Create array of possible extreme x-coords */
        /* Triangle vertices */
        for (j=0;j<3;j++)
            if (y0<=tri->p[j].y && y1>=tri->p[j].y)
                x[i++] = tri->p[j].x;
        /* Segments intercepting y0 */
        for (j=0;j<2;j++)
            for (k=j+1;k<3;k++)
                if (tri->p[j].y < y0 && tri->p[k].y > y0)
                    x[i++] = p2d_x_intercept(y0,tri->p[j],tri->p[k]);
        /* Segments intercepting y1 */
        for (j=0;j<2;j++)
            for (k=j+1;k<3;k++)
                if (tri->p[j].y < y1 && tri->p[k].y > y1)
                    x[i++] = p2d_x_intercept(y1,tri->p[j],tri->p[k]);
        nx=i;
        left_col  = render_col(bmap,array_min(x,nx));
        right_col = render_col(bmap,array_max(x,nx));
// printf("    %d to %d\n",left_col,right_col);
        for (col=left_col;col<=right_col;col++)
            {
            if (render_type==RENDER_TYPE_ANTIALIASED)
                render_pixelset(bmap,col,row,rcolor,
                       render_type,bgcolor,
                       tri2d_intersection_area(bmap,tri,row,col));
            else
                if (render_pixel_contained(bmap,tri,row,col))
                    render_pixelset(bmap,col,row,rcolor,
                                      render_type,bgcolor,1.);
            }
        }
    }
Beispiel #3
0
void render_col(BITMAP* buffer, MAP* map, short idx, VEC2F vp, float cam_h, VEC2F ray_dir, int col)
{   
    if(idx & SHORT_SIGN_FLAG)
    {
        //printf("ASDF = %d %d\n", (short)(idx & ~SHORT_SIGN_FLAG), idx);
        SSECTOR* ssector = &map->ssectors[(short)(idx & ~SHORT_SIGN_FLAG)];
        int i;
        for(i = 0; i < ssector->seg_num; ++i)
        {
            SEG* seg = &map->segs[ssector->first_seg_idx + i];
            VEC2F v1 = get_vertex(map, seg->v1_idx);
            VEC2F v2 = get_vertex(map, seg->v2_idx);
            RAY_VS_SEGMENT_RESULT res = ray_vs_segment(v1, v2, vp, ray_dir);
            VEC2F n = vec2f(v1.y - v2.y, v2.x - v1.x);
            LINEDEF* linedef = &map->linedefs[seg->linedef_idx];
            
            SIDEDEF *sidedef1, *sidedef2;
            SECTOR *sector1, *sector2;
            
            if(seg->dir)
            {
                sidedef1 = &map->sidedefs[linedef->neg_sidedef_idx];
                sector1 = &map->sectors[sidedef1->sector_idx];
                sidedef2 = linedef->pos_sidedef_idx == -1 ? NULL : &map->sidedefs[linedef->pos_sidedef_idx];
                sector2 = linedef->pos_sidedef_idx == -1 ? NULL : &map->sectors[sidedef2->sector_idx];
            }
            else
            {
                sidedef1 = &map->sidedefs[linedef->pos_sidedef_idx];
                sector1 = &map->sectors[sidedef1->sector_idx];
                sidedef2 = linedef->neg_sidedef_idx == -1 ? NULL : &map->sidedefs[linedef->neg_sidedef_idx];
                sector2 = linedef->neg_sidedef_idx == -1 ? NULL : &map->sectors[sidedef2->sector_idx];
            }
            
            //printf("%c%c%c%c%c%c%c%c\n", sidedef->mid_tex_name[0],  sidedef->mid_tex_name[1],
             //sidedef->mid_tex_name[2], sidedef->mid_tex_name[3], sidedef->mid_tex_name[4], sidedef->mid_tex_name[5],
              //sidedef->mid_tex_name[6], sidedef->mid_tex_name[7]);
            
            if(res.t > 10 && res.k >= 0 && res.k <= 1.0 && vec2f_dot(n, vec2f_diff(vp, v1)) < 0)
            {
                VEC2F d = vec2f_diff(v2, v1);
                VEC2F wall_normal = vec2f(-d.y, d.x);
                float wall_len = sqrt(d.x * d.x + d.y * d.y);
                wall_normal.x /= wall_len;
                wall_normal.y /= wall_len;
                int r = clamp255((int)(fabs(wall_normal.x) * 4000 / sqrt(res.t)));
                int g = clamp255((int)(fabs(wall_normal.y) * 4000 / sqrt(res.t)));
                int color = makecol(r, g, 0);
                
                if(sidedef1 && !sidedef2)
                    render_col_helper(col, sector1->ceil_height + cam_h, sector1->floor_height + cam_h, res.t, color);
                else
                {
                    render_col_helper(col, sector2->ceil_height + cam_h, sector1->ceil_height + cam_h, res.t, color);
                    render_col_helper(col, sector2->floor_height + cam_h, sector1->floor_height + cam_h, res.t, color);
                    if(sidedef1->mid_tex_name[0] != '-')
                       render_col_helper(col, sector1->floor_height + cam_h, sector1->ceil_height + cam_h, res.t, color);
                }
            }
        }
        
        // render subsector...
    }
    else
    {
        NODE* node = &map->nodes[idx];
        
        VEC2F n = vec2f(-node->y2, node->x2);
        if(vec2f_dot(n, vec2f(vp.x - node->x1, vp.y - node->y1)) >= 0)
        {
            render_col(buffer, map, node->left_child_idx, vp, cam_h, ray_dir, col);
            render_col(buffer, map, node->right_child_idx, vp, cam_h, ray_dir, col);
        }
        else
        {
            render_col(buffer, map, node->right_child_idx, vp, cam_h, ray_dir, col);
            render_col(buffer, map, node->left_child_idx, vp, cam_h, ray_dir, col);
        }
    }
}
Beispiel #4
0
int main()
{
    int exit = 0;
    MAP* map = load_map("e1m1.wad");
    VEC2F vp = vec2f(0.f, 0.f);
    float ang, move_speed = 200.f, rot_speed = 2.5f;
    
    init();
    
    //VEC2F vn = vec2f(-v.y, v.x);
    //VEC2F ray_dir = vec2f();
    
    //short s = -1;
    //s &= ~(1 << 15);
    //printf("ZOMG = %d\n", s);
    
    clock_t last_clock = clock();
    
    while(!exit)
    {
        clock_t now = clock();
        float dt = (float)(now - last_clock) / CLOCKS_PER_SEC;
        last_clock = now;
        
        VEC2F view_dir = vec2f(cos(ang), sin(ang));
        VEC2F view_dir_norm = vec2f(-view_dir.y, view_dir.x);
        
        if(key[KEY_ESC]) exit = 1;
        if(key[KEY_S]) vp = vec2f_sum(vp, vec2f_uscale(view_dir, -move_speed * dt));
        if(key[KEY_W]) vp = vec2f_sum(vp, vec2f_uscale(view_dir, move_speed * dt));
        if(key[KEY_A]) vp = vec2f_sum(vp, vec2f_uscale(view_dir_norm, -move_speed * dt));
        if(key[KEY_D]) vp = vec2f_sum(vp, vec2f_uscale(view_dir_norm, move_speed * dt));
        if(key[KEY_LEFT]) ang -= rot_speed * dt;
        if(key[KEY_RIGHT]) ang += rot_speed * dt;
        
        clear_to_color(buffer, 0);
        
        SECTOR* s = find_sector(map, map->node_num - 1, vp);
        float h = s->floor_height + 45;
        
        int i;
        
        for(i = 0; i < H_RES; ++i)
        {
            float t = i - H_RES / 2;
            float u = FOCAL_DIST;
            
            VEC2F ray_dir = vec2f_sum(vec2f_uscale(view_dir, u), vec2f_uscale(view_dir_norm, t)); //vec2f(view_dir.x * FOCAL_DIST + view_dir_norm.x * t, view_dir.y * FOCAL_DIST + view_dir_norm.y * t);
            float ray_len = sqrt(ray_dir.x * ray_dir.x + ray_dir.y * ray_dir.y);
            ray_dir.x /= ray_len;
            ray_dir.y /= ray_len;
            render_col(buffer, map, map->node_num - 1, vp, -h, ray_dir, i);
            
            //line(buffer, SCREEN_W / 2, SCREEN_H / 2, SCREEN_W / 2 + ray_dir.x * 200, SCREEN_H / 2 + ray_dir.y * 200, makecol(255, 255, 255));
        }

        
        
        if(key[KEY_TAB])
        for(i = 0; i < map->seg_num; ++i)
        {
            VERTEX v1t = map->vertexes[map->segs[i].v1_idx];
            VERTEX v2t = map->vertexes[map->segs[i].v2_idx];
            VEC2F v1 = vec2f(v1t.x, v1t.y);
            VEC2F v2 = vec2f(v2t.x, v2t.y);
            VEC2F mid = vec2f((v1.x + v2.x) / 2, (v1.y + v2.y) / 2);
            
            VEC2F n = normalized_normal(vec2f_diff(v2, v1));
            float scl = 1.f / 2.f;
            
            line(buffer, v1.x*scl + SCREEN_W / 2,
                         v1.y*scl + SCREEN_H / 2,
                         v2.x*scl + SCREEN_W / 2,
                         v2.y*scl + SCREEN_H / 2, makecol(255, 255, 255));
            circlefill(buffer, (int)vp.x*scl + SCREEN_W/2, (int)vp.y*scl +SCREEN_H/2, 3, makecol(255, 255, 255));
            
            
            line(buffer, SCREEN_W/2+ mid.x*scl,
                        SCREEN_H/2 +  mid.y*scl,
                        SCREEN_W/2+ (mid.x + n.x * 10)*scl,
                        SCREEN_H/2+ (mid.y + n.y * 10)*scl, makecol(255, 255, 255));
            
            
            line(buffer, SCREEN_W/2+vp.x*scl,
                        SCREEN_H/2+vp.y*scl,
                        SCREEN_W/2+(vp.x+view_dir.x*100)*scl,
                        SCREEN_H/2+(vp.y+view_dir.y*100)*scl, makecol(255, 255, 255));
        }
        
        //
        
        draw_sprite(buffer, mouse_sprite, mouse_x, mouse_y);
        blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H);
    }
    
    destroy_map(map);
    deinit();
    return 0;
}END_OF_MAIN()
Beispiel #5
0
void render_col(BITMAP* buffer, MAP* map, short idx, VEC2F vp, float cam_h, VEC2F ray_dir, int col, int* minh, int* maxh)
{   
    if(idx & SHORT_SIGN_FLAG)
    {
        //printf("ASDF = %d %d\n", (short)(idx & ~SHORT_SIGN_FLAG), idx);
        SSECTOR* ssector = &map->ssectors[(short)(idx & ~SHORT_SIGN_FLAG)];
        int i;
        for(i = 0; i < ssector->seg_num; ++i)
        {
            SEG* seg = &map->segs[ssector->first_seg_idx + i];
            VEC2F v1 = get_vertex(map, seg->v1_idx);
            VEC2F v2 = get_vertex(map, seg->v2_idx);
            RAY_VS_SEGMENT_RESULT res = ray_vs_segment(v1, v2, vp, ray_dir);
            VEC2F n = vec2f(v1.y - v2.y, v2.x - v1.x);
            LINEDEF* linedef = &map->linedefs[seg->linedef_idx];
            
            SIDEDEF *sidedef1, *sidedef2;
            SECTOR *sector1, *sector2;
            
            if(seg->dir)
            {
                sidedef1 = &map->sidedefs[linedef->neg_sidedef_idx];
                sector1 = &map->sectors[sidedef1->sector_idx];
                sidedef2 = linedef->pos_sidedef_idx == -1 ? NULL : &map->sidedefs[linedef->pos_sidedef_idx];
                sector2 = linedef->pos_sidedef_idx == -1 ? NULL : &map->sectors[sidedef2->sector_idx];
            }
            else
            {
                sidedef1 = &map->sidedefs[linedef->pos_sidedef_idx];
                sector1 = &map->sectors[sidedef1->sector_idx];
                sidedef2 = linedef->neg_sidedef_idx == -1 ? NULL : &map->sidedefs[linedef->neg_sidedef_idx];
                sector2 = linedef->neg_sidedef_idx == -1 ? NULL : &map->sectors[sidedef2->sector_idx];
            }
            
            //printf("%c%c%c%c%c%c%c%c\n", sidedef->mid_tex_name[0],  sidedef->mid_tex_name[1],
             //sidedef->mid_tex_name[2], sidedef->mid_tex_name[3], sidedef->mid_tex_name[4], sidedef->mid_tex_name[5],
              //sidedef->mid_tex_name[6], sidedef->mid_tex_name[7]);
            
            if(res.t > 0 && res.k >= 0 && res.k <= 1.0)
            {
               // VEC2F d = vec2f_diff(v2, v1);
                //VEC2F wall_normal = vec2f(-d.y, d.x);
                //float wall_len = sqrt(d.x * d.x + d.y * d.y);
                //wall_normal.x /= wall_len;
                //wall_normal.y /= wall_len;
                //int r = clamp255((int)(fabs(wall_normal.x) * 4000 / sqrt(res.t)));
                //int g = clamp255((int)(fabs(wall_normal.y) * 4000 / sqrt(res.t)));
                int color = random_colors[(ssector->first_seg_idx + i) % RANDOM_COLOR_NUM];//makecol(r, g, 0);
                
                if(sidedef1 && !sidedef2) {
                    //render_col_helper(col, sector1->ceil_height + cam_h, sector1->floor_height + cam_h, res.t, color);
                    float top_y = sector1->ceil_height - cam_h;
                    float bottom_y = sector1->floor_height - cam_h;
                    float z = res.t;
                    
                    float top_h = MAX(SCREEN_H / 2 + top_y / z  * FOCAL_DIST, *minh);
                    float bottom_h = MIN(SCREEN_H / 2 + bottom_y / z * FOCAL_DIST, *maxh);
                                printf("%f %f\n", top_h, bottom_h);
                    
                    //if(bottom_h >= top_h)
                    { 
                        if(vec2f_dot(n, vec2f_diff(vp, v1)) < 0)
                            rectfill(buffer, col * 2, (int)top_h/2*2, col * 2 + 2, (int)bottom_h/2*2, color);
                   }
                   
                                           *minh = MAX(*minh, bottom_h);
                        *maxh = MIN(*maxh, top_h);
                }
                    
                else
                {   
                    float y0 = sector1->ceil_height - cam_h;
                    float y1 = sector2->ceil_height - cam_h;
                    float z = res.t;
                    
                    float h1 = MAX(SCREEN_H / 2 + y0 * FOCAL_DIST / z, *minh);
                    float h2 = MIN(SCREEN_H / 2 + y1 * FOCAL_DIST / z, *maxh);
                    
                    if(h2 >= h1)
                    {
                        if(vec2f_dot(n, vec2f_diff(vp, v1)) < 0)
                            rectfill(buffer, col * 2, (int)h1/2*2, col * 2 + 2, (int)h2/2*2, color);
                    }
                    *minh = MAX(*minh, h1);
                    
                    
                    y0 = sector2->floor_height - cam_h;
                    y1 = sector1->floor_height - cam_h;
                    
                    h1 = MAX(SCREEN_H / 2 + y0 * FOCAL_DIST / z, *minh);
                    h2 = MIN(SCREEN_H / 2 + y1 * FOCAL_DIST / z, *maxh);
                    
                    if(h2 >= h1)
                    {
                        if(vec2f_dot(n, vec2f_diff(vp, v1)) < 0)
                            rectfill(buffer, col * 2, (int)h1/2*2, col * 2 + 2, (int)h2/2*2, color);
                    }
                    
                                            *maxh = MIN(*maxh, h2);
                }
            }
        }
        
        // render subsector...
    }
    else
    {
        NODE* node = &map->nodes[idx];
        
        VEC2F n = vec2f(-node->y2, node->x2);
        if(vec2f_dot(n, vec2f(vp.x - node->x1, vp.y - node->y1)) < 0)
        {
            render_col(buffer, map, node->left_child_idx, vp, cam_h, ray_dir, col, minh, maxh);
            render_col(buffer, map, node->right_child_idx, vp, cam_h, ray_dir, col, minh, maxh);
        }
        else
        {
            render_col(buffer, map, node->right_child_idx, vp, cam_h, ray_dir, col, minh, maxh);
            render_col(buffer, map, node->left_child_idx, vp, cam_h, ray_dir, col, minh, maxh);
        }
    }
}