switch(c)
{
case VF_MIN:
- r_refdef.view.x = (int)(f[0] * vid.width / vid_conwidth.value);
- r_refdef.view.y = (int)(f[1] * vid.height / vid_conheight.value);
+ r_refdef.view.x = (int)(f[0]);
+ r_refdef.view.y = (int)(f[1]);
break;
case VF_MIN_X:
- r_refdef.view.x = (int)(k * vid.width / vid_conwidth.value);
+ r_refdef.view.x = (int)(k);
break;
case VF_MIN_Y:
- r_refdef.view.y = (int)(k * vid.height / vid_conheight.value);
+ r_refdef.view.y = (int)(k);
break;
case VF_SIZE:
- r_refdef.view.width = (int)(f[0] * vid.width / vid_conwidth.value);
- r_refdef.view.height = (int)(f[1] * vid.height / vid_conheight.value);
+ r_refdef.view.width = (int)(f[0]);
+ r_refdef.view.height = (int)(f[1]);
break;
case VF_SIZE_X:
- r_refdef.view.width = (int)(k * vid.width / vid_conwidth.value);
+ r_refdef.view.width = (int)(k);
break;
case VF_SIZE_Y:
- r_refdef.view.height = (int)(k * vid.height / vid_conheight.value);
+ r_refdef.view.height = (int)(k);
break;
case VF_VIEWPORT:
- r_refdef.view.x = (int)(f[0] * vid.width / vid_conwidth.value);
- r_refdef.view.y = (int)(f[1] * vid.height / vid_conheight.value);
+ r_refdef.view.x = (int)(f[0]);
+ r_refdef.view.y = (int)(f[1]);
f = PRVM_G_VECTOR(OFS_PARM2);
- r_refdef.view.width = (int)(f[0] * vid.width / vid_conwidth.value);
- r_refdef.view.height = (int)(f[1] * vid.height / vid_conheight.value);
+ r_refdef.view.width = (int)(f[0]);
+ r_refdef.view.height = (int)(f[1]);
break;
case VF_FOV:
r_refdef.view.frustum_x = tan(f[0] * M_PI / 360.0);r_refdef.view.ortho_x = f[0];
VM_SAFEPARMCOUNT(1, VM_CL_unproject);
f = PRVM_G_VECTOR(OFS_PARM0);
- VectorSet(temp, f[2], f[0] * f[2] * -r_refdef.view.frustum_x * 2.0 / r_refdef.view.width, f[1] * f[2] * -r_refdef.view.frustum_y * 2.0 / r_refdef.view.height);
+ VectorSet(temp, f[2], (-1.0 + 2.0 * (f[0] - r_refdef.view.x)) / r_refdef.view.width * f[2] * -r_refdef.view.frustum_x, (-1.0 + 2.0 * (f[1] - r_refdef.view.y)) / r_refdef.view.height * f[2] * -r_refdef.view.frustum_y);
Matrix4x4_Transform(&r_refdef.view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
}
f = PRVM_G_VECTOR(OFS_PARM0);
Matrix4x4_Invert_Simple(&m, &r_refdef.view.matrix);
Matrix4x4_Transform(&m, f, v);
- VectorSet(PRVM_G_VECTOR(OFS_RETURN), v[1]/v[0]/-r_refdef.view.frustum_x*0.5*r_refdef.view.width, v[2]/v[0]/-r_refdef.view.frustum_y*r_refdef.view.height*0.5, v[0]);
+ VectorSet(PRVM_G_VECTOR(OFS_RETURN), r_refdef.view.x + r_refdef.view.width*0.5*(1.0+v[1]/v[0]/-r_refdef.view.frustum_x), r_refdef.view.y + r_refdef.view.height*0.5*(1.0+v[2]/v[0]/-r_refdef.view.frustum_y), v[0]);
}
//#330 float(float stnum) getstatf (EXT_CSQC)
{
mempool_t *pool;
qboolean initialized;
+ double progstarttime;
int max_vertices;
int num_vertices;
R_RenderView();
polys->num_vertices = polys->num_triangles = 0;
+ polys->progstarttime = prog->starttime;
}
static void VM_ResizePolygons(vmpolygons_t *polys)
{
int surfacelistindex;
vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+ if(polys->progstarttime != prog->starttime) // from other progs? won't draw these (this can cause crashes!)
+ return;
R_Mesh_ResetTextureState();
R_Mesh_Matrix(&identitymatrix);
GL_CullFace(GL_NONE);
int numtriangles = 0;
rtexture_t *tex = polys->data_triangles[surfacelist[surfacelistindex]].texture;
int drawflag = polys->data_triangles[surfacelist[surfacelistindex]].drawflag;
+ // this can't call _DrawQ_ProcessDrawFlag, but should be in sync with it
+ // FIXME factor this out
if(drawflag == DRAWFLAG_ADDITIVE)
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
else if(drawflag == DRAWFLAG_MODULATE)
GL_BlendFunc(GL_DST_COLOR, GL_ZERO);
else if(drawflag == DRAWFLAG_2XMODULATE)
GL_BlendFunc(GL_DST_COLOR,GL_SRC_COLOR);
+ else if(drawflag == DRAWFLAG_SCREEN)
+ GL_BlendFunc(GL_ONE_MINUS_DST_COLOR,GL_ONE);
else
GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
R_Mesh_TexBind(0, R_GetTexture(tex));
void VM_CL_R_PolygonBegin (void)
{
const char *picname;
+ skinframe_t *sf;
vmpolygons_t* polys = vmpolygons + PRVM_GetProgNr();
+ int tf;
+
+ // TODO instead of using skinframes here (which provides the benefit of
+ // better management of flags, and is more suited for 3D rendering), what
+ // about supporting Q3 shaders?
VM_SAFEPARMCOUNT(2, VM_CL_R_PolygonBegin);
if (!polys->initialized)
VM_InitPolygons(polys);
+ if(polys->progstarttime != prog->starttime)
+ {
+ // from another progs? then reset the polys first (fixes crashes on map change, because that can make skinframe textures invalid)
+ polys->num_vertices = polys->num_triangles = 0;
+ polys->progstarttime = prog->starttime;
+ }
if (polys->begin_active)
{
VM_Warning("VM_CL_R_PolygonBegin: called twice without VM_CL_R_PolygonBegin after first\n");
return;
}
picname = PRVM_G_STRING(OFS_PARM0);
- polys->begin_texture = picname[0] ? Draw_CachePic_Flags (picname, CACHEPICFLAG_NOCLAMP)->tex : r_texture_white;
- polys->begin_drawflag = (int)PRVM_G_FLOAT(OFS_PARM1);
+
+ sf = NULL;
+ if(*picname)
+ {
+ tf = TEXF_ALPHA;
+ if((int)PRVM_G_FLOAT(OFS_PARM1) & DRAWFLAG_MIPMAP)
+ tf |= TEXF_MIPMAP;
+
+ do
+ {
+ sf = R_SkinFrame_FindNextByName(sf, picname);
+ }
+ while(sf && sf->textureflags != tf);
+
+ if(!sf || !sf->base)
+ sf = R_SkinFrame_LoadExternal(picname, tf, true);
+
+ if(sf)
+ R_SkinFrame_MarkUsed(sf);
+ }
+
+ polys->begin_texture = (sf && sf->base) ? sf->base : r_texture_white;
+ polys->begin_drawflag = (int)PRVM_G_FLOAT(OFS_PARM1) & DRAWFLAG_MASK;
polys->begin_vertices = 0;
polys->begin_active = true;
}