mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +00:00
[renderer] Get sw fisheye working again
Again, gl/vulkan not working yet (on the assumption that sw would be trickier). Fisheye overrides water warp because updating the projection map every frame is far too expensive. I've added a post-process pass to the interface in order to hide the implementation details, but I'm not sure I'm happy about how the multi-pass rendering for cube maps is handled (or having the frame buffers as exposed as they are), but mainly because Vulkan will make implementation interesting.
This commit is contained in:
parent
0c437492b4
commit
20a2e7e06f
11 changed files with 366 additions and 237 deletions
|
@ -40,6 +40,7 @@ struct skin_s;
|
|||
struct mod_alias_ctx_s;
|
||||
struct mod_sprite_ctx_s;
|
||||
struct entqueue_s;
|
||||
struct framebuffer_s;
|
||||
|
||||
/*
|
||||
All video plugins must export these functions
|
||||
|
@ -112,9 +113,11 @@ typedef struct vid_render_funcs_s {
|
|||
void (*draw_entities) (struct entqueue_s *queue);
|
||||
void (*draw_particles) (struct psystem_s *psystem);
|
||||
void (*draw_transparent) (void);
|
||||
void (*post_process) (struct framebuffer_s *src);
|
||||
void (*set_2d) (int scaled);
|
||||
void (*end_frame) (void);
|
||||
|
||||
struct framebuffer_s *(*create_cube_map) (int side);
|
||||
struct framebuffer_s *(*create_frame_buffer) (int width, int height);
|
||||
void (*bind_framebuffer) (struct framebuffer_s *framebuffer);
|
||||
|
||||
|
|
|
@ -81,4 +81,13 @@ int R_BillboardFrame (entity_t *ent, int orientation, const vec3_t cameravec,
|
|||
mspriteframe_t *R_GetSpriteFrame (const msprite_t *sprite,
|
||||
const animation_t *animation);
|
||||
|
||||
// These correspond to the standard box sides for OpenGL cube maps
|
||||
#define BOX_FRONT 4
|
||||
#define BOX_RIGHT 0
|
||||
#define BOX_BEHIND 5
|
||||
#define BOX_LEFT 1
|
||||
#define BOX_TOP 2
|
||||
#define BOX_BOTTOM 3
|
||||
void R_RenderFisheye (framebuffer_t *cube);
|
||||
|
||||
#endif//__r_internal_h
|
||||
|
|
|
@ -157,6 +157,7 @@ libs_video_renderer_librender_sw_la_SOURCES = \
|
|||
libs/video/renderer/sw/nonintel.c \
|
||||
libs/video/renderer/sw/screen.c \
|
||||
libs/video/renderer/sw/surf8.S \
|
||||
libs/video/renderer/sw/sw_fisheye.c \
|
||||
libs/video/renderer/sw/sw_graph.c \
|
||||
libs/video/renderer/sw/sw_raclip.c \
|
||||
libs/video/renderer/sw/sw_raclipa.S \
|
||||
|
|
|
@ -364,14 +364,14 @@ gl_R_RenderView (void)
|
|||
// translation function to map texture coordinates to fixed/regular
|
||||
// grid vertices coordinates.
|
||||
// Render view. Fisheye is done.
|
||||
|
||||
#if 0
|
||||
#define BOX_FRONT 0
|
||||
#define BOX_RIGHT 1
|
||||
#define BOX_BEHIND 2
|
||||
#define BOX_LEFT 3
|
||||
#define BOX_TOP 4
|
||||
#define BOX_BOTTOM 5
|
||||
|
||||
#endif
|
||||
static mat4f_t box_rotations[] = {
|
||||
{ { 1, 0, 0, 0}, // front
|
||||
{ 0, 1, 0, 0},
|
||||
|
|
|
@ -66,7 +66,48 @@ static qboolean scr_initialized;// ready to draw
|
|||
static qpic_t *scr_ram;
|
||||
static qpic_t *scr_turtle;
|
||||
|
||||
static framebuffer_t *fisheye_cube_map;
|
||||
static framebuffer_t *warp_buffer;
|
||||
|
||||
static mat4f_t box_rotations[] = {
|
||||
[BOX_FRONT] = {
|
||||
{ 1, 0, 0, 0}, // front
|
||||
{ 0, 1, 0, 0},
|
||||
{ 0, 0, 1, 0},
|
||||
{ 0, 0, 0, 1}
|
||||
},
|
||||
[BOX_RIGHT] = {
|
||||
{ 0,-1, 0, 0}, // right
|
||||
{ 1, 0, 0, 0},
|
||||
{ 0, 0, 1, 0},
|
||||
{ 0, 0, 0, 1}
|
||||
},
|
||||
[BOX_BEHIND] = {
|
||||
{-1, 0, 0, 0}, // back
|
||||
{ 0,-1, 0, 0},
|
||||
{ 0, 0, 1, 0},
|
||||
{ 0, 0, 0, 1}
|
||||
},
|
||||
[BOX_LEFT] = {
|
||||
{ 0, 1, 0, 0}, // left
|
||||
{-1, 0, 0, 0},
|
||||
{ 0, 0, 1, 0},
|
||||
{ 0, 0, 0, 1}
|
||||
},
|
||||
[BOX_TOP] = {
|
||||
{ 0, 0, 1, 0}, // top
|
||||
{ 0, 1, 0, 0},
|
||||
{-1, 0, 0, 0},
|
||||
{ 0, 0, 0, 1}
|
||||
},
|
||||
[BOX_BOTTOM] = {
|
||||
{ 0, 0,-1, 0}, // bottom
|
||||
{ 0, 1, 0, 0},
|
||||
{ 1, 0, 0, 0},
|
||||
{ 0, 0, 0, 1}
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
set_vrect (const vrect_t *vrectin, vrect_t *vrect, int lineadj)
|
||||
{
|
||||
|
@ -138,6 +179,44 @@ SCR_CalcRefdef (void)
|
|||
r_data->scr_fullupdate = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
render_scene (void)
|
||||
{
|
||||
r_framecount++;
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
r_funcs->render_view ();
|
||||
r_funcs->draw_entities (r_ent_queue);
|
||||
r_funcs->draw_particles (&r_psystem);
|
||||
r_funcs->draw_transparent ();
|
||||
}
|
||||
|
||||
static void
|
||||
render_side (int side)
|
||||
{
|
||||
mat4f_t camera;
|
||||
mat4f_t camera_inverse;
|
||||
mat4f_t rotinv;
|
||||
|
||||
memcpy (camera, r_refdef.camera, sizeof (camera));
|
||||
memcpy (camera_inverse, r_refdef.camera_inverse, sizeof (camera_inverse));
|
||||
mmulf (r_refdef.camera, camera, box_rotations[side]);
|
||||
mat4ftranspose (rotinv, box_rotations[side]);
|
||||
mmulf (r_refdef.camera_inverse, rotinv, camera_inverse);
|
||||
|
||||
//FIXME see fixme in r_screen.c
|
||||
r_refdef.frame.mat[0] = -r_refdef.camera[1];
|
||||
r_refdef.frame.mat[1] = r_refdef.camera[0];
|
||||
r_refdef.frame.mat[2] = r_refdef.camera[2];
|
||||
r_refdef.frame.mat[3] = r_refdef.camera[3];
|
||||
|
||||
r_data->refdef->fov_x = r_data->refdef->fov_y = 90;
|
||||
r_funcs->bind_framebuffer (&fisheye_cube_map[side]);
|
||||
render_scene ();
|
||||
|
||||
memcpy (r_refdef.camera, camera, sizeof (camera));
|
||||
memcpy (r_refdef.camera_inverse, camera_inverse, sizeof (camera_inverse));
|
||||
}
|
||||
|
||||
/*
|
||||
SCR_UpdateScreen
|
||||
|
||||
|
@ -158,6 +237,10 @@ SCR_UpdateScreen (transform_t *camera, double realtime, SCR_Func *scr_funcs)
|
|||
r_time1 = Sys_DoubleTime ();
|
||||
}
|
||||
|
||||
if (scr_fisheye->int_val && !fisheye_cube_map) {
|
||||
fisheye_cube_map = r_funcs->create_cube_map (r_data->vid->height);
|
||||
}
|
||||
|
||||
refdef_t *refdef = r_data->refdef;
|
||||
if (camera) {
|
||||
Transform_GetWorldMatrix (camera, refdef->camera);
|
||||
|
@ -181,10 +264,6 @@ SCR_UpdateScreen (transform_t *camera, double realtime, SCR_Func *scr_funcs)
|
|||
R_SetFrustum (refdef->frustum, &refdef->frame,
|
||||
refdef->fov_x, refdef->fov_y);
|
||||
|
||||
//FIXME breaks fisheye as it calls the view render many times
|
||||
EntQueue_Clear (r_ent_queue);
|
||||
r_framecount++;
|
||||
|
||||
r_data->realtime = realtime;
|
||||
scr_copytop = r_data->scr_copyeverything = 0;
|
||||
|
||||
|
@ -203,7 +282,8 @@ SCR_UpdateScreen (transform_t *camera, double realtime, SCR_Func *scr_funcs)
|
|||
r_dowarp = refdef->viewleaf->contents <= CONTENTS_WATER;
|
||||
}
|
||||
if (r_dowarp && !warp_buffer) {
|
||||
warp_buffer = r_funcs->create_frame_buffer (r_data->vid->width, r_data->vid->height);
|
||||
warp_buffer = r_funcs->create_frame_buffer (r_data->vid->width,
|
||||
r_data->vid->height);
|
||||
}
|
||||
}
|
||||
R_MarkLeaves ();
|
||||
|
@ -213,10 +293,21 @@ SCR_UpdateScreen (transform_t *camera, double realtime, SCR_Func *scr_funcs)
|
|||
if (r_dowarp) {
|
||||
r_funcs->bind_framebuffer (warp_buffer);
|
||||
}
|
||||
r_funcs->render_view ();
|
||||
r_funcs->draw_entities (r_ent_queue);
|
||||
r_funcs->draw_particles (&r_psystem);
|
||||
r_funcs->draw_transparent ();
|
||||
if (scr_fisheye->int_val) {
|
||||
switch (scr_fviews->int_val) {
|
||||
case 6: render_side (BOX_BEHIND);
|
||||
case 5: render_side (BOX_BOTTOM);
|
||||
case 4: render_side (BOX_TOP);
|
||||
case 3: render_side (BOX_LEFT);
|
||||
case 2: render_side (BOX_RIGHT);
|
||||
default:render_side (BOX_FRONT);
|
||||
}
|
||||
r_funcs->bind_framebuffer (0);
|
||||
r_funcs->post_process (fisheye_cube_map);
|
||||
} else {
|
||||
render_scene ();
|
||||
r_funcs->post_process (warp_buffer);
|
||||
}
|
||||
r_funcs->set_2d (0);
|
||||
view_draw (r_data->scr_view);
|
||||
r_funcs->set_2d (1);
|
||||
|
|
166
libs/video/renderer/sw/sw_fisheye.c
Normal file
166
libs/video/renderer/sw/sw_fisheye.c
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
sw_fisheye.c
|
||||
|
||||
SW fisheye rendering
|
||||
|
||||
Copyright (C) 2003 Arkadi Shishlov <arkadi@it.lv>
|
||||
Copyright (C) 2022 Bill Currie <bill@taniwha.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/render.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "r_internal.h"
|
||||
#include "vid_internal.h"
|
||||
#include "vid_sw.h"
|
||||
|
||||
static void
|
||||
fisheyelookuptable (byte **buf, int width, int height, framebuffer_t *cube,
|
||||
double fov)
|
||||
{
|
||||
int cube_size = cube->width;
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
double dx = x - width / 2;
|
||||
double dy = -(y - height / 2);
|
||||
double yaw = sqrt (dx * dx + dy * dy) * fov / width;
|
||||
double roll = atan2 (dy, dx);
|
||||
double sx = sin (yaw) * cos (roll);
|
||||
double sy = sin (yaw) * sin (roll);
|
||||
double sz = cos (yaw);
|
||||
|
||||
// determine which side of the box we need
|
||||
double abs_x = fabs (sx);
|
||||
double abs_y = fabs (sy);
|
||||
double abs_z = fabs (sz);
|
||||
int side;
|
||||
double xs = 0, ys = 0;
|
||||
|
||||
if (abs_x > abs_y) {
|
||||
if (abs_x > abs_z) {
|
||||
side = ((sx > 0.0) ? BOX_RIGHT : BOX_LEFT);
|
||||
} else {
|
||||
side = ((sz > 0.0) ? BOX_FRONT : BOX_BEHIND);
|
||||
}
|
||||
} else {
|
||||
if (abs_y > abs_z) {
|
||||
side = ((sy > 0.0) ? BOX_TOP : BOX_BOTTOM);
|
||||
} else {
|
||||
side = ((sz > 0.0) ? BOX_FRONT : BOX_BEHIND);
|
||||
}
|
||||
}
|
||||
|
||||
#define RC(x) ((x / 2) + 0.5)
|
||||
#define R2(x) ((x / 2) + 0.5)
|
||||
|
||||
// scale up our vector [x,y,z] to the box
|
||||
switch(side) {
|
||||
case BOX_FRONT: xs = RC( sx / sz); ys = R2(-sy / sz); break;
|
||||
case BOX_BEHIND: xs = RC(-sx / -sz); ys = R2(-sy / -sz); break;
|
||||
case BOX_LEFT: xs = RC( sz / -sx); ys = R2(-sy / -sx); break;
|
||||
case BOX_RIGHT: xs = RC(-sz / sx); ys = R2(-sy / sx); break;
|
||||
case BOX_TOP: xs = RC( sx / sy); ys = R2( sz / sy); break;
|
||||
case BOX_BOTTOM: xs = RC( sx / -sy); ys = R2( sz / sy); break;
|
||||
}
|
||||
|
||||
xs = bound (0, xs, 1);
|
||||
ys = bound (0, ys, 1);
|
||||
int sxs = xs * (cube_size - 1);
|
||||
int sys = ys * (cube_size - 1);
|
||||
sw_framebuffer_t *fb = cube[side].buffer;
|
||||
*buf++ = fb->color + sys * fb->rowbytes + sxs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
renderlookup (byte **offs)
|
||||
{
|
||||
framebuffer_t *fb = sw_ctx->framebuffer;
|
||||
sw_framebuffer_t *swfb = fb->buffer;
|
||||
byte *p = swfb->color;
|
||||
unsigned x, y;
|
||||
for (y = 0; y < fb->height; y++) {
|
||||
for (x = 0; x < fb->width; x++, offs++)
|
||||
p[x] = **offs;
|
||||
p += swfb->rowbytes;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
R_RenderFisheye (framebuffer_t *cube)
|
||||
{
|
||||
int width = r_refdef.vrect.width;
|
||||
int height = r_refdef.vrect.height;
|
||||
int fov = scr_ffov->int_val;
|
||||
static int pwidth = -1;
|
||||
static int pheight = -1;
|
||||
static int pfov = -1;
|
||||
static unsigned psize = -1;
|
||||
static byte **offs = NULL;
|
||||
|
||||
if (fov < 1) fov = 1;
|
||||
|
||||
if (pwidth != width || pheight != height || pfov != fov
|
||||
|| psize != cube->width) {
|
||||
if (offs) free (offs);
|
||||
offs = malloc (width*height*sizeof(byte*));
|
||||
SYS_CHECKMEM (offs);
|
||||
pwidth = width;
|
||||
pheight = height;
|
||||
pfov = fov;
|
||||
psize = cube->width;
|
||||
fisheyelookuptable (offs, width, height, cube, fov*M_PI/180.0);
|
||||
}
|
||||
#if 0
|
||||
sw_framebuffer_t *fb = cube[0].buffer;
|
||||
int rowbytes = fb->rowbytes;
|
||||
int csize = cube[0].width;
|
||||
for (int s = 0; s < 6; s++) {
|
||||
fb = cube[s].buffer;
|
||||
memset (fb->color, 31, csize);
|
||||
memset (fb->color + (csize - 1) * rowbytes, 31, csize);
|
||||
for (int y = 0; y < csize; y++) {
|
||||
fb->color[y * rowbytes] = 31;
|
||||
fb->color[y * rowbytes + csize - 1] = 31;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
renderlookup (offs);
|
||||
}
|
|
@ -713,8 +713,6 @@ R_RenderView_ (void)
|
|||
R_HighFPPrecision ();
|
||||
}
|
||||
|
||||
static void R_RenderViewFishEye (void);
|
||||
|
||||
void
|
||||
R_RenderView (void)
|
||||
{
|
||||
|
@ -733,10 +731,8 @@ R_RenderView (void)
|
|||
|
||||
if ((intptr_t) (&colormap) & 3)
|
||||
Sys_Error ("Globals are missaligned");
|
||||
if (!scr_fisheye->int_val)
|
||||
R_RenderView_ ();
|
||||
else
|
||||
R_RenderViewFishEye ();
|
||||
|
||||
R_RenderView_ ();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -751,224 +747,6 @@ R_InitTurb (void)
|
|||
}
|
||||
}
|
||||
|
||||
#define BOX_FRONT 0
|
||||
#define BOX_RIGHT 1
|
||||
#define BOX_BEHIND 2
|
||||
#define BOX_LEFT 3
|
||||
#define BOX_TOP 4
|
||||
#define BOX_BOTTOM 5
|
||||
#if 0
|
||||
static mat4f_t box_rotations[] = {
|
||||
{ { 1, 0, 0, 0}, // front
|
||||
{ 0, 1, 0, 0},
|
||||
{ 0, 0, 1, 0},
|
||||
{ 0, 0, 0, 1} },
|
||||
{ { 0,-1, 0, 0}, // right
|
||||
{ 1, 0, 0, 0},
|
||||
{ 0, 0, 1, 0},
|
||||
{ 0, 0, 0, 1} },
|
||||
{ {-1, 0, 0, 0}, // back
|
||||
{ 0,-1, 0, 0},
|
||||
{ 0, 0, 1, 0},
|
||||
{ 0, 0, 0, 1} },
|
||||
{ { 0, 1, 0, 0}, // left
|
||||
{-1, 0, 0, 0},
|
||||
{ 0, 0, 1, 0},
|
||||
{ 0, 0, 0, 1} },
|
||||
{ { 0, 0, 1, 0}, // top
|
||||
{ 0, 1, 0, 0},
|
||||
{-1, 0, 0, 0},
|
||||
{ 0, 0, 0, 1} },
|
||||
{ { 0, 0,-1, 0}, // bottom
|
||||
{ 0, 1, 0, 0},
|
||||
{ 1, 0, 0, 0},
|
||||
{ 0, 0, 0, 1} },
|
||||
};
|
||||
#endif
|
||||
static int sw_cube_map_size;
|
||||
|
||||
static void
|
||||
fisheyelookuptable (byte **buf, int width, int height, byte *scrp, double fov)
|
||||
{
|
||||
int x, y;
|
||||
int scrsize = sw_cube_map_size * sw_cube_map_size;
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
for (x = 0; x < width; x++) {
|
||||
double dx = x-width/2;
|
||||
double dy = -(y-height/2);
|
||||
double yaw = sqrt(dx*dx+dy*dy)*fov/((double)width);
|
||||
double roll = atan2(dy, dx);
|
||||
double sx = sin(yaw) * cos(roll);
|
||||
double sy = sin(yaw) * sin(roll);
|
||||
double sz = cos(yaw);
|
||||
|
||||
// determine which side of the box we need
|
||||
double abs_x = fabs(sx);
|
||||
double abs_y = fabs(sy);
|
||||
double abs_z = fabs(sz);
|
||||
int side;
|
||||
double xs = 0, ys = 0;
|
||||
if (abs_x > abs_y) {
|
||||
if (abs_x > abs_z) { side = ((sx > 0.0) ? BOX_RIGHT : BOX_LEFT); }
|
||||
else { side = ((sz > 0.0) ? BOX_FRONT : BOX_BEHIND); }
|
||||
} else {
|
||||
if (abs_y > abs_z) { side = ((sy > 0.0) ? BOX_TOP : BOX_BOTTOM); }
|
||||
else { side = ((sz > 0.0) ? BOX_FRONT : BOX_BEHIND); }
|
||||
}
|
||||
|
||||
#define RC(x) ((x / 2) + 0.5)
|
||||
#define R2(x) ((x / 2) + 0.5)
|
||||
|
||||
// scale up our vector [x,y,z] to the box
|
||||
switch(side) {
|
||||
case BOX_FRONT: xs = RC( sx / sz); ys = R2(-sy / sz); break;
|
||||
case BOX_BEHIND: xs = RC(-sx / -sz); ys = R2(-sy / -sz); break;
|
||||
case BOX_LEFT: xs = RC( sz / -sx); ys = R2(-sy / -sx); break;
|
||||
case BOX_RIGHT: xs = RC(-sz / sx); ys = R2(-sy / sx); break;
|
||||
case BOX_TOP: xs = RC( sx / sy); ys = R2( sz / sy); break;
|
||||
case BOX_BOTTOM: xs = RC( sx / -sy); ys = R2( sz / sy); break;
|
||||
}
|
||||
|
||||
if (xs < 0.0) xs = 0.0;
|
||||
if (xs >= 1.0) xs = 0.999;
|
||||
if (ys < 0.0) ys = 0.0;
|
||||
if (ys >= 1.0) ys = 0.999;
|
||||
int sxs = xs * sw_cube_map_size;
|
||||
int sys = ys * sw_cube_map_size;
|
||||
*buf++ = scrp+side * scrsize + sys * sw_cube_map_size + sxs;
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
static void
|
||||
rendercopy (void *dest)
|
||||
{
|
||||
void *p = vid.buffer;
|
||||
// XXX
|
||||
vid.buffer = dest;
|
||||
R_RenderView_ ();
|
||||
vid.buffer = p;
|
||||
}
|
||||
|
||||
static void
|
||||
renderside (byte *bufs, int side)
|
||||
{
|
||||
mat4f_t camera;
|
||||
mat4f_t camera_inverse;
|
||||
mat4f_t rotinv;
|
||||
|
||||
memcpy (camera, r_refdef.camera, sizeof (camera));
|
||||
memcpy (camera_inverse, r_refdef.camera_inverse, sizeof (camera_inverse));
|
||||
mmulf (r_refdef.camera, camera, box_rotations[side]);
|
||||
mat4ftranspose (rotinv, box_rotations[side]);
|
||||
mmulf (r_refdef.camera_inverse, rotinv, camera_inverse);
|
||||
|
||||
//FIXME see fixme in r_screen.c
|
||||
r_refdef.frame.mat[0] = -r_refdef.camera[1];
|
||||
r_refdef.frame.mat[1] = r_refdef.camera[0];
|
||||
r_refdef.frame.mat[2] = r_refdef.camera[2];
|
||||
r_refdef.frame.mat[3] = r_refdef.camera[3];
|
||||
|
||||
float fov_x = r_refdef.fov_x;
|
||||
float fov_y = r_refdef.fov_y;
|
||||
unsigned width = vid.width;
|
||||
unsigned height = vid.height;
|
||||
vrect_t rect = r_refdef.vrect;
|
||||
r_refdef.fov_x = r_refdef.fov_y = 90;
|
||||
r_refdef.vrect.x = r_refdef.vrect.y = 0;
|
||||
r_refdef.vrect.height = r_refdef.vrect.width = sw_cube_map_size;
|
||||
vid.rowbytes = vid.height = vid.width = sw_cube_map_size;
|
||||
R_ViewChanged ();
|
||||
|
||||
rendercopy (bufs);
|
||||
|
||||
vid.rowbytes = width;
|
||||
r_refdef.vrect = rect;
|
||||
vid.height = height;
|
||||
vid.width = width;
|
||||
r_refdef.fov_x = fov_x;
|
||||
r_refdef.fov_y = fov_y;
|
||||
|
||||
memcpy (r_refdef.camera, camera, sizeof (camera));
|
||||
memcpy (r_refdef.camera_inverse, camera_inverse, sizeof (camera_inverse));
|
||||
}
|
||||
#endif
|
||||
static void
|
||||
renderlookup (byte **offs, byte* bufs)
|
||||
{
|
||||
framebuffer_t *fb = sw_ctx->framebuffer;
|
||||
sw_framebuffer_t *swfb = fb->buffer;
|
||||
byte *p = swfb->color;
|
||||
unsigned x, y;
|
||||
for (y = 0; y < fb->height; y++) {
|
||||
for (x = 0; x < fb->width; x++, offs++)
|
||||
p[x] = **offs;
|
||||
p += swfb->rowbytes;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
R_RenderViewFishEye (void)
|
||||
{
|
||||
sw_cube_map_size = vid.height;
|
||||
int width = vid.width; //r_refdef.vrect.width;
|
||||
int height = vid.height; //r_refdef.vrect.height;
|
||||
int scrsize = sw_cube_map_size * sw_cube_map_size;
|
||||
int fov = scr_ffov->int_val;
|
||||
int views = scr_fviews->int_val;
|
||||
static int pwidth = -1;
|
||||
static int pheight = -1;
|
||||
static int pfov = -1;
|
||||
static int pviews = -1;
|
||||
static byte *scrbufs = NULL;
|
||||
static byte **offs = NULL;
|
||||
|
||||
if (fov < 1) fov = 1;
|
||||
|
||||
if (pwidth != width || pheight != height || pfov != fov) {
|
||||
if (scrbufs) free (scrbufs);
|
||||
if (offs) free (offs);
|
||||
// front|right|back|left|top|bottom
|
||||
scrbufs = malloc (scrsize*6);
|
||||
SYS_CHECKMEM (scrbufs);
|
||||
offs = malloc (width*height*sizeof(byte*));
|
||||
SYS_CHECKMEM (offs);
|
||||
pwidth = width;
|
||||
pheight = height;
|
||||
pfov = fov;
|
||||
fisheyelookuptable (offs, width, height, scrbufs, fov*M_PI/180.0);
|
||||
}
|
||||
|
||||
if (views != pviews) {
|
||||
pviews = views;
|
||||
memset (scrbufs, 0, scrsize*6);
|
||||
}
|
||||
#if 0
|
||||
switch (views) {
|
||||
case 6: renderside (scrbufs + scrsize * BOX_BEHIND, BOX_BEHIND);
|
||||
case 5: renderside (scrbufs + scrsize * BOX_BOTTOM, BOX_BOTTOM);
|
||||
case 4: renderside (scrbufs + scrsize * BOX_TOP, BOX_TOP);
|
||||
case 3: renderside (scrbufs + scrsize * BOX_LEFT, BOX_LEFT);
|
||||
case 2: renderside (scrbufs + scrsize * BOX_RIGHT, BOX_RIGHT);
|
||||
default: renderside (scrbufs + scrsize * BOX_FRONT, BOX_FRONT);
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
memset (scrbufs + scrsize*0, 31, sw_cube_map_size);
|
||||
memset (scrbufs + scrsize*1, 31, sw_cube_map_size);
|
||||
memset (scrbufs + scrsize*2, 31, sw_cube_map_size);
|
||||
memset (scrbufs + scrsize*3, 31, sw_cube_map_size);
|
||||
memset (scrbufs + scrsize*4, 31, sw_cube_map_size);
|
||||
memset (scrbufs + scrsize*5, 31, sw_cube_map_size);
|
||||
for (int y = 0; y < sw_cube_map_size * 6; y++) {
|
||||
scrbufs[y * sw_cube_map_size] = 31;
|
||||
scrbufs[y * sw_cube_map_size + sw_cube_map_size - 1] = 31;
|
||||
}
|
||||
#endif
|
||||
renderlookup (offs, scrbufs);
|
||||
}
|
||||
|
||||
void
|
||||
R_ClearState (void)
|
||||
{
|
||||
|
|
|
@ -268,6 +268,11 @@ gl_draw_transparent (void)
|
|||
gl_R_DrawWaterSurfaces ();
|
||||
}
|
||||
|
||||
static void
|
||||
gl_post_process (framebuffer_t *src)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gl_set_2d (int scaled)
|
||||
{
|
||||
|
@ -300,6 +305,12 @@ gl_end_frame (void)
|
|||
}
|
||||
}
|
||||
|
||||
static framebuffer_t *
|
||||
gl_create_cube_map (int size)
|
||||
{
|
||||
Sys_Error ("not implemented");
|
||||
}
|
||||
|
||||
static framebuffer_t *
|
||||
gl_create_frame_buffer (int width, int height)
|
||||
{
|
||||
|
@ -348,9 +359,11 @@ vid_render_funcs_t gl_vid_render_funcs = {
|
|||
gl_R_RenderEntities,
|
||||
gl_R_DrawParticles,
|
||||
gl_draw_transparent,
|
||||
gl_post_process,
|
||||
gl_set_2d,
|
||||
gl_end_frame,
|
||||
|
||||
gl_create_cube_map,
|
||||
gl_create_frame_buffer,
|
||||
gl_bind_framebuffer,
|
||||
|
||||
|
|
|
@ -226,6 +226,11 @@ glsl_draw_transparent (void)
|
|||
glsl_R_DrawWaterSurfaces ();
|
||||
}
|
||||
|
||||
static void
|
||||
glsl_post_process (framebuffer_t *src)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
glsl_set_2d (int scaled)
|
||||
{
|
||||
|
@ -244,6 +249,12 @@ glsl_end_frame (void)
|
|||
qfeglFlush ();
|
||||
}
|
||||
|
||||
static framebuffer_t *
|
||||
glsl_create_cube_map (int size)
|
||||
{
|
||||
Sys_Error ("not implemented");
|
||||
}
|
||||
|
||||
static framebuffer_t *
|
||||
glsl_create_frame_buffer (int width, int height)
|
||||
{
|
||||
|
@ -292,9 +303,11 @@ vid_render_funcs_t glsl_vid_render_funcs = {
|
|||
glsl_R_RenderEntities,
|
||||
glsl_R_DrawParticles,
|
||||
glsl_draw_transparent,
|
||||
glsl_post_process,
|
||||
glsl_set_2d,
|
||||
glsl_end_frame,
|
||||
|
||||
glsl_create_cube_map,
|
||||
glsl_create_frame_buffer,
|
||||
glsl_bind_framebuffer,
|
||||
|
||||
|
|
|
@ -157,14 +157,27 @@ sw_draw_transparent (void)
|
|||
}
|
||||
|
||||
static void
|
||||
sw_set_2d (int scaled)
|
||||
sw_post_process (framebuffer_t *src)
|
||||
{
|
||||
if (!scaled && r_dowarp) {
|
||||
int bind = 0;
|
||||
|
||||
if (scr_fisheye->int_val) {
|
||||
R_RenderFisheye (src);
|
||||
bind = 1;
|
||||
} else if (r_dowarp) {
|
||||
D_WarpScreen ();
|
||||
bind = 1;
|
||||
}
|
||||
if (bind) {
|
||||
sw_bind_framebuffer (0);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sw_set_2d (int scaled)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
sw_end_frame (void)
|
||||
{
|
||||
|
@ -198,6 +211,33 @@ sw_end_frame (void)
|
|||
sw_ctx->update (sw_ctx, &vrect);
|
||||
}
|
||||
|
||||
static framebuffer_t *
|
||||
sw_create_cube_map (int side)
|
||||
{
|
||||
size_t pixels = side * side; // per face
|
||||
size_t size = sizeof (framebuffer_t) * 6;
|
||||
size += sizeof (sw_framebuffer_t) * 6;
|
||||
size += pixels * 6; // color buffer
|
||||
// depth buffer, scan table and zspantable are shared between cube faces
|
||||
// FIXME need *6 depth and zspan for multi-threaded
|
||||
size += pixels * sizeof (short); // depth buffer
|
||||
|
||||
framebuffer_t *cube = malloc (size);
|
||||
__auto_type buffer_base = (sw_framebuffer_t *) &cube[6];
|
||||
byte *color_base = (byte *) &buffer_base[6];
|
||||
short *depth_base = (short *) (color_base + 6 * pixels);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
cube[i].width = side;
|
||||
cube[i].height = side;
|
||||
__auto_type buffer = buffer_base + i;
|
||||
cube[i].buffer = buffer;
|
||||
buffer->color = color_base + i * pixels;
|
||||
buffer->depth = depth_base;
|
||||
buffer->rowbytes = side;
|
||||
}
|
||||
return cube;
|
||||
}
|
||||
|
||||
static framebuffer_t *
|
||||
sw_create_frame_buffer (int width, int height)
|
||||
{
|
||||
|
@ -297,9 +337,11 @@ vid_render_funcs_t sw_vid_render_funcs = {
|
|||
R_DrawEntitiesOnList,
|
||||
R_DrawParticles,
|
||||
sw_draw_transparent,
|
||||
sw_post_process,
|
||||
sw_set_2d,
|
||||
sw_end_frame,
|
||||
|
||||
sw_create_cube_map,
|
||||
sw_create_frame_buffer,
|
||||
sw_bind_framebuffer,
|
||||
|
||||
|
|
|
@ -308,6 +308,11 @@ vulkan_draw_transparent (void)
|
|||
{
|
||||
}
|
||||
|
||||
static void
|
||||
vulkan_post_process (framebuffer_t *src)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
vulkan_set_2d (int scaled)
|
||||
{
|
||||
|
@ -418,6 +423,12 @@ vulkan_end_frame (void)
|
|||
vulkan_ctx->curFrame %= vulkan_ctx->frames.size;
|
||||
}
|
||||
|
||||
static framebuffer_t *
|
||||
vulkan_create_cube_map (int size)
|
||||
{
|
||||
Sys_Error ("not implemented");
|
||||
}
|
||||
|
||||
static framebuffer_t *
|
||||
vulkan_create_frame_buffer (int width, int height)
|
||||
{
|
||||
|
@ -705,9 +716,11 @@ vid_render_funcs_t vulkan_vid_render_funcs = {
|
|||
vulkan_draw_entities,
|
||||
vulkan_draw_particles,
|
||||
vulkan_draw_transparent,
|
||||
vulkan_post_process,
|
||||
vulkan_set_2d,
|
||||
vulkan_end_frame,
|
||||
|
||||
vulkan_create_cube_map,
|
||||
vulkan_create_frame_buffer,
|
||||
vulkan_bind_framebuffer,
|
||||
|
||||
|
|
Loading…
Reference in a new issue