/**
 * Given a set of flags, determine whether a shader with these flags exists within the GL_shader vector. If no shader with the requested flags exists, attempt to compile one.
 *
 * @param shader_t  shader_type variable, a reference to the shader program needed
 * @param flags	Integer variable, holding a combination of SDR_* flags
 * @return 		Index into GL_shader, referencing a valid shader, or -1 if shader compilation failed
 */
int gr_opengl_maybe_create_shader(shader_type shader_t, unsigned int flags)
{
	size_t idx = opengl_get_shader_idx(shader_t, flags);

	if (idx < GL_shader.size())
		return (int)idx;

	// If we are here, it means we need to compile a new shader
	return opengl_compile_shader(shader_t, flags);
}
/**
 * Given a set of flags, determine whether a shader with these flags exists within the GL_shader vector. If no shader with the requested flags exists, attempt to compile one.
 *
 * @param shader_t  shader_type variable, a reference to the shader program needed
 * @param flags	Integer variable, holding a combination of SDR_* flags
 * @return 		Index into GL_shader, referencing a valid shader, or -1 if shader compilation failed
 */
int gr_opengl_maybe_create_shader(shader_type shader_t, unsigned int flags)
{
	size_t idx;
	size_t max = GL_shader.size();

	for (idx = 0; idx < max; idx++) {
		if (GL_shader[idx].shader == shader_t && GL_shader[idx].flags == flags) {
			return (int)idx;
		}
	}

	// If we are here, it means we need to compile a new shader
	return opengl_compile_shader(shader_t, flags);
}
예제 #3
0
파일: glcc.c 프로젝트: ajithcj/miaow
int opengl_shader_binary_generator(const GLchar ** opengl_vertex_source,
	const GLchar ** opengl_fragment_source,
	const GLchar ** opengl_tessellation_control_source,
	const GLchar ** opengl_tessellation_evaluation_source,
	const GLchar ** opengl_geometry_source, const char *outputfile)
{
	int i;
	void *bin_buffer;
	FILE *f;

	GLuint opengl_vertex_shader_id = 0;
	GLuint opengl_tessellation_control_shader_id = 0;
	GLuint opengl_tessellation_evaluation_shader_id = 0;
	GLuint opengl_geometry_shader_id = 0;
	GLuint opengl_fragment_shader_id = 0;

	GLint status;
	GLint formats;
	GLint logLen;
	GLsizei written;
	GLint bin_length;

	if (!opengl_vertex_source || !opengl_fragment_source)
		return -1;

	/* Compile shaders */
	opengl_vertex_shader_id =
		opengl_compile_shader(opengl_vertex_source, GL_VERTEX_SHADER);
	if (opengl_tessellation_control_source)
		opengl_tessellation_control_shader_id =
			opengl_compile_shader
			(opengl_tessellation_control_source,
			GL_TESS_CONTROL_SHADER);
	if (opengl_tessellation_evaluation_source)
		opengl_tessellation_evaluation_shader_id =
			opengl_compile_shader
			(opengl_tessellation_evaluation_source,
			GL_TESS_EVALUATION_SHADER);
	if (opengl_geometry_source)
		opengl_geometry_shader_id =
			opengl_compile_shader(opengl_geometry_source,
			GL_GEOMETRY_SHADER);
	opengl_fragment_shader_id =
		opengl_compile_shader(opengl_fragment_source,
		GL_FRAGMENT_SHADER);

	/* Create GL program */
	GLuint glprogram = glCreateProgram();

	if (glprogram == 0)
	{
		fprintf(stderr, "Error creating program object.\n");
		exit(1);
	}

	/* Attach shaders to program */
	glAttachShader(glprogram, opengl_vertex_shader_id);
	if (opengl_tessellation_control_shader_id != 0)
		glAttachShader(glprogram,
			opengl_tessellation_control_shader_id);
	if (opengl_tessellation_evaluation_shader_id != 0)
		glAttachShader(glprogram,
			opengl_tessellation_evaluation_shader_id);
	if (opengl_geometry_shader_id != 0)
		glAttachShader(glprogram, opengl_geometry_shader_id);
	glAttachShader(glprogram, opengl_fragment_shader_id);

	/* Link */
	glProgramParameteri(glprogram, PROGRAM_BINARY_RETRIEVABLE_HINT,
		GL_TRUE);
	glLinkProgram(glprogram);

	glGetProgramiv(glprogram, GL_LINK_STATUS, &status);
	if (status == GL_FALSE)
	{
		fprintf(stderr, "Failed to link shader program!\n");
		glGetProgramiv(glprogram, GL_INFO_LOG_LENGTH, &logLen);
		if (logLen > 0)
		{
			char *log = (char *) xmalloc(logLen);

			glGetProgramInfoLog(glprogram, logLen, &written, log);
			fprintf(stderr, "Program log: \n%s", log);
			free(log);
			exit(1);
		}
	}
	else
		glUseProgram(glprogram);

	/* Dump binary */
	glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &formats);
	GLint *binaryFormats = xcalloc(formats, sizeof(GLint));

	glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, binaryFormats);
	for (i = 0; i < formats; i++)
		printf("Format[%d]=%d\n", i, binaryFormats[i]);


	glGetProgramiv(glprogram, GL_PROGRAM_BINARY_LENGTH, &bin_length);
	printf("Shader binary has %d bytes\n", bin_length);
	bin_buffer = xmalloc(bin_length);

	f = fopen(outputfile, "wb");
	fwrite(bin_buffer, bin_length, 1, f);
	fclose(f);

	/* Process generated binary */
	if (dump_intermediate)
		opengl_shader_binary_analyze(outputfile);

	free(bin_buffer);
	return 0;
}