mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-12 16:17:44 -10:00
allow us to build without D3D support under Windows (just define NO_DIRECT3D) clean up TMAP flags fix a couple of minor OpenGL state change issues with spec and env map rendering make sure we build again for OS X (OGL extension functions work a little different there) render targets always need to be power-of-2 to avoid incomplete buffer issues in the code when we disable culling in opengl_3dunlit be sure that we re-enable it on exit of function re-fix screenshots add true alpha blending support (with cmdline for now since the artwork has the catch up) draw lines with float positioning, to be more accurate with resizing on non-standard resolutions don't load cubemaps from file for D3D, not sure how to do it anyway update geometry batcher code, memory fixes, dynamic stuff, basic fixage, etc.
677 lines
14 KiB
C++
677 lines
14 KiB
C++
/*
|
|
* Code created by Thomas Whittaker (RT) for a FreeSpace 2 source code project
|
|
*
|
|
* You may not sell or otherwise commercially exploit the source or things you
|
|
* created based on the source.
|
|
*
|
|
*/
|
|
|
|
//#include <map>
|
|
#include <vector>
|
|
|
|
#include "globalincs/pstypes.h"
|
|
#include "graphics/grbatch.h"
|
|
#include "graphics/2d.h"
|
|
#include "cmdline/cmdline.h"
|
|
#include "render/3d.h"
|
|
|
|
|
|
geometry_batcher::~geometry_batcher()
|
|
{
|
|
if (vert != NULL) {
|
|
vm_free(vert);
|
|
vert = NULL;
|
|
}
|
|
|
|
if (vert_list != NULL) {
|
|
vm_free(vert_list);
|
|
vert_list = NULL;
|
|
}
|
|
}
|
|
|
|
void geometry_batcher::allocate_internal(int n_verts)
|
|
{
|
|
// this is called to start a batch, you make sure you have enough memory
|
|
// to store all the geometry, then you clear out the memory and set the
|
|
// number of primitives to 0
|
|
if (n_verts > n_allocated) {
|
|
if (vert != NULL) {
|
|
vm_free(vert);
|
|
vert = NULL;
|
|
}
|
|
|
|
if (vert_list != NULL) {
|
|
vm_free(vert_list);
|
|
vert_list = NULL;
|
|
}
|
|
|
|
vert = (vertex *) vm_malloc( sizeof(vertex) * n_verts );
|
|
vert_list = (vertex **) vm_malloc( sizeof(vertex*) * n_verts );
|
|
|
|
Verify( (vert != NULL) && (vert_list != NULL) );
|
|
|
|
for (int i = 0; i < n_verts; i++)
|
|
vert_list[i] = &vert[i];
|
|
|
|
memset( vert, 0, sizeof(vertex) * n_verts );
|
|
n_allocated = n_verts;
|
|
}
|
|
|
|
n_to_render = 0;
|
|
}
|
|
|
|
void geometry_batcher::allocate(int quad, int n_tri)
|
|
{
|
|
int to_alloc = 0;
|
|
|
|
// quads have two triangles, therefore six verts
|
|
if (quad > 0 ) {
|
|
to_alloc += (quad * 6);
|
|
}
|
|
|
|
// a single triangle has a mere 3 verts
|
|
if ( n_tri > 0 ) {
|
|
to_alloc += (n_tri * 3);
|
|
}
|
|
|
|
allocate_internal(to_alloc);
|
|
}
|
|
|
|
void geometry_batcher::add_allocate(int quad, int n_tri)
|
|
{
|
|
int to_alloc = (n_to_render * 3);
|
|
|
|
// quads have two triangles, therefore six verts
|
|
if ( quad > 0 ) {
|
|
to_alloc += (quad * 6);
|
|
}
|
|
|
|
// a single triangle has a mere 3 verts
|
|
if (n_tri > 0) {
|
|
to_alloc += (n_tri * 3);
|
|
}
|
|
|
|
vertex *old_vert = vert;
|
|
|
|
if (to_alloc > n_allocated) {
|
|
if (vert_list != NULL) {
|
|
vm_free(vert_list);
|
|
vert_list = NULL;
|
|
}
|
|
|
|
vert = (vertex *) vm_malloc( sizeof(vertex) * to_alloc );
|
|
vert_list = (vertex **) vm_malloc( sizeof(vertex*) * to_alloc );
|
|
|
|
Verify( (vert != NULL) && (vert_list != NULL) );
|
|
|
|
for (int i = 0; i < to_alloc; i++)
|
|
vert_list[i] = &vert[i];
|
|
|
|
memset( vert, 0, sizeof(vertex) * to_alloc );
|
|
|
|
if (old_vert != NULL) {
|
|
memcpy( vert, old_vert, sizeof(vertex) * n_to_render * 3 );
|
|
vm_free(old_vert);
|
|
}
|
|
|
|
n_allocated = to_alloc;
|
|
}
|
|
}
|
|
|
|
void geometry_batcher::clone(const geometry_batcher &geo)
|
|
{
|
|
n_to_render = geo.n_to_render;
|
|
n_allocated = geo.n_allocated;
|
|
|
|
if (n_allocated > 0) {
|
|
vert = (vertex *) vm_malloc( sizeof(vertex) * n_allocated );
|
|
vert_list = (vertex **) vm_malloc( sizeof(vertex*) * n_allocated );
|
|
|
|
memcpy( vert, geo.vert, sizeof(vertex) * n_allocated );
|
|
|
|
for (int i = 0; i < n_allocated; i++) {
|
|
vert_list[i] = &vert[i];
|
|
}
|
|
} else {
|
|
vert = NULL;
|
|
vert_list = NULL;
|
|
}
|
|
}
|
|
|
|
const geometry_batcher &geometry_batcher::operator=(const geometry_batcher &geo)
|
|
{
|
|
if (this != &geo) {
|
|
clone(geo);
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
/*
|
|
0----1
|
|
|\ |
|
|
| \ |
|
|
3----2
|
|
*/
|
|
void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float depth)
|
|
{
|
|
rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad
|
|
|
|
vec3d PNT, p[4];
|
|
vec3d fvec, rvec, uvec;
|
|
vertex *P = &vert[n_to_render * 3];
|
|
|
|
vm_vert2vec(pnt, &PNT);
|
|
|
|
|
|
// get the direction from the point to the eye
|
|
vm_vec_sub(&fvec, &View_position, &PNT);
|
|
vm_vec_normalize(&fvec);
|
|
|
|
// get an up vector in the general direction of what we want
|
|
uvec = View_matrix.vec.uvec;
|
|
|
|
// make a right vector from the f and up vector, this r vec is exactly what we want, so...
|
|
vm_vec_crossprod(&rvec, &fvec, &uvec);
|
|
vm_vec_normalize(&rvec);
|
|
|
|
// fix the u vec with it
|
|
vm_vec_crossprod(&uvec, &fvec, &rvec);
|
|
|
|
// move the center of the sprite based on the depth parameter
|
|
if ( depth != 0.0f )
|
|
vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
|
|
|
|
// move one of the verts to the left
|
|
vm_vec_scale_add(&p[0], &PNT, &rvec, rad);
|
|
|
|
// and one to the right
|
|
vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);
|
|
|
|
// now move all oof the verts to were they need to be
|
|
vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
|
|
vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
|
|
vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
|
|
vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);
|
|
|
|
|
|
//move all the data from the vecs into the verts
|
|
//tri 1
|
|
g3_transfer_vertex(&P[5], &p[3]);
|
|
g3_transfer_vertex(&P[4], &p[2]);
|
|
g3_transfer_vertex(&P[3], &p[1]);
|
|
|
|
//tri 2
|
|
g3_transfer_vertex(&P[2], &p[3]);
|
|
g3_transfer_vertex(&P[1], &p[1]);
|
|
g3_transfer_vertex(&P[0], &p[0]);
|
|
|
|
// set up the UV coords
|
|
if ( orient & 1 ) {
|
|
// tri 1
|
|
P[5].u = 1.0f;
|
|
P[4].u = 0.0f;
|
|
P[3].u = 0.0f;
|
|
// tri 2
|
|
P[2].u = 1.0f;
|
|
P[1].u = 0.0f;
|
|
P[0].u = 1.0f;
|
|
} else {
|
|
// tri 1
|
|
P[5].u = 0.0f;
|
|
P[4].u = 1.0f;
|
|
P[3].u = 1.0f;
|
|
// tri 2
|
|
P[2].u = 0.0f;
|
|
P[1].u = 1.0f;
|
|
P[0].u = 0.0f;
|
|
}
|
|
|
|
if ( orient & 2 ) {
|
|
// tri 1
|
|
P[5].v = 1.0f;
|
|
P[4].v = 1.0f;
|
|
P[3].v = 0.0f;
|
|
// tri 2
|
|
P[2].v = 1.0f;
|
|
P[1].v = 0.0f;
|
|
P[0].v = 0.0f;
|
|
} else {
|
|
// tri 1
|
|
P[5].v = 0.0f;
|
|
P[4].v = 0.0f;
|
|
P[3].v = 1.0f;
|
|
// tri 2
|
|
P[2].v = 0.0f;
|
|
P[1].v = 1.0f;
|
|
P[0].v = 1.0f;
|
|
}
|
|
|
|
for (int i = 0; i < 6 ; i++) {
|
|
P[i].r = pnt->r;
|
|
P[i].g = pnt->g;
|
|
P[i].b = pnt->b;
|
|
P[i].a = pnt->a;
|
|
}
|
|
|
|
n_to_render += 2;
|
|
}
|
|
|
|
void geometry_batcher::draw_bitmap(vertex *pnt, int orient, float rad, float angle, float depth)
|
|
{
|
|
rad *= 1.41421356f;//1/0.707, becase these are the points of a square or width and height rad
|
|
|
|
extern float Physics_viewer_bank;
|
|
angle += Physics_viewer_bank;
|
|
|
|
if ( angle < 0.0f )
|
|
angle += PI2;
|
|
else if ( angle > PI2 )
|
|
angle -= PI2;
|
|
|
|
vec3d PNT, p[4];
|
|
vec3d fvec, rvec, uvec;
|
|
vertex *P = &vert[n_to_render * 3];
|
|
|
|
vm_vert2vec(pnt, &PNT);
|
|
|
|
vm_vec_sub(&fvec, &View_position, &PNT);
|
|
vm_vec_normalize(&fvec);
|
|
|
|
vm_rot_point_around_line(&uvec, &View_matrix.vec.uvec, angle, &vmd_zero_vector, &fvec);
|
|
// uvec = View_matrix.vec.uvec;
|
|
|
|
vm_vec_crossprod(&rvec, &fvec, &uvec);
|
|
vm_vec_normalize(&rvec);
|
|
vm_vec_crossprod(&uvec, &fvec, &rvec);
|
|
|
|
vm_vec_scale_add(&PNT, &PNT, &fvec, depth);
|
|
vm_vec_scale_add(&p[0], &PNT, &rvec, rad);
|
|
vm_vec_scale_add(&p[2], &PNT, &rvec, -rad);
|
|
|
|
vm_vec_scale_add(&p[1], &p[2], &uvec, rad);
|
|
vm_vec_scale_add(&p[3], &p[0], &uvec, -rad);
|
|
vm_vec_scale_add(&p[0], &p[0], &uvec, rad);
|
|
vm_vec_scale_add(&p[2], &p[2], &uvec, -rad);
|
|
|
|
|
|
//move all the data from the vecs into the verts
|
|
//tri 1
|
|
g3_transfer_vertex(&P[5], &p[3]);
|
|
g3_transfer_vertex(&P[4], &p[2]);
|
|
g3_transfer_vertex(&P[3], &p[1]);
|
|
|
|
//tri 2
|
|
g3_transfer_vertex(&P[2], &p[3]);
|
|
g3_transfer_vertex(&P[1], &p[1]);
|
|
g3_transfer_vertex(&P[0], &p[0]);
|
|
|
|
// set up the UV coords
|
|
if ( orient & 1 ) {
|
|
// tri 1
|
|
P[5].u = 1.0f;
|
|
P[4].u = 0.0f;
|
|
P[3].u = 0.0f;
|
|
// tri 2
|
|
P[2].u = 1.0f;
|
|
P[1].u = 0.0f;
|
|
P[0].u = 1.0f;
|
|
} else {
|
|
// tri 1
|
|
P[5].u = 0.0f;
|
|
P[4].u = 1.0f;
|
|
P[3].u = 1.0f;
|
|
// tri 2
|
|
P[2].u = 0.0f;
|
|
P[1].u = 1.0f;
|
|
P[0].u = 0.0f;
|
|
}
|
|
|
|
if ( orient & 2 ) {
|
|
// tri 1
|
|
P[5].v = 1.0f;
|
|
P[4].v = 1.0f;
|
|
P[3].v = 0.0f;
|
|
// tri 2
|
|
P[2].v = 1.0f;
|
|
P[1].v = 0.0f;
|
|
P[0].v = 0.0f;
|
|
} else {
|
|
// tri 1
|
|
P[5].v = 0.0f;
|
|
P[4].v = 0.0f;
|
|
P[3].v = 1.0f;
|
|
// tri 2
|
|
P[2].v = 0.0f;
|
|
P[1].v = 1.0f;
|
|
P[0].v = 1.0f;
|
|
}
|
|
|
|
/* //tri 1
|
|
P[5].u = 0.0f; P[5].v = 0.0f;
|
|
P[4].u = 1.0f; P[4].v = 0.0f;
|
|
P[3].u = 1.0f; P[3].v = 1.0f;
|
|
|
|
//tri 2
|
|
P[2].u = 0.0f; P[2].v = 0.0f;
|
|
P[1].u = 1.0f; P[1].v = 1.0f;
|
|
P[0].u = 0.0f; P[0].v = 1.0f;*/
|
|
|
|
for (int i = 0; i < 6 ; i++) {
|
|
P[i].r = pnt->r;
|
|
P[i].g = pnt->g;
|
|
P[i].b = pnt->b;
|
|
P[i].a = pnt->a;
|
|
}
|
|
|
|
n_to_render += 2;
|
|
}
|
|
|
|
void geometry_batcher::draw_tri(vertex* verts)
|
|
{
|
|
vertex *P = &vert[n_to_render *3 ];
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
P[i] = verts[i];
|
|
|
|
n_to_render += 1;
|
|
}
|
|
|
|
void geometry_batcher::draw_quad(vertex* verts)
|
|
{
|
|
vertex *P = &vert[n_to_render * 3];
|
|
|
|
P[0] = verts[0];
|
|
P[1] = verts[1];
|
|
P[2] = verts[2];
|
|
|
|
P[0] = verts[0];
|
|
P[2] = verts[2];
|
|
P[3] = verts[3];
|
|
|
|
n_to_render += 2;
|
|
}
|
|
|
|
|
|
void geometry_batcher::draw_beam(vec3d *start, vec3d *end, float width, float intensity)
|
|
{
|
|
vec3d p[4];
|
|
vertex *P = &vert[n_to_render * 3];
|
|
|
|
vec3d fvec, uvecs, uvece, evec;
|
|
|
|
vm_vec_sub(&fvec, start, end);
|
|
vm_vec_normalize_safe(&fvec);
|
|
|
|
vm_vec_sub(&evec, &View_position, start);
|
|
vm_vec_normalize_safe(&evec);
|
|
|
|
vm_vec_crossprod(&uvecs, &fvec, &evec);
|
|
vm_vec_normalize_safe(&uvecs);
|
|
|
|
vm_vec_sub(&evec, &View_position, end);
|
|
vm_vec_normalize_safe(&evec);
|
|
|
|
vm_vec_crossprod(&uvece, &fvec, &evec);
|
|
vm_vec_normalize_safe(&uvece);
|
|
|
|
|
|
vm_vec_scale_add(&p[0], start, &uvecs, width);
|
|
vm_vec_scale_add(&p[1], end, &uvece, width);
|
|
vm_vec_scale_add(&p[2], end, &uvece, -width);
|
|
vm_vec_scale_add(&p[3], start, &uvecs, -width);
|
|
|
|
|
|
//move all the data from the vecs into the verts
|
|
//tri 1
|
|
g3_transfer_vertex(&P[0], &p[3]);
|
|
g3_transfer_vertex(&P[1], &p[2]);
|
|
g3_transfer_vertex(&P[2], &p[1]);
|
|
|
|
//tri 2
|
|
g3_transfer_vertex(&P[3], &p[3]);
|
|
g3_transfer_vertex(&P[4], &p[1]);
|
|
g3_transfer_vertex(&P[5], &p[0]);
|
|
|
|
//set up the UV coords
|
|
//tri 1
|
|
P[0].u = 0.0f; P[0].v = 0.0f;
|
|
P[1].u = 1.0f; P[1].v = 0.0f;
|
|
P[2].u = 1.0f; P[2].v = 1.0f;
|
|
|
|
//tri 2
|
|
P[3].u = 0.0f; P[3].v = 0.0f;
|
|
P[4].u = 1.0f; P[4].v = 1.0f;
|
|
P[5].u = 0.0f; P[5].v = 1.0f;
|
|
|
|
ubyte _color = (ubyte)(255.0f * intensity);
|
|
|
|
for(int i = 0; i < 6; i++){
|
|
P[i].r = P[i].g = P[i].b = P[i].a = _color;
|
|
}
|
|
|
|
n_to_render += 2;
|
|
}
|
|
|
|
float geometry_batcher::draw_laser(vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
|
|
{
|
|
width1 *= 0.5f;
|
|
width2 *= 0.5f;
|
|
|
|
vec3d uvec, fvec, rvec, center, reye;
|
|
|
|
vm_vec_sub( &fvec, p0, p1 );
|
|
vm_vec_normalize_safe( &fvec );
|
|
|
|
vm_vec_avg( ¢er, p0, p1 ); // needed for the return value only
|
|
vm_vec_sub(&reye, &Eye_position, ¢er);
|
|
vm_vec_normalize(&reye);
|
|
|
|
// compute the up vector
|
|
vm_vec_crossprod(&uvec, &fvec, &reye);
|
|
vm_vec_normalize(&uvec);
|
|
// ... the forward vector
|
|
vm_vec_crossprod(&fvec, &uvec, &reye);
|
|
vm_vec_normalize(&fvec);
|
|
// now recompute right vector, in case it wasn't entirely perpendiclar
|
|
vm_vec_crossprod(&rvec, &uvec, &fvec);
|
|
|
|
// Now have uvec, which is up vector and rvec which is the normal
|
|
// of the face.
|
|
|
|
vec3d start, end;
|
|
|
|
vm_vec_scale_add(&start, p0, &fvec, -width1);
|
|
vm_vec_scale_add(&end, p1, &fvec, width2);
|
|
|
|
vec3d vecs[4];
|
|
|
|
vertex *pts = &vert[n_to_render * 3];
|
|
|
|
vm_vec_scale_add( &vecs[0], &end, &uvec, width2 );
|
|
vm_vec_scale_add( &vecs[1], &start, &uvec, width1 );
|
|
vm_vec_scale_add( &vecs[2], &start, &uvec, -width1 );
|
|
vm_vec_scale_add( &vecs[3], &end, &uvec, -width2 );
|
|
|
|
g3_transfer_vertex( &pts[0], &vecs[0] );
|
|
g3_transfer_vertex( &pts[1], &vecs[1] );
|
|
g3_transfer_vertex( &pts[2], &vecs[2] );
|
|
|
|
g3_transfer_vertex( &pts[3], &vecs[0] );
|
|
g3_transfer_vertex( &pts[4], &vecs[2] );
|
|
g3_transfer_vertex( &pts[5], &vecs[3] );
|
|
|
|
pts[0].u = 1.0f;
|
|
pts[0].v = 0.0f;
|
|
pts[1].u = 0.0f;
|
|
pts[1].v = 0.0f;
|
|
pts[2].u = 0.0f;
|
|
pts[2].v = 1.0f;
|
|
|
|
pts[3].u = 1.0f;
|
|
pts[3].v = 0.0f;
|
|
pts[4].u = 0.0f;
|
|
pts[4].v = 1.0f;
|
|
pts[5].u = 1.0f;
|
|
pts[5].v = 1.0f;
|
|
|
|
pts[0].r = (ubyte)r;
|
|
pts[0].g = (ubyte)g;
|
|
pts[0].b = (ubyte)b;
|
|
pts[0].a = 255;
|
|
pts[1].r = (ubyte)r;
|
|
pts[1].g = (ubyte)g;
|
|
pts[1].b = (ubyte)b;
|
|
pts[1].a = 255;
|
|
pts[2].r = (ubyte)r;
|
|
pts[2].g = (ubyte)g;
|
|
pts[2].b = (ubyte)b;
|
|
pts[2].a = 255;
|
|
pts[3].r = (ubyte)r;
|
|
pts[3].g = (ubyte)g;
|
|
pts[3].b = (ubyte)b;
|
|
pts[3].a = 255;
|
|
pts[4].r = (ubyte)r;
|
|
pts[4].g = (ubyte)g;
|
|
pts[4].b = (ubyte)b;
|
|
pts[4].a = 255;
|
|
pts[5].r = (ubyte)r;
|
|
pts[5].g = (ubyte)g;
|
|
pts[5].b = (ubyte)b;
|
|
pts[5].a = 255;
|
|
|
|
|
|
n_to_render += 2;
|
|
|
|
return center.xyz.z;
|
|
}
|
|
|
|
void geometry_batcher::render(int flags)
|
|
{
|
|
if (n_to_render) {
|
|
g3_draw_poly( n_to_render * 3, vert_list, flags | TMAP_FLAG_TRILIST);
|
|
n_to_render = 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// laser batcher
|
|
|
|
struct batch_item {
|
|
batch_item(): texture(-1), tmap_flags(0), alpha(1.0f), laser(false) {};
|
|
|
|
geometry_batcher batch;
|
|
|
|
int texture;
|
|
int tmap_flags;
|
|
float alpha;
|
|
|
|
bool laser;
|
|
};
|
|
|
|
static std::vector<batch_item> geometry_map;
|
|
|
|
static int find_good_batch_item(int texture)
|
|
{
|
|
for (uint i = 0; i < geometry_map.size(); i++) {
|
|
if (geometry_map[i].texture == texture)
|
|
return i;
|
|
}
|
|
|
|
// don't have an existing match so add a new entry
|
|
batch_item new_item;
|
|
|
|
new_item.texture = texture;
|
|
|
|
geometry_map.push_back(new_item);
|
|
|
|
return (int)(geometry_map.size() - 1);
|
|
}
|
|
|
|
float batch_add_laser(int texture, vec3d *p0, float width1, vec3d *p1, float width2, int r, int g, int b)
|
|
{
|
|
if (texture < 0) {
|
|
Int3();
|
|
return 0.0f;
|
|
}
|
|
|
|
geometry_batcher *item = NULL;
|
|
int index = find_good_batch_item(texture);
|
|
Assert( index >= 0 );
|
|
|
|
geometry_map[index].laser = true;
|
|
item = &geometry_map[index].batch;
|
|
|
|
item->add_allocate(1);
|
|
|
|
return item->draw_laser(p0, width1, p1, width2, r, g, b);
|
|
}
|
|
|
|
int batch_add_bitmap(int texture, int tmap_flags, vertex *pnt, int orient, float rad, float alpha, float depth)
|
|
{
|
|
if (texture < 0) {
|
|
Int3();
|
|
return 1;
|
|
}
|
|
|
|
geometry_batcher *item = NULL;
|
|
int index = find_good_batch_item(texture);
|
|
Assert( index >= 0 );
|
|
|
|
Assert( geometry_map[index].laser == false );
|
|
|
|
geometry_map[index].tmap_flags = tmap_flags;
|
|
geometry_map[index].alpha = alpha;
|
|
|
|
item = &geometry_map[index].batch;
|
|
|
|
item->add_allocate(1);
|
|
|
|
item->draw_bitmap(pnt, orient, rad, depth);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void batch_render_lasers()
|
|
{
|
|
for (uint i = 0; i < geometry_map.size(); i++) {
|
|
if ( !geometry_map[i].laser )
|
|
continue;
|
|
|
|
if ( !geometry_map[i].batch.need_to_render() )
|
|
continue;
|
|
|
|
Assert( geometry_map[i].texture >= 0 );
|
|
gr_set_bitmap(geometry_map[i].texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, 0.99999f);
|
|
geometry_map[i].batch.render(TMAP_FLAG_TEXTURED | TMAP_FLAG_XPARENT | TMAP_HTL_3D_UNLIT | TMAP_FLAG_RGB | TMAP_FLAG_GOURAUD | TMAP_FLAG_CORRECT);
|
|
}
|
|
}
|
|
|
|
void batch_render_bitmaps()
|
|
{
|
|
for (uint i = 0; i < geometry_map.size(); i++) {
|
|
if ( geometry_map[i].laser )
|
|
continue;
|
|
|
|
if ( !geometry_map[i].batch.need_to_render() )
|
|
continue;
|
|
|
|
Assert( geometry_map[i].texture >= 0 );
|
|
gr_set_bitmap(geometry_map[i].texture, GR_ALPHABLEND_FILTER, GR_BITBLT_MODE_NORMAL, geometry_map[i].alpha);
|
|
geometry_map[i].batch.render( geometry_map[i].tmap_flags );
|
|
}
|
|
}
|
|
|
|
void batch_render_all()
|
|
{
|
|
batch_render_lasers();
|
|
batch_render_bitmaps();
|
|
}
|
|
|
|
void batch_reset()
|
|
{
|
|
geometry_map.clear();
|
|
}
|
|
|