r_refdef.view.isoverlay = false;
// FIXME: restore cl.csqc_origin
// FIXME: restore cl.csqc_angles
- cl.csqc_vidvars.drawworld = r_drawworld.integer != 0;
+ cl.csqc_vidvars.drawworld = r_drawworld.integer;
cl.csqc_vidvars.drawenginesbar = false;
cl.csqc_vidvars.drawcrosshair = false;
}
prog->globals.client->time = cl.time;
for(i=1;i<prog->num_edicts;i++)
{
+ // so we can easily check if CSQC entity #edictnum is currently drawn
+ cl.csqcrenderentities[i].entitynumber = 0;
ed = &prog->edicts[i];
if(ed->priv.required->free)
continue;
case VF_MIN:
r_refdef.view.x = (int)(f[0]);
r_refdef.view.y = (int)(f[1]);
+ DrawQ_RecalcView();
break;
case VF_MIN_X:
r_refdef.view.x = (int)(k);
+ DrawQ_RecalcView();
break;
case VF_MIN_Y:
r_refdef.view.y = (int)(k);
+ DrawQ_RecalcView();
break;
case VF_SIZE:
r_refdef.view.width = (int)(f[0]);
r_refdef.view.height = (int)(f[1]);
+ DrawQ_RecalcView();
break;
case VF_SIZE_X:
r_refdef.view.width = (int)(k);
+ DrawQ_RecalcView();
break;
case VF_SIZE_Y:
r_refdef.view.height = (int)(k);
+ DrawQ_RecalcView();
break;
case VF_VIEWPORT:
r_refdef.view.x = (int)(f[0]);
f = PRVM_G_VECTOR(OFS_PARM2);
r_refdef.view.width = (int)(f[0]);
r_refdef.view.height = (int)(f[1]);
+ DrawQ_RecalcView();
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);
- if(v_flipped.integer)
- f[0] = (2 * r_refdef.view.x + r_refdef.view.width) * (vid_conwidth.integer / (float) vid.width) - f[0];
VectorSet(temp,
f[2],
- (-1.0 + 2.0 * (f[0] / (vid_conwidth.integer / (float) vid.width) - r_refdef.view.x) / r_refdef.view.width) * f[2] * -r_refdef.view.frustum_x,
- (-1.0 + 2.0 * (f[1] / (vid_conheight.integer / (float) vid.height) - r_refdef.view.y) / r_refdef.view.height) * f[2] * -r_refdef.view.frustum_y);
+ (-1.0 + 2.0 * (f[0] / vid_conwidth.integer)) * f[2] * -r_refdef.view.frustum_x,
+ (-1.0 + 2.0 * (f[1] / vid_conheight.integer)) * f[2] * -r_refdef.view.frustum_y);
+ if(v_flipped.integer)
+ temp[1] = -temp[1];
Matrix4x4_Transform(&r_refdef.view.matrix, temp, PRVM_G_VECTOR(OFS_RETURN));
}
if(v_flipped.integer)
v[1] = -v[1];
VectorSet(PRVM_G_VECTOR(OFS_RETURN),
- (vid_conwidth.integer / (float) vid.width) * (r_refdef.view.x + r_refdef.view.width*0.5*(1.0+v[1]/v[0]/-r_refdef.view.frustum_x)),
- (vid_conheight.integer / (float) vid.height) * (r_refdef.view.y + r_refdef.view.height*0.5*(1.0+v[2]/v[0]/-r_refdef.view.frustum_y)),
+ vid_conwidth.integer * (0.5*(1.0+v[1]/v[0]/-r_refdef.view.frustum_x)),
+ vid_conheight.integer * (0.5*(1.0+v[2]/v[0]/-r_refdef.view.frustum_y)),
v[0]);
+ // explanation:
+ // after transforming, relative position to viewport (0..1) = 0.5 * (1 + v[2]/v[0]/-frustum_{x \or y})
+ // as 2D drawing honors the viewport too, to get the same pixel, we simply multiply this by conwidth/height
}
//#330 float(float stnum) getstatf (EXT_CSQC)
static void VM_CL_boxparticles (void)
{
int effectnum;
- prvm_edict_t *own;
+ // prvm_edict_t *own;
float *origin_from, *origin_to, *dir_from, *dir_to;
float count;
int flags;
VM_SAFEPARMCOUNTRANGE(7, 8, VM_CL_boxparticles);
effectnum = (int)PRVM_G_FLOAT(OFS_PARM0);
- own = PRVM_G_EDICT(OFS_PARM1); // TODO find use for this
+ // own = PRVM_G_EDICT(OFS_PARM1); // TODO find use for this
origin_from = PRVM_G_VECTOR(OFS_PARM2);
origin_to = PRVM_G_VECTOR(OFS_PARM3);
dir_from = PRVM_G_VECTOR(OFS_PARM4);
void VM_CL_ParticleThemeFromGlobals(vmparticletheme_t *theme)
{
theme->typeindex = (unsigned short)*vmpartspawner.particle_type;
- theme->blendmode = (pblend_t)(int)*vmpartspawner.particle_blendmode;
- theme->orientation = (porientation_t)(int)*vmpartspawner.particle_orientation;
+ theme->blendmode = (pblend_t)*vmpartspawner.particle_blendmode;
+ theme->orientation = (porientation_t)*vmpartspawner.particle_orientation;
theme->color1 = ((int)vmpartspawner.particle_color1[0] << 16) + ((int)vmpartspawner.particle_color1[1] << 8) + ((int)vmpartspawner.particle_color1[2]);
theme->color2 = ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]);
theme->tex = (int)*vmpartspawner.particle_tex;
if (prog->argc < 3) // global-set particle
{
- part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)(vmpartspawner.particle_color1[0]) << 16) + ((int)(vmpartspawner.particle_color1[1]) << 8) + ((int)(vmpartspawner.particle_color1[2])), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)(int)*vmpartspawner.particle_blendmode, (porientation_t)(int)*vmpartspawner.particle_orientation, (int)(vmpartspawner.particle_staincolor1[0])*65536 + (int)(vmpartspawner.particle_staincolor1[1])*256 + (int)(vmpartspawner.particle_staincolor1[2]), (int)(vmpartspawner.particle_staincolor2[0])*65536 + (int)(vmpartspawner.particle_staincolor2[1])*256 + (int)(vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
+ part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)(vmpartspawner.particle_color1[0]) << 16) + ((int)(vmpartspawner.particle_color1[1]) << 8) + ((int)(vmpartspawner.particle_color1[2])), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)*vmpartspawner.particle_blendmode, (porientation_t)*vmpartspawner.particle_orientation, (int)(vmpartspawner.particle_staincolor1[0])*65536 + (int)(vmpartspawner.particle_staincolor1[1])*256 + (int)(vmpartspawner.particle_staincolor1[2]), (int)(vmpartspawner.particle_staincolor2[0])*65536 + (int)(vmpartspawner.particle_staincolor2[1])*256 + (int)(vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
if (!part)
{
PRVM_G_FLOAT(OFS_RETURN) = 0;
org = PRVM_G_VECTOR(OFS_PARM0);
dir = PRVM_G_VECTOR(OFS_PARM1);
if (prog->argc < 5) // global-set particle
- part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)vmpartspawner.particle_color1[0] << 16) + ((int)vmpartspawner.particle_color1[1] << 8) + ((int)vmpartspawner.particle_color1[2]), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)(int)*vmpartspawner.particle_blendmode, (porientation_t)(int)*vmpartspawner.particle_orientation, ((int)vmpartspawner.particle_staincolor1[0] << 16) + ((int)vmpartspawner.particle_staincolor1[1] << 8) + ((int)vmpartspawner.particle_staincolor1[2]), ((int)vmpartspawner.particle_staincolor2[0] << 16) + ((int)vmpartspawner.particle_staincolor2[1] << 8) + ((int)vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
+ part = CL_NewParticle(org, (unsigned short)*vmpartspawner.particle_type, ((int)vmpartspawner.particle_color1[0] << 16) + ((int)vmpartspawner.particle_color1[1] << 8) + ((int)vmpartspawner.particle_color1[2]), ((int)vmpartspawner.particle_color2[0] << 16) + ((int)vmpartspawner.particle_color2[1] << 8) + ((int)vmpartspawner.particle_color2[2]), (int)*vmpartspawner.particle_tex, *vmpartspawner.particle_size, *vmpartspawner.particle_sizeincrease, *vmpartspawner.particle_alpha*256, *vmpartspawner.particle_alphafade*256, *vmpartspawner.particle_gravity, *vmpartspawner.particle_bounce, org[0], org[1], org[2], dir[0], dir[1], dir[2], *vmpartspawner.particle_airfriction, *vmpartspawner.particle_liquidfriction, *vmpartspawner.particle_originjitter, *vmpartspawner.particle_velocityjitter, (*vmpartspawner.particle_qualityreduction) ? true : false, *vmpartspawner.particle_time, *vmpartspawner.particle_stretch, (pblend_t)*vmpartspawner.particle_blendmode, (porientation_t)*vmpartspawner.particle_orientation, ((int)vmpartspawner.particle_staincolor1[0] << 16) + ((int)vmpartspawner.particle_staincolor1[1] << 8) + ((int)vmpartspawner.particle_staincolor1[2]), ((int)vmpartspawner.particle_staincolor2[0] << 16) + ((int)vmpartspawner.particle_staincolor2[1] << 8) + ((int)vmpartspawner.particle_staincolor2[2]), (int)*vmpartspawner.particle_staintex, *vmpartspawner.particle_stainalpha*256, *vmpartspawner.particle_stainsize, *vmpartspawner.particle_angle, *vmpartspawner.particle_spin, NULL);
else // themed particle
{
themenum = (int)PRVM_G_FLOAT(OFS_PARM4);
{
rtexture_t *texture;
int drawflag;
+ qboolean hasalpha;
unsigned short elements[3];
}vmpolygons_triangle_t;
unsigned short *data_sortedelement3s;
qboolean begin_active;
+ int begin_draw2d;
rtexture_t *begin_texture;
int begin_drawflag;
int begin_vertices;
float begin_vertex[VMPOLYGONS_MAXPOINTS][3];
float begin_color[VMPOLYGONS_MAXPOINTS][4];
float begin_texcoord[VMPOLYGONS_MAXPOINTS][2];
+ qboolean begin_texture_hasalpha;
} vmpolygons_t;
// FIXME: make VM_CL_R_Polygon functions use Debug_Polygon functions?
R_Mesh_ResetTextureState();
R_EntityMatrix(&identitymatrix);
GL_CullFace(GL_NONE);
- R_Mesh_PrepareVertices_Generic_Arrays(polys->num_vertices, polys->data_vertex3f, polys->data_color4f, polys->data_texcoord2f);
+ GL_DepthTest(true); // polys in 3D space shall always have depth test
+ GL_DepthRange(0, 1);
+ R_Mesh_VertexPointer(polys->data_vertex3f, 0, 0);
+ R_Mesh_ColorPointer(polys->data_color4f, 0, 0);
+ R_Mesh_TexCoordPointer(0, 2, polys->data_texcoord2f, 0, 0);
for (surfacelistindex = 0;surfacelistindex < numsurfaces;)
{
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);
+ DrawQ_ProcessDrawFlag(drawflag, polys->data_triangles[surfacelist[surfacelistindex]].hasalpha);
R_SetupShader_Generic(tex, NULL, GL_MODULATE, 1);
numtriangles = 0;
for (;surfacelistindex < numsurfaces;surfacelistindex++)
VectorCopy(polys->data_triangles[surfacelist[surfacelistindex]].elements, polys->data_sortedelement3s + 3*numtriangles);
numtriangles++;
}
- R_Mesh_Draw(0, polys->num_vertices, 0, numtriangles, NULL, NULL, 0, polys->data_sortedelement3s, NULL, 0);
+ R_Mesh_Draw(0, polys->num_vertices, 0, numtriangles, NULL, polys->data_sortedelement3s, 0, 0);
}
}
void VMPolygons_Store(vmpolygons_t *polys)
{
- if (r_refdef.draw2dstage)
+ qboolean hasalpha;
+ int i;
+
+ // detect if we have alpha
+ hasalpha = polys->begin_texture_hasalpha;
+ for(i = 0; !hasalpha && (i < polys->begin_vertices); ++i)
+ if(polys->begin_color[i][3] < 1)
+ hasalpha = true;
+
+ if (polys->begin_draw2d)
{
// draw the polygon as 2D immediately
drawqueuemesh_t mesh;
mesh.data_vertex3f = polys->begin_vertex[0];
mesh.data_color4f = polys->begin_color[0];
mesh.data_texcoord2f = polys->begin_texcoord[0];
- DrawQ_Mesh(&mesh, polys->begin_drawflag);
+ DrawQ_Mesh(&mesh, polys->begin_drawflag, hasalpha);
}
else
{
int i;
if (polys->max_triangles < polys->num_triangles + polys->begin_vertices-2)
{
- polys->max_triangles *= 2;
+ while (polys->max_triangles < polys->num_triangles + polys->begin_vertices-2)
+ polys->max_triangles *= 2;
VM_ResizePolygons(polys);
}
if (polys->num_vertices + polys->begin_vertices <= polys->max_vertices)
polys->data_triangles[polys->num_triangles].elements[0] = polys->num_vertices;
polys->data_triangles[polys->num_triangles].elements[1] = polys->num_vertices + i+1;
polys->data_triangles[polys->num_triangles].elements[2] = polys->num_vertices + i+2;
+ polys->data_triangles[polys->num_triangles].hasalpha = hasalpha;
polys->num_triangles++;
}
polys->num_vertices += polys->begin_vertices;
polys->num_vertices = 0; // otherwise it's not rendered at all and prints an error message --blub */
}
-//void(string texturename, float flag) R_BeginPolygon
+//void(string texturename, float flag[, float is2d]) R_BeginPolygon
void VM_CL_R_PolygonBegin (void)
{
const char *picname;
// better management of flags, and is more suited for 3D rendering), what
// about supporting Q3 shaders?
- VM_SAFEPARMCOUNT(2, VM_CL_R_PolygonBegin);
+ VM_SAFEPARMCOUNTRANGE(2, 3, VM_CL_R_PolygonBegin);
if (!polys->initialized)
VM_InitPolygons(polys);
}
polys->begin_texture = (sf && sf->base) ? sf->base : r_texture_white;
+ polys->begin_texture_hasalpha = (sf && sf->base) ? sf->hasalpha : false;
polys->begin_drawflag = (int)PRVM_G_FLOAT(OFS_PARM1) & DRAWFLAG_MASK;
polys->begin_vertices = 0;
polys->begin_active = true;
+ polys->begin_draw2d = (prog->argc >= 3 ? (int)PRVM_G_FLOAT(OFS_PARM2) : r_refdef.draw2dstage);
}
//void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
break;
if (i == MAX_EDICTS)
return;
- prog->skeletons[i] = skeleton = (skeleton_t *)Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
+ prog->skeletons[i] = skeleton = Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
PRVM_G_FLOAT(OFS_RETURN) = i + 1;
skeleton->model = model;
skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
VM_CL_R_SetView, // #303 float(float property, ...) setproperty (EXT_CSQC)
VM_CL_R_RenderScene, // #304 void() renderscene (EXT_CSQC)
VM_CL_R_AddDynamicLight, // #305 void(vector org, float radius, vector lightcolours) adddynamiclight (EXT_CSQC)
-VM_CL_R_PolygonBegin, // #306 void(string texturename, float flag[, float is2d, float lines]) R_BeginPolygon
+VM_CL_R_PolygonBegin, // #306 void(string texturename, float flag, float is2d[NYI: , float lines]) R_BeginPolygon
VM_CL_R_PolygonVertex, // #307 void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex
VM_CL_R_PolygonEnd, // #308 void() R_EndPolygon
NULL /* R_LoadWorldModel in menu VM, should stay unassigned in client*/, // #309