Ejemplo n.º 1
0
GLfloat opengl_texture_state::AnisoFilter(GLfloat aniso)
{
#if 0
	GLfloat rval = units[active_texture_unit].aniso_filter;

	if ( (aniso > 0.0f) /*&& (aniso != rval)*/ ) {
		if ( Is_Extension_Enabled(OGL_EXT_TEXTURE_FILTER_ANISOTROPIC) ) {
			units[active_texture_unit].aniso_filter = aniso;
			CLAMP(units[active_texture_unit].aniso_filter, 1.0f, GL_max_anisotropy);
	
			glTexParameterf(units[active_texture_unit].texture_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, units[active_texture_unit].aniso_filter);
		}

		if ( Is_Extension_Enabled(OGL_EXT_TEXTURE_LOD_BIAS) ) {
			if (units[active_texture_unit].aniso_filter > 1.0f) {
				glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, 0.0f);
			} else {
				glTexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, -0.75f);
			}
		}
	}

	return rval;
#endif

	return GL_anisotropy;
}
int gr_opengl_bm_make_render_target(int n, int *width, int *height, ubyte *bpp, int *mm_lvl, int flags)
{
	Assert( (n >= 0) && (n < MAX_BITMAPS) );

	if ( !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) || Cmdline_no_fbo ) {
		return 0;
	}

	if ( (flags & BMP_FLAG_CUBEMAP) && !Is_Extension_Enabled(OGL_ARB_TEXTURE_CUBE_MAP) ) {
		return 0;
	}

	if ( (flags & BMP_FLAG_CUBEMAP) && (*width != *height) ) {
		MIN(*width, *height) = MAX(*width, *height);
	}

	// Only enforce power of two size if not supported
	if (!(Is_Extension_Enabled(OGL_ARB_TEXTURE_NON_POWER_OF_TWO)))
	{
		Assert( is_power_of_two(*width, *height) );
	}

	if ( opengl_make_render_target(bm_bitmaps[n].handle, n, width, height, bpp, mm_lvl, flags) ) {
		return 1;
	}

	return 0;
}
Ejemplo n.º 3
0
int distortion_add_beam(int texture, int tmap_flags, vec3d *start, vec3d *end, float width, float intensity, float offset)
{
	if (texture < 0) {
		Int3();
		return 1;
	}

	if ( GLSL_version < 120 || !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) ) {
		// don't render distortions if we can't support them.
		return 0;
	}

	batch_item *item = NULL;

	SCP_map<int, batch_item>::iterator it = distortion_map.find(texture);

	if ( !distortion_map.empty() && it != distortion_map.end() ) {
		item = &it->second;
	} else {
		item = &distortion_map[texture];
		item->texture = texture;
	}

	Assertion( (item->laser == false), "Distortion particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );

	item->tmap_flags = tmap_flags;
	item->alpha = intensity;

	item->batch.add_allocate(1);

	item->batch.draw_beam(start,end,width,intensity,offset);

	return 0;
}
Ejemplo n.º 4
0
void opengl_post_process_init()
{
	Post_initialized = 0;

	//We need to read the tbl first. This is mostly for FRED's benefit, as otherwise the list of post effects for the sexp doesn't get updated.
	if ( !opengl_post_init_table() ) {
		mprintf(("  Unable to read post-processing table! Disabling post-processing...\n\n"));
		Cmdline_postprocess = 0;
		return;
	}

	if ( !Cmdline_postprocess ) {
		return;
	}

	if ( !Scene_texture_initialized ) {
		return;
	}

	if ( !is_minimum_GLSL_version() || Cmdline_no_fbo || !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) ) {
		Cmdline_postprocess = 0;
		return;
	}

	// for ease of use we require support for non-power-of-2 textures in one
	// form or another:
	//    - the NPOT extension
	//    - GL version 2.0+ (which should work for non-reporting ATI cards since we don't use mipmaps)
	if ( !(Is_Extension_Enabled(OGL_ARB_TEXTURE_NON_POWER_OF_TWO) || (GL_version >= 20)) ) {
		Cmdline_postprocess = 0;
		return;
	}

	if ( !opengl_post_init_shaders() ) {
		mprintf(("  Unable to initialize post-processing shaders! Disabling post-processing...\n\n"));
		Cmdline_postprocess = 0;
		return;
	}

	if ( !opengl_post_init_framebuffer() ) {
		mprintf(("  Unable to initialize post-processing framebuffer! Disabling post-processing...\n\n"));
		Cmdline_postprocess = 0;
		return;
	}

	Post_initialized = 1;
}
int get_num_mipmap_levels(int w, int h)
{
	int size, levels = 0;

	// make sure we can and should generate mipmaps before trying to use them
	if ( !Cmdline_mipmap || !Is_Extension_Enabled(OGL_SGIS_GENERATE_MIPMAP) )
		return 1;

	size = MAX(w, h);

	while (size > 0) {
		size >>= 1;
		levels++;
	}

	return (levels > 1) ? levels : 1;
}
Ejemplo n.º 6
0
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;
	}

	if ( tmap_flags & TMAP_FLAG_SOFT_QUAD && ( !Cmdline_softparticles || GLSL_version <= 120 ) ) {
		// don't render this as a soft particle if we don't support soft particles
		tmap_flags &= ~(TMAP_FLAG_SOFT_QUAD);
	}

	if ( GLSL_version > 120 && Cmdline_softparticles && !Cmdline_no_geo_sdr_effects && Is_Extension_Enabled(OGL_EXT_GEOMETRY_SHADER4) && (tmap_flags & TMAP_FLAG_VERTEX_GEN) ) {
		geometry_batch_add_bitmap(texture, tmap_flags, pnt, orient, rad, alpha, depth);
		return 0;
	} else if ( tmap_flags & TMAP_FLAG_VERTEX_GEN ) {
		tmap_flags &= ~(TMAP_FLAG_VERTEX_GEN);
	}

	batch_item *item = NULL;

	SCP_map<int, batch_item>::iterator it = geometry_map.find(texture);

	if ( !geometry_map.empty() && it != geometry_map.end() ) {
		item = &it->second;
	} else {
		item = &geometry_map[texture];
		item->texture = texture;
	}

	Assertion( (item->laser == false), "Particle effect %s used as laser glow or laser bitmap\n", bm_get_filename(texture) );

	item->tmap_flags = tmap_flags;
	item->alpha = alpha;

	item->batch.add_allocate(1);

	item->batch.draw_bitmap(pnt, orient, rad, depth);

	return 0;
}
int gr_opengl_bm_set_render_target(int n, int face)
{
	if ( !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) || Cmdline_no_fbo ) {
		return 0;
	}

	if (n == -1) {
		opengl_set_render_target(-1);
		return 1;
	}

	Assert( (n >= 0) && (n < MAX_BITMAPS) );

	int is_static = (bm_bitmaps[n].type == BM_TYPE_RENDER_TARGET_STATIC);

	if ( opengl_set_render_target(n, face, is_static) ) {
		return 1;
	}

	return 0;
}
void gr_opengl_bm_save_render_target(int n)
{
	Assert( (n >= 0) && (n < MAX_BITMAPS) );

	if ( !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) || Cmdline_no_fbo ) {
		return;
	}

	bitmap_entry *be = &bm_bitmaps[n];
	bitmap *bmp = &be->bm;

	size_t rc = opengl_export_render_target( n, bmp->w, bmp->h, (bmp->true_bpp == 32), be->num_mipmaps, (ubyte*)bmp->data );

	if (rc != be->mem_taken) {
		Int3();
		return;
	}

	if (Cmdline_save_render_targets) {
		dds_save_image(bmp->w, bmp->h, bmp->true_bpp, be->num_mipmaps, (ubyte*)bmp->data, (bmp->flags & BMP_FLAG_CUBEMAP));
	}
}
void opengl_extensions_init()
{
	opengl_get_extensions();

	// if S3TC compression is found, then "GL_ARB_texture_compression" must be an extension
	Use_compressed_textures = Is_Extension_Enabled(OGL_EXT_TEXTURE_COMPRESSION_S3TC);
	Texture_compression_available = Is_Extension_Enabled(OGL_ARB_TEXTURE_COMPRESSION);
	// Swifty put this in, but it's not doing anything. Once he uses it, he can uncomment it.
	//int use_base_vertex = Is_Extension_Enabled(OGL_ARB_DRAW_ELEMENTS_BASE_VERTEX);

	//allow VBOs to be used
	if ( !Cmdline_nohtl && !Cmdline_novbo && Is_Extension_Enabled(OGL_ARB_VERTEX_BUFFER_OBJECT) ) {
		Use_VBOs = 1;
	}

	if ( !Cmdline_no_pbo && Is_Extension_Enabled(OGL_ARB_PIXEL_BUFFER_OBJECT) ) {
		Use_PBOs = 1;
	}

	// setup the best fog function found
	if ( !Fred_running ) {
		if ( Is_Extension_Enabled(OGL_EXT_FOG_COORD) ) {
			OGL_fogmode = 2;
		} else {
			OGL_fogmode = 1;
		}
	}

	// if we can't do cubemaps then turn off Cmdline_env
	if ( !(Is_Extension_Enabled(OGL_ARB_TEXTURE_CUBE_MAP) && Is_Extension_Enabled(OGL_ARB_TEXTURE_ENV_COMBINE)) ) {
		Cmdline_env = 0;
	}

	if ( !Cmdline_noglsl && Is_Extension_Enabled(OGL_ARB_SHADER_OBJECTS) && Is_Extension_Enabled(OGL_ARB_FRAGMENT_SHADER)
			&& Is_Extension_Enabled(OGL_ARB_VERTEX_SHADER) ) {
		int ver = 0, major = 0, minor = 0;
		const char *glsl_ver = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION_ARB);

		sscanf(glsl_ver, "%d.%d", &major, &minor);
		ver = (major * 100) + minor;

		// SM 4.0 compatible or better
		if (ver >= 400) {
			Use_GLSL = 4;
		}
		// SM 3.0 compatible
		else if ( ver >= 130 ) {
			Use_GLSL = 3;
		}
		// SM 2.0 compatible
		else if (ver >= 120) {
			Use_GLSL = 2;
		}
		// we require GLSL 1.20 or higher
		else if (ver < 110) {
			Use_GLSL = 0;
			mprintf(("  OpenGL Shading Language version %s is not sufficient to use GLSL mode in FSO. Defaulting to fixed-function renderer.\n", glGetString(GL_SHADING_LANGUAGE_VERSION_ARB) ));
#ifdef NDEBUG
			popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "GLSL support not available on this GPU. Disabling shader support and defaulting to fixed-function rendering.\n");
#endif
		}
	}

	// can't have this stuff without GLSL support
	if ( !Use_GLSL ) {
		Cmdline_normal = 0;
		Cmdline_height = 0;
		Cmdline_postprocess = 0;
	}

	if (Use_GLSL) {
		GLint max_texture_units;
		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &max_texture_units);

		// we need enough texture slots for this stuff to work
		
		if (max_texture_units < 6) {
			mprintf(( "Not enough texture units for height map support. We need at least 6, we found %d.\n", max_texture_units ));
			Cmdline_height = 0;
		} else if (max_texture_units < 5) {
			mprintf(( "Not enough texture units for height and normal map support. We need at least 5, we found %d.\n", max_texture_units ));
			Cmdline_normal = 0;
			Cmdline_height = 0;
		} else if (max_texture_units < 4) {
			mprintf(( "Not enough texture units found for GLSL support. We need at least 4, we found %d.\n", max_texture_units ));
			Use_GLSL = 0;
		}
	}
}
Ejemplo n.º 10
0
void opengl_extensions_init()
{
	opengl_get_extensions();

	// if S3TC compression is found, then "GL_ARB_texture_compression" must be an extension
	Use_compressed_textures = Is_Extension_Enabled(OGL_EXT_TEXTURE_COMPRESSION_S3TC);
	Texture_compression_available = Is_Extension_Enabled(OGL_ARB_TEXTURE_COMPRESSION);
	// Swifty put this in, but it's not doing anything. Once he uses it, he can uncomment it.
	//int use_base_vertex = Is_Extension_Enabled(OGL_ARB_DRAW_ELEMENTS_BASE_VERTEX);

	//allow VBOs to be used
	if ( !Cmdline_nohtl && !Cmdline_novbo && Is_Extension_Enabled(OGL_ARB_VERTEX_BUFFER_OBJECT) ) {
		Use_VBOs = 1;
	}

	if ( !Cmdline_no_pbo && Is_Extension_Enabled(OGL_ARB_PIXEL_BUFFER_OBJECT) ) {
		Use_PBOs = 1;
	}

	// setup the best fog function found
	if ( !Fred_running ) {
		if ( Is_Extension_Enabled(OGL_EXT_FOG_COORD) ) {
			OGL_fogmode = 2;
		} else {
			OGL_fogmode = 1;
		}
	}

	// if we can't do cubemaps then turn off Cmdline_env
	if ( !(Is_Extension_Enabled(OGL_ARB_TEXTURE_CUBE_MAP) && Is_Extension_Enabled(OGL_ARB_TEXTURE_ENV_COMBINE)) ) {
		Cmdline_env = 0;
	}

	if ( !(Is_Extension_Enabled(OGL_EXT_GEOMETRY_SHADER4) && Is_Extension_Enabled(OGL_EXT_TEXTURE_ARRAY) && Is_Extension_Enabled(OGL_ARB_DRAW_ELEMENTS_BASE_VERTEX)) ) {
		Cmdline_shadow_quality = 0;
		mprintf(("  No hardware support for shadow mapping. Shadows will be disabled. \n"));
	}

	if ( !Cmdline_noglsl && Is_Extension_Enabled(OGL_ARB_SHADER_OBJECTS) && Is_Extension_Enabled(OGL_ARB_FRAGMENT_SHADER)
			&& Is_Extension_Enabled(OGL_ARB_VERTEX_SHADER) ) {
		int ver = 0, major = 0, minor = 0;
		const char *glsl_ver = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);

		sscanf(glsl_ver, "%d.%d", &major, &minor);
		ver = (major * 100) + minor;

		GLSL_version = ver;

		// we require a minimum GLSL version
		if (!is_minimum_GLSL_version()) {
			mprintf(("  OpenGL Shading Language version %s is not sufficient to use GLSL mode in FSO. Defaulting to fixed-function renderer.\n", glGetString(GL_SHADING_LANGUAGE_VERSION) ));
		}
	}

	// can't have this stuff without GLSL support
	if ( !is_minimum_GLSL_version() ) {
		Cmdline_normal = 0;
		Cmdline_height = 0;
		Cmdline_postprocess = 0;
		Cmdline_shadow_quality = 0;
		Cmdline_no_deferred_lighting = 1;
	}

	if ( GLSL_version < 120 || !Is_Extension_Enabled(OGL_EXT_FRAMEBUFFER_OBJECT) || !Is_Extension_Enabled(OGL_ARB_FLOATING_POINT_TEXTURES) ) {
        mprintf(("  No hardware support for deferred lighting. Deferred lighting will be disabled. \n"));
		Cmdline_no_deferred_lighting = 1;
		Cmdline_no_batching = true;
	}

	if (is_minimum_GLSL_version()) {
		GLint max_texture_units;
		glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &max_texture_units);

		// we need enough texture slots for this stuff to work

		if (max_texture_units < 6) {
			mprintf(( "Not enough texture units for height map support. We need at least 6, we found %d.\n", max_texture_units ));
			Cmdline_height = 0;
		} else if (max_texture_units < 5) {
			mprintf(( "Not enough texture units for height and normal map support. We need at least 5, we found %d.\n", max_texture_units ));
			Cmdline_normal = 0;
			Cmdline_height = 0;
		} else if (max_texture_units < 4) {
			mprintf(( "Not enough texture units found for GLSL support. We need at least 4, we found %d.\n", max_texture_units ));
			GLSL_version = 0;
		}
	}
}
/**
 * Compiles a new shader, and creates an opengl_shader_t that will be put into the GL_shader vector
 * if compilation is successful.
 *
 * @param sdr		Identifier defined with the program we wish to compile
 * @param flags		Combination of SDR_* flags
 */
int opengl_compile_shader(shader_type sdr, uint flags)
{
	int sdr_index = -1;
	int empty_idx;
	opengl_shader_t new_shader;

	Assert(sdr < NUM_SHADER_TYPES);

	opengl_shader_type_t *sdr_info = &GL_shader_types[sdr];

	mprintf(("Compiling new shader:\n"));
	mprintf(("	%s\n", sdr_info->description));

	// figure out if the variant requested needs a geometry shader
	bool use_geo_sdr = false;

	// do we even have a geometry shader?
	if ( sdr_info->geo != NULL ) {
		for (int i = 0; i < GL_num_shader_variants; ++i) {
			opengl_shader_variant_t *variant = &GL_shader_variants[i];

			if (variant->type_id == sdr && flags & variant->flag && variant->use_geometry_sdr) {
				use_geo_sdr = true;
				break;
			}
		}
	}

	auto vertex_content = opengl_get_shader_content(sdr_info->type_id, sdr_info->vert, flags);
	auto fragment_content = opengl_get_shader_content(sdr_info->type_id, sdr_info->frag, flags);
	SCP_vector<SCP_string> geom_content;

	if ( use_geo_sdr ) {
		if (!Is_Extension_Enabled(OGL_EXT_GEOMETRY_SHADER4)) {
			return -1;
		}

		// read geometry shader
		geom_content = opengl_get_shader_content(sdr_info->type_id, sdr_info->geo, flags);

		Current_geo_sdr_params = &sdr_info->geo_sdr_info;
	}

	new_shader.program_id = opengl_shader_create(vertex_content, fragment_content, geom_content);

	if (!new_shader.program_id) {
		return -1;
	}

	new_shader.shader = sdr_info->type_id;
	new_shader.flags = flags;

	opengl_shader_set_current(&new_shader);

	// initialize uniforms and attributes
	for ( int i = 0; i < sdr_info->num_uniforms; ++i ) {
		opengl_shader_init_uniform( sdr_info->uniforms[i] );
	}

	for (int i = 0; i < sdr_info->num_attributes; ++i) {
		opengl_shader_init_attribute(sdr_info->attributes[i]);
	}

	// if this shader is POST_PROCESS_MAIN, hack in the user-defined flags
	if ( sdr_info->type_id == SDR_TYPE_POST_PROCESS_MAIN ) {
		opengl_post_init_uniforms(flags);
	}

	mprintf(("Shader Variant Features:\n"));

	// initialize all uniforms and attributes that are specific to this variant
	for ( int i = 0; i < GL_num_shader_variants; ++i ) {
		opengl_shader_variant_t &variant = GL_shader_variants[i];

		if ( sdr_info->type_id == variant.type_id && variant.flag & flags ) {
			for (int j = 0; j < variant.num_uniforms; ++j) {
				opengl_shader_init_uniform(variant.uniforms[j]);
			}

			for (int j = 0; j < variant.num_attributes; ++j) {
				opengl_shader_init_attribute(variant.attributes[j]);
			}

			mprintf(("	%s\n", variant.description));
		}
	}

	opengl_shader_set_current();

	// add it to our list of embedded shaders
	// see if we have empty shader slots
	empty_idx = -1;
	for ( int i = 0; i < (int)GL_shader.size(); ++i ) {
		if ( GL_shader[i].shader == NUM_SHADER_TYPES ) {
			empty_idx = i;
			break;
		}
	}

	// then insert it at an empty slot or at the end
	if ( empty_idx >= 0 ) {
		GL_shader[empty_idx] = new_shader;
		sdr_index = empty_idx;
	} else {
		sdr_index = GL_shader.size();
		GL_shader.push_back(new_shader);
	}

	return sdr_index;
}