/* validate shader */
bool is_valid (GLuint sp) {
	int params = -1;

	glValidateProgram (sp);
	glGetProgramiv (sp, GL_VALIDATE_STATUS, &params);
	printf ("program %i GL_VALIDATE_STATUS = %i\n", sp, params);
	if (GL_TRUE != params) {
		_print_programme_info_log (sp);
		return false;
	}
	return true;
}
Esempio n. 2
0
int main(){

	assert(restart_gl_log());
	assert(start_gl());

	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LESS);

	GLfloat points[] = {
			 0.0f,	0.5f,	0.0f,
			 0.5f, -0.5f,	0.0f,
			-0.5f, -0.5f,	0.0f
	};

	GLfloat colours[] = {
			1.0f, 0.0f,  0.0f,
			0.0f, 1.0f,  0.0f,
			0.0f, 0.0f,  1.0f
	};

	GLuint vao;
	char vertex_shader[1024 * 256];
	char fragmet_shader[1024 * 256];
	GLuint vs, fs, shader_programme;
	const GLchar* p;
	int params = -1;

	GLuint points_vbo;
	GLuint colours_vbo;

	glGenBuffers(1, &points_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
	glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), points, GL_STATIC_DRAW);

	/* create a second VBO, containing the array of colours.
	note that we could also put them both into a single vertex buffer. in this
	case we would use the pointer and stride parameters of glVertexAttribPointer()
	to describe the different data layouts */
	glGenBuffers(1, &colours_vbo);
	glBindBuffer(GL_ARRAY_BUFFER, colours_vbo);
	glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(GLfloat), colours, GL_STATIC_DRAW);

	/* create the VAO.
	we bind each VBO in turn, and call glVertexAttribPointer() to indicate where
	the memory should be fetched for vertex shader input variables 0, and 1,
	respectively. we also have to explicitly enable both 'attribute' variables.
	'attribute' is the older name for vertex shader 'in' variables. */
	glGenVertexArrays(1, &vao);
	glBindVertexArray(vao);
	glBindBuffer(GL_ARRAY_BUFFER, points_vbo);
	glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
	glBindBuffer(GL_ARRAY_BUFFER, colours_vbo);
	glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);
	glEnableVertexAttribArray(0);
	glEnableVertexAttribArray(1);

	// Load shaders from files here
	assert(parse_file_into_str("test_vs.glsl", vertex_shader, 1024*256));
	assert(parse_file_into_str("test_fs.glsl", fragmet_shader, 1024*256));

	vs = glCreateShader(GL_VERTEX_SHADER);
	p = (const GLchar*)vertex_shader;
	glShaderSource(vs, 1, &p, NULL);
	glCompileShader(vs);

	// Check for shader compile errors
	glGetShaderiv(vs, GL_COMPILE_STATUS, &params);
	if(GL_TRUE != params){
		fprintf (stderr, "ERROR: GL shader index %i did not compile\n", vs);
		_print_shader_info_log (vs);
		return 1; /* or exit or something */
	}

	fs = glCreateShader(GL_FRAGMENT_SHADER);
	p = (const GLchar*)fragmet_shader;
	glShaderSource (fs, 1, &p, NULL);
	glCompileShader (fs);

	// Check for shader compile errors
	glGetShaderiv(fs, GL_COMPILE_STATUS, &params);
	if(GL_TRUE != params){
		fprintf (stderr, "ERROR: GL shader index %i did not compile\n", fs);
		_print_shader_info_log (fs);
		return 1; /* or exit or something */
	}

    shader_programme = glCreateProgram();
    glAttachShader(shader_programme, fs);
    glAttachShader(shader_programme, vs);
    glLinkProgram(shader_programme);

    /* check for shader linking errors - very important! */
	glGetProgramiv (shader_programme, GL_LINK_STATUS, &params);
	if (GL_TRUE != params) {
		fprintf (
			stderr,
			"ERROR: could not link shader programme GL index %i\n",
			shader_programme
		);
		_print_programme_info_log (shader_programme);
		return 1;
	}

	glEnable (GL_CULL_FACE); // cull face
	glCullFace (GL_BACK); // cull back face
	glFrontFace (GL_CW); // GL_CCW for counter clock-wise

	while(!glfwWindowShouldClose(g_window)){
		_update_fps_counter(g_window);
		// wipe the drawing  surface clear
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glViewport(0, 0, g_gl_width, g_gl_height);

		glUseProgram(shader_programme);
		glBindVertexArray(vao);

		/* draw points 0-3 from the currently bound VAO with current in-use
         shader */
		glDrawArrays(GL_TRIANGLES, 0, 3);

		// Update events like input
		glfwPollEvents();
		if(GLFW_PRESS == glfwGetKey(g_window, GLFW_KEY_ESCAPE)){
			glfwSetWindowShouldClose(g_window, 1);
		}
		// put the stuff we ve been drawing onto the display
		glfwSwapBuffers(g_window);
	}

	// close GL context and any other GLFW resources
	glfwTerminate();

	return 0;

}
/* print absolutely everything about a shader - only useful if you get really
stuck wondering why a shader isn't working properly */
void print_all (GLuint sp) {
	int params = -1;
	int i;

	printf ("--------------------\nshader programme %i info:\n", sp);
	glGetProgramiv (sp, GL_LINK_STATUS, &params);
	printf ("GL_LINK_STATUS = %i\n", params);
	
	glGetProgramiv (sp, GL_ATTACHED_SHADERS, &params);
	printf ("GL_ATTACHED_SHADERS = %i\n", params);
	
	glGetProgramiv (sp, GL_ACTIVE_ATTRIBUTES, &params);
	printf ("GL_ACTIVE_ATTRIBUTES = %i\n", params);
	
	for (i = 0; i < params; i++) {
		char name[64];
		int max_length = 64;
		int actual_length = 0;
		int size = 0;
		GLenum type;
		glGetActiveAttrib (sp, i, max_length, &actual_length, &size, &type, name);
		if (size > 1) {
			int j;
			for (j = 0; j < size; j++) {
				char long_name[64];
				int location;

				sprintf (long_name, "%s[%i]", name, j);
				location = glGetAttribLocation (sp, long_name);
				printf ("  %i) type:%s name:%s location:%i\n",
					i, GL_type_to_string (type), long_name, location);
			}
		} else {
			int location = glGetAttribLocation (sp, name);
			printf ("  %i) type:%s name:%s location:%i\n",
				i, GL_type_to_string (type), name, location);
		}
	}
	
	glGetProgramiv (sp, GL_ACTIVE_UNIFORMS, &params);
	printf ("GL_ACTIVE_UNIFORMS = %i\n", params);
	for (i = 0; i < params; i++) {
		char name[64];
		int max_length = 64;
		int actual_length = 0;
		int size = 0;
		GLenum type;
		glGetActiveUniform (sp, i, max_length, &actual_length, &size, &type, name);
		if (size > 1) {
			int j;
			for (j = 0; j < size; j++) {
				char long_name[64];
				int location;

				sprintf (long_name, "%s[%i]", name, j);
				location = glGetUniformLocation (sp, long_name);
				printf ("  %i) type:%s name:%s location:%i\n",
					i, GL_type_to_string (type), long_name, location);
			}
		} else {
			int location = glGetUniformLocation (sp, name);
			printf ("  %i) type:%s name:%s location:%i\n",
				i, GL_type_to_string (type), name, location);
		}
	}
	
	_print_programme_info_log (sp);
}
int main () {
	GLfloat points[] = {
		 0.0f,	0.5f,	0.0f,
		 0.5f, -0.5f,	0.0f,
		-0.5f, -0.5f,	0.0f
	};
	GLuint vbo;
	GLuint vao;
	char vertex_shader[1024 * 256];
	char fragment_shader[1024 * 256];
	GLuint vs, fs, shader_programme;
	const GLchar* p;
	int params = -1;
	GLint colour_loc;

	assert (restart_gl_log ());
	assert (start_gl ());
	
	/* tell GL to only draw onto a pixel if the shape is closer to the viewer */
	glEnable (GL_DEPTH_TEST); /* enable depth-testing */
	glDepthFunc (GL_LESS); /* depth-testing interprets a smaller value as "closer" */
	
	
	glGenBuffers (1, &vbo);
	glBindBuffer (GL_ARRAY_BUFFER, vbo);
	glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW);
	
	glGenVertexArrays (1, &vao);
	glBindVertexArray (vao);
	glEnableVertexAttribArray (0);
	glBindBuffer (GL_ARRAY_BUFFER, vbo);
	glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
	
	/* load shaders from files here */
	
	assert (parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256));
	assert (parse_file_into_str ("test_fs.glsl", fragment_shader, 1024 * 256));
	
	vs = glCreateShader (GL_VERTEX_SHADER);
	p = (const GLchar*)vertex_shader;
	glShaderSource (vs, 1, &p, NULL);
	glCompileShader (vs);
	
	/* check for shader compile errors - very important! */
	
	glGetShaderiv (vs, GL_COMPILE_STATUS, &params);
	if (GL_TRUE != params) {
		fprintf (stderr, "ERROR: GL shader index %i did not compile\n", vs);
		_print_shader_info_log (vs);
		return 1; /* or exit or something */
	}
	
	fs = glCreateShader (GL_FRAGMENT_SHADER);
	p = (const GLchar*)fragment_shader;
	glShaderSource (fs, 1, &p, NULL);
	glCompileShader (fs);
	
	/* check for compile errors */
	glGetShaderiv (fs, GL_COMPILE_STATUS, &params);
	if (GL_TRUE != params) {
		fprintf (stderr, "ERROR: GL shader index %i did not compile\n", fs);
		_print_shader_info_log (fs);
		return 1; /* or exit or something */
	}
	
	shader_programme = glCreateProgram ();
	glAttachShader (shader_programme, fs);
	glAttachShader (shader_programme, vs);
	glLinkProgram (shader_programme);
	
	/* check for shader linking errors - very important! */
	glGetProgramiv (shader_programme, GL_LINK_STATUS, &params);
	if (GL_TRUE != params) {
		fprintf (
			stderr,
			"ERROR: could not link shader programme GL index %i\n",
			shader_programme
		);
		_print_programme_info_log (shader_programme);
		return 1;
	}
	print_all (shader_programme);
	assert (is_valid (shader_programme));
	
	colour_loc = glGetUniformLocation (shader_programme, "inputColour");
	assert (colour_loc > -1);
	glUseProgram (shader_programme);
	glUniform4f (colour_loc, 1.0f, 0.0f, 0.0f, 1.0f);
	
	while (!glfwWindowShouldClose (g_window)) {
		_update_fps_counter (g_window);
		/* wipe the drawing surface clear */
		glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		glViewport (0, 0, g_gl_width, g_gl_height);
		
		glUseProgram (shader_programme);
		glBindVertexArray (vao);
		/* draw points 0-3 from the currently bound VAO with current in-use shader */
		glDrawArrays (GL_TRIANGLES, 0, 3);
		/* update other events like input handling */
		glfwPollEvents ();
		if (GLFW_PRESS == glfwGetKey (g_window, GLFW_KEY_ESCAPE)) {
			glfwSetWindowShouldClose (g_window, 1);
		}
		/* put the stuff we've been drawing onto the display */
		glfwSwapBuffers (g_window);
	}
	
	/* close GL context and any other GLFW resources */
	glfwTerminate();
	return 0;
}