//
// load a simple vertex shader + fragment shader pair from files
// and compile+link it into a new shader program
// returns handle to program
GLuint link_programme_from_files (const char* vs_file_name,
	const char* fs_file_name) {
	char* vs_str = NULL;
	char* fs_str = NULL;
	GLuint vs, fs, sp;
	long vs_sz, fs_sz;
	int params = -1;

	// work out size of files
	vs_sz = get_file_size (vs_file_name);
	fs_sz = get_file_size (fs_file_name);
	if (!vs_sz || !fs_sz) {
		return 0;
	}
	vs_str = (char*)malloc (vs_sz + 1); // oddly had to do +1 sometimes
	fs_str = (char*)malloc (fs_sz + 1); // oddly had to do +1 sometimes
	// read files intro strings
	if (!parse_file_into_str (vs_file_name, vs_str)) {
		return 0;
	}
	if (!parse_file_into_str (fs_file_name, fs_str)) {
		return 0;
	}
	// create GPU shaders
	vs = glCreateShader (GL_VERTEX_SHADER);
	fs = glCreateShader (GL_FRAGMENT_SHADER);
	glShaderSource (vs, 1, (const char**)&vs_str, NULL);
	glShaderSource (fs, 1, (const char**)&fs_str, NULL);
	free (vs_str);
	free (fs_str);
	glCompileShader (vs);
	// check for compile errors
	glGetShaderiv (vs, GL_COMPILE_STATUS, &params);
	if (GL_TRUE != params) {
		fprintf (stderr, "ERROR: vertex shader %s did not compile\n", vs_file_name);
		print_shader_info_log (vs);
		return 0; // or exit or something
	}
	glCompileShader (fs);
	// check for compile errors
	glGetShaderiv (fs, GL_COMPILE_STATUS, &params);
	if (GL_TRUE != params) {
		fprintf (stderr, "ERROR: frag shader %s did not compile\n", fs_file_name);
		print_shader_info_log (fs);
		return 0; // or exit or something
	}
	sp = glCreateProgram ();
	glAttachShader (sp, vs);
	glAttachShader (sp, fs);
	glLinkProgram (sp);
	
	return sp;
}
예제 #2
0
int init_shaders(Shader *shader,
	const char *vertex_shader_loc,
	const char *fragment_shader_loc)
{
	int params = -1;
	int length;
	char vertex_shader_source[1024 * 256];
	char fragment_shader_source[1024 * 256];
	const GLchar *p;

	parse_file_into_str(vertex_shader_loc, vertex_shader_source, 1024 * 256);
    shader->vertexShader = glCreateShader(GL_VERTEX_SHADER);
    p = (const GLchar *)vertex_shader_source;
    glShaderSource(shader->vertexShader, 1, &p, NULL);
    glCompileShader(shader->vertexShader);
    glGetShaderiv(shader->vertexShader, GL_COMPILE_STATUS, &params);
    if (GL_TRUE != params) {
        fprintf(stderr, "ERROR: GL shader index %i did not compile\n", shader->vertexShader);
        print_shader_info_log(shader->vertexShader);
        return 1;
    }

    parse_file_into_str(fragment_shader_loc, fragment_shader_source, 1024 * 256);
    shader->fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    p = (const GLchar *)fragment_shader_source;
    glShaderSource(shader->fragmentShader, 1, &p, NULL);
    glCompileShader(shader->fragmentShader);
    glGetShaderiv(shader->fragmentShader, GL_COMPILE_STATUS, &params);
    if (GL_TRUE != params) {
        fprintf(stderr, "ERROR: GL shader index %i did not compile\n", shader->fragmentShader);
        print_shader_info_log(shader->fragmentShader);
        return 1;
    }

    shader->program = glCreateProgram();
    glAttachShader(shader->program, shader->fragmentShader);
    glAttachShader(shader->program, shader->vertexShader);    
    glLinkProgram(shader->program);
    glGetProgramiv(shader->program, GL_LINK_STATUS, &params);
    if (GL_TRUE != params) {
        fprintf(stderr, "ERROR: could not link shader programme GL index %i\n",shader->program);
        print_program_info_log(shader->program);
        return 1;
    }

	shader->projection_matrix_location = glGetUniformLocation(shader->program, "projection");
	shader->view_matrix_location = glGetUniformLocation(shader->program, "view");

    return 0;
}
예제 #3
0
bool check_shader_errors (GLuint shader) {
	GLint params = -1;
	glGetShaderiv (shader, GL_COMPILE_STATUS, &params);
	if (GL_TRUE != params) {
		fprintf (stderr, "ERROR: shader %u did not compile\n", shader);
		print_shader_info_log (shader);
		return false;
	}
	return true;
}
예제 #4
0
static inline GLuint compile_shader(GLenum type, const char *source, int len){
  GLint status;
  GLuint shader = glCreateShader(type);
#if (defined DEBUG) && !(defined NDEBUG)
  DEBUG_PRINTF("Compiling %s\n", shader_type_to_string(type));
#endif
  if(len == 0){
    len = strlen(source);
  }
  glShaderSource(shader, 1, &source, &len);
  glCompileShader(shader);
  glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  if(!status){
    print_shader_info_log(shader, "Error when compiling shader.\n");
    exit(EXIT_FAILURE);
  }
  //always print shader info when debbuing is enabled#
#if (defined DEBUG) && !(defined NDEBUG)
  print_shader_info_log(shader, "");
#endif
  return shader;
}
bool create_shader (const char* file_name, GLuint* shader, GLenum type) {
	gl_log ("creating shader from %s...\n", file_name);
	char shader_string[MAX_SHADER_LENGTH];
	assert (parse_file_into_str (file_name, shader_string, MAX_SHADER_LENGTH));
	*shader = glCreateShader (type);
	const GLchar* p = (const GLchar*)shader_string;
	glShaderSource (*shader, 1, &p, NULL);
	glCompileShader (*shader);
	// check for compile errors
	int params = -1;
	glGetShaderiv (*shader, GL_COMPILE_STATUS, &params);
	if (GL_TRUE != params) {
		gl_log_err ("ERROR: GL shader index %i did not compile\n", *shader);
		print_shader_info_log (*shader);
		return false; // or exit or something
	}
	gl_log ("shader compiled. index %i\n", *shader);
	return true;
}
예제 #6
0
/*****************************************************************************\
 * read_shader                                                               *
\*****************************************************************************/
GLuint read_shader(const std::string &vertex_filename,
                   const std::string &fragment_filename)
{
  GLint        status;
  std::string  source;
  const char  *cstring;
  GLuint       program;

  if(access(vertex_filename.data(),F_OK) == -1)
  {
      std::cerr<<"Cannot load shader file "<<vertex_filename<<std::endl;
      std::cerr<<"Wrong path ?"<<std::endl;
      abort();
  }
  if(access(fragment_filename.data(),F_OK) == -1)
  {
      std::cerr<<"Cannot load shader file "<<vertex_filename<<std::endl;
      std::cerr<<"Wrong path ?"<<std::endl;
      abort();
  }


  program = glCreateProgram(); PRINT_OPENGL_ERROR();

  // Create the vertex shader.
  if (vertex_filename != "")
    {
      GLuint handle = glCreateShader(GL_VERTEX_SHADER); PRINT_OPENGL_ERROR();
      source = get_file_content(vertex_filename);
      cstring = source.c_str();
      glShaderSource(handle, 1, &cstring, NULL);   PRINT_OPENGL_ERROR();
      // Compile the vertex shader, and print out the compiler log file.
      glCompileShader(handle); PRINT_OPENGL_ERROR();
      glGetShaderiv(handle, GL_COMPILE_STATUS, &status); PRINT_OPENGL_ERROR();
      print_shader_info_log(handle);
      glAttachShader(program, handle); PRINT_OPENGL_ERROR();
      if (!status) return 0;
    }

  // Create the fragment shader
  if (fragment_filename != "")
    {
      GLuint handle = glCreateShader(GL_FRAGMENT_SHADER); PRINT_OPENGL_ERROR();
      source = get_file_content(fragment_filename);
      cstring = source.c_str();
      glShaderSource(handle, 1, &cstring, NULL); PRINT_OPENGL_ERROR();
      // Compile the fragment shader, and print out the compiler log file.
      glCompileShader(handle); PRINT_OPENGL_ERROR();
      glGetShaderiv(handle, GL_COMPILE_STATUS, &status); PRINT_OPENGL_ERROR();
      print_shader_info_log(handle);
      glAttachShader(program, handle); PRINT_OPENGL_ERROR();
      if (!status) return 0;
    }

  // Link the program object and print out the info log.
  glLinkProgram(program); PRINT_OPENGL_ERROR();
  glGetProgramiv(program, GL_LINK_STATUS, &status); PRINT_OPENGL_ERROR();
  print_program_info_log(program);
  if (!status) return 0;

  // Install program object as part of current state.
  glUseProgram(program); PRINT_OPENGL_ERROR();

  return program;
}
예제 #7
0
파일: main.cpp 프로젝트: lilijreey/opengl
int main () {
	assert (restart_gl_log ());
	// all the start-up code for GLFW and GLEW is called here
	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"


	/* OTHER STUFF GOES HERE NEXT */
	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
	};

  glm::mat4 mvp = glm::mat4(1.0f);
	
	GLuint points_vbo;
	glGenBuffers (1, &points_vbo);
	glBindBuffer (GL_ARRAY_BUFFER, points_vbo);
//	glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW);
	glBufferData (GL_ARRAY_BUFFER, 
                sizeof(g_vertex_buffer_data) * sizeof (GLfloat),
                g_vertex_buffer_data, 
                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 */
	GLuint colours_vbo;
	glGenBuffers (1, &colours_vbo);
	glBindBuffer (GL_ARRAY_BUFFER, colours_vbo);
//	glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW);
	glBufferData (GL_ARRAY_BUFFER, 
                sizeof(g_color_buffer_data) * sizeof (GLfloat),
                g_color_buffer_data, 
                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. */
	GLuint vao;
	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);
	
	char vertex_shader[1024 * 256];
	char fragment_shader[1024 * 256];
	assert (parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256));
	assert (parse_file_into_str ("test_fs.glsl", fragment_shader, 1024 * 256));
	
	GLuint vs = glCreateShader (GL_VERTEX_SHADER);
	const GLchar* p = (const GLchar*)vertex_shader;
	glShaderSource (vs, 1, &p, NULL);
	glCompileShader (vs);
	
	// check for compile errors
	int params = -1;
	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
	}
	
	GLuint 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
	}
	
	GLuint shader_programme = glCreateProgram ();
	glAttachShader (shader_programme, fs);
	glAttachShader (shader_programme, vs);
  glBindAttribLocation(shader_programme, 0, "vertex_position");
  glBindAttribLocation(shader_programme, 1, "vertex_colour");
	glLinkProgram (shader_programme);
	
	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 false;
	}

//pass uniform
    GLint u = glGetUniformLocation(shader_programme, "mvp");
    assert (u > -1);
    glUniformMatrix4fv(u, 1, GL_FALSE, &mvp[0][0]);

	
	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, 12* 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;
}
예제 #8
0
파일: shader.c 프로젝트: qioixiy/notes
GLuint setup_shader_program(char * sourcefilename)
{
  GLuint retval;
  GLuint frag_shader, shader_program;
  char *frag_source;
  GLchar ** frag_sourcep;
  
  frag_shader = glCreateShader(GL_FRAGMENT_SHADER); 

  if (0 == frag_shader)
    {
      fprintf(stderr, "Error creating shader\n");
      check_error("Error creating fragment shader");
      retval = 0; /* error  */
    }
  else
    {
     /* read the source from sourcefilename into a string  */
      /* pointed to by frag_source.                          */
  
      frag_source = textFileRead(sourcefilename);
  
      if (NULL == frag_source)
	{
	  fprintf(stderr, "Error:no file to read the fragment shader from\n");
	  fprintf(stderr, "  can't find file '%s'\n", sourcefilename);
	  retval = 0; /* error  */
	}
      
      frag_sourcep = &frag_source;

      glShaderSource(frag_shader, 1, (const GLchar **)frag_sourcep,NULL);

      check_error("after glShaderSource");

      /* compile the source we loaded into the fragment shader */
      glCompileShader(frag_shader);

      check_error("after glCompileShader");

      shader_program = glCreateProgram();
      
      if (0 == shader_program)
	{
	  fprintf(stderr,
		  "Error creating shader program with glCreateProgram\n");
	  check_error("Error creating shader program");
	  retval =  0; /* error  */
	}
      else
	{
	  glAttachShader(shader_program, frag_shader);

	  check_error("after glAttachShader");

	  glLinkProgram(shader_program);
	  check_error("after glAttachShader");

	  /* print out any link-stage warnings or errors  */
	  print_shader_info_log(shader_program);


	  /* make this program part of the opengl state  */
  
	  glUseProgram(shader_program);
	  check_error("after glUseProgram");

	  retval = shader_program;
	}
    } 
  return(retval);
}
예제 #9
0
int main () {
	restart_gl_log ();
	// all the GLFW and GLEW start-up code is moved to here in gl_utils.cpp
	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"

	/* OTHER STUFF GOES HERE NEXT */
	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 points_vbo;
	glGenBuffers (1, &points_vbo);
	glBindBuffer (GL_ARRAY_BUFFER, points_vbo);
	glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW);
	
	GLuint colours_vbo;
	glGenBuffers (1, &colours_vbo);
	glBindBuffer (GL_ARRAY_BUFFER, colours_vbo);
	glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW);
	
	GLuint vao;
	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);
	
	char vertex_shader[1024 * 256];
	char fragment_shader[1024 * 256];
	parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256);
	parse_file_into_str ("test_fs.glsl", fragment_shader, 1024 * 256);
	
	GLuint vs = glCreateShader (GL_VERTEX_SHADER);
	const GLchar* p = (const GLchar*)vertex_shader;
	glShaderSource (vs, 1, &p, NULL);
	glCompileShader (vs);
	
	// check for compile errors
	int params = -1;
	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
	}
	
	GLuint 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
	}
	
	GLuint shader_programme = glCreateProgram ();
	glAttachShader (shader_programme, fs);
	glAttachShader (shader_programme, vs);
	glLinkProgram (shader_programme);
	
	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 false;
	}
	
	GLfloat matrix[] = {
		1.0f, 0.0f, 0.0f, 0.0f, // first column
		0.0f, 1.0f, 0.0f, 0.0f, // second column
		0.0f, 0.0f, 1.0f, 0.0f, // third column
		0.5f, 0.0f, 0.0f, 1.0f // fourth column
	};
	
	int matrix_location = glGetUniformLocation (shader_programme, "matrix");
	glUseProgram (shader_programme);
	glUniformMatrix4fv (matrix_location, 1, GL_FALSE, matrix);
	
	glEnable (GL_CULL_FACE); // cull face
	glCullFace (GL_BACK); // cull back face
	glFrontFace (GL_CW); // GL_CCW for counter clock-wise
	
	float speed = 1.0f; // move at 1 unit per second
	float last_position = 0.0f;
	while (!glfwWindowShouldClose (g_window)) {
		// add a timer for doing animation
		static double previous_seconds = glfwGetTime ();
		double current_seconds = glfwGetTime ();
		double elapsed_seconds = current_seconds - previous_seconds;
		previous_seconds = current_seconds;
		
		_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);
		
		//
		// Note: this call is not necessary, but I like to do it anyway before any
		// time that I call glDrawArrays() so I never use the wrong shader programme
		glUseProgram (shader_programme);
		
		// update the matrix
		// - you could simplify this by just using sin(current_seconds)
		matrix[12] = elapsed_seconds * speed + last_position;
		last_position = matrix[12];
		if (fabs (last_position) > 1.0) {
			speed = -speed;
		}
		//
		// Note: this call is related to the most recently 'used' shader programme
		glUniformMatrix4fv (matrix_location, 1, GL_FALSE, matrix);
		
		//
		// Note: this call is not necessary, but I like to do it anyway before any
		// time that I call glDrawArrays() so I never use the wrong vertex data
		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;
}
예제 #10
0
GLuint shaderSetup( const char *vert, const char *frag ) {
    GLchar *vsrc = NULL, *fsrc = NULL;
    GLuint vs, fs, prog;
    GLint flag;

    // Assume that everything will work
    shaderErrorCode = E_NO_ERROR;

    // Create the shader handles
    vs = glCreateShader( GL_VERTEX_SHADER );
    fs = glCreateShader( GL_FRAGMENT_SHADER );

    // Read in shader source
    vsrc = read_text_file( vert );
    if( vsrc == NULL ) {
        fprintf( stderr, "Error reading vertex shader file %s\n",
             vert);
        shaderErrorCode = E_VS_LOAD;
        return( 0 );
    }

    fsrc = read_text_file( frag );
    if( fsrc == NULL ) {
        fprintf( stderr, "Error reading fragment shader file %s\n",
             frag);
        shaderErrorCode = E_FS_LOAD;
#ifdef __cplusplus
        delete [] vsrc;
#else
        free( vsrc );
#endif
        return( 0 );
    }

    // Attach the source to the shaders
    glShaderSource( vs, 1, (const GLchar **) &vsrc, NULL );
    glShaderSource( fs, 1, (const GLchar **) &fsrc, NULL );

    // We're done with the source code now
#ifdef __cplusplus
    delete [] vsrc;
    delete [] fsrc;
#else
    free(vsrc);
    free(fsrc);
#endif

    // Compile the shaders, and print any relevant message logs
    glCompileShader( vs );
    glGetShaderiv( vs, GL_COMPILE_STATUS, &flag );
    print_shader_info_log( vs );
    if( flag == GL_FALSE ) {
        shaderErrorCode = E_VS_COMPILE;
        return( 0 );
    }

    glCompileShader( fs );
    glGetShaderiv( fs, GL_COMPILE_STATUS, &flag );
    print_shader_info_log( fs );
    if( flag == GL_FALSE ) {
        shaderErrorCode = E_FS_COMPILE;
        return( 0 );
    }

    // Create the program and attach the shaders
    prog = glCreateProgram();
    glAttachShader( prog, vs );
    glAttachShader( prog, fs );

    // Report any message log information
    print_program_info_log( prog );

    // Link the program, and print any message log information
    glLinkProgram( prog );
    glGetProgramiv( prog, GL_LINK_STATUS, &flag );
    print_program_info_log( prog );
    if( flag == GL_FALSE ) {
        shaderErrorCode = E_SHADER_LINK;
        return( 0 );
    }

    return( prog );

}
int main () {
	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"
	glClearColor (0.2, 0.2, 0.2, 1.0);

	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 points_vbo;
	glGenBuffers (1, &points_vbo);
	glBindBuffer (GL_ARRAY_BUFFER, points_vbo);
	glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW);
	
	GLuint colours_vbo;
	glGenBuffers (1, &colours_vbo);
	glBindBuffer (GL_ARRAY_BUFFER, colours_vbo);
	glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW);
	
	GLuint vao;
	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);
	
	char vertex_shader[1024 * 256];
	char geometry_shader[1024 * 256];
	char fragment_shader[1024 * 256];
	assert (parse_file_into_str ("test_vs.glsl", vertex_shader, 1024 * 256));
	assert (parse_file_into_str ("test_gs.glsl", geometry_shader, 1024 * 256));
	assert (parse_file_into_str ("test_fs.glsl", fragment_shader, 1024 * 256));
	
	GLuint vs = glCreateShader (GL_VERTEX_SHADER);
	const GLchar* p = (const GLchar*)vertex_shader;
	glShaderSource (vs, 1, &p, NULL);
	glCompileShader (vs);
	
	// check for compile errors
	int params = -1;
	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
	}
	
	// create geometry shader
	GLuint gs = glCreateShader (GL_GEOMETRY_SHADER);
	p = (const GLchar*)geometry_shader;
	glShaderSource (gs, 1, &p, NULL);
	glCompileShader (gs);
	
	// check for compile errors
	glGetShaderiv (gs, GL_COMPILE_STATUS, &params);
	if (GL_TRUE != params) {
		fprintf (stderr, "ERROR: GL shader index %i did not compile\n", gs);
		print_shader_info_log (gs);
		return 1; // or exit or something
	}
	
	GLuint 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
	}
	
	GLuint shader_programme = glCreateProgram ();
	glAttachShader (shader_programme, fs);
	// attach geometry shader too
	glAttachShader (shader_programme, gs);
	glAttachShader (shader_programme, vs);
	glLinkProgram (shader_programme);
	
	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 false;
	}
	assert (is_programme_valid (shader_programme));
	
	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);
		// points drawing mode
		glDrawArrays (GL_POINTS, 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;
}
예제 #12
0
int main () {
	assert (restart_gl_log ());
/*------------------------------start GL context------------------------------*/
	assert (start_gl ());

/*------------------------------create geometry-------------------------------*/
	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 points_vbo;
	glGenBuffers (1, &points_vbo);
	glBindBuffer (GL_ARRAY_BUFFER, points_vbo);
	glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), points, GL_STATIC_DRAW);
	
	GLuint colours_vbo;
	glGenBuffers (1, &colours_vbo);
	glBindBuffer (GL_ARRAY_BUFFER, colours_vbo);
	glBufferData (GL_ARRAY_BUFFER, 9 * sizeof (GLfloat), colours, GL_STATIC_DRAW);
	
	GLuint vao;
	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);

/*------------------------------create shaders--------------------------------*/
	char vertex_shader[1024 * 256];
	char fragment_shader[1024 * 256];
	assert (parse_file_into_str ("Shaders/test_vs.glsl", vertex_shader, 1024 * 256));
	assert (parse_file_into_str ("Shaders/test_fs.glsl", fragment_shader, 1024 * 256));
	
	GLuint vs = glCreateShader (GL_VERTEX_SHADER);
	const GLchar* p = (const GLchar*)vertex_shader;
	glShaderSource (vs, 1, &p, NULL);
	glCompileShader (vs);
	
	// check for compile errors
	int params = -1;
	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
	}
	
	GLuint 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
	}
	
	GLuint shader_programme = glCreateProgram ();
	glAttachShader (shader_programme, fs);
	glAttachShader (shader_programme, vs);
	glLinkProgram (shader_programme);
	
	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 false;
	}
	
/*--------------------------create camera matrices----------------------------*/
	/* create PROJECTION MATRIX */
	#define ONE_DEG_IN_RAD (2.0 * M_PI) / 360.0 // 0.017444444
	// input variables
	float near = 0.1f; // clipping plane
	float far = 100.0f; // clipping plane
	float fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians
	float aspect = (float)g_gl_width / (float)g_gl_height; // aspect ratio
	// matrix components
	float range = tan (fov * 0.5f) * near;
	float Sx = (2.0f * near) / (range * aspect + range * aspect);
	float Sy = near / range;
	float Sz = -(far + near) / (far - near);
	float Pz = -(2.0f * far * near) / (far - near);
	GLfloat proj_mat[] = {
		Sx, 0.0f, 0.0f, 0.0f,
		0.0f, Sy, 0.0f, 0.0f,
		0.0f, 0.0f, Sz, -1.0f,
		0.0f, 0.0f, Pz, 0.0f
	};
	
	/* create VIEW MATRIX */
	float cam_speed = 1.0f; // 1 unit per second
	float cam_yaw_speed = 10.0f; // 10 degrees per second
	float cam_pos[] = {0.0f, 0.0f, 2.0f}; // don't start at zero, or we will be too close
	float cam_yaw = 0.0f; // y-rotation in degrees
	mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2]));
	mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw);
	mat4 view_mat = R * T;
	
	/* get location numbers of matrices in shader programme */
	GLint view_mat_location = glGetUniformLocation (shader_programme, "view");
	GLint proj_mat_location = glGetUniformLocation (shader_programme, "proj");
	/* use program (make current in state machine) and set default matrix values*/
	glUseProgram (shader_programme);
	glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m);
	glUniformMatrix4fv (proj_mat_location, 1, GL_FALSE, proj_mat);
	
/*------------------------------rendering loop--------------------------------*/
	/* some rendering defaults */
	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)) {
		static double previous_seconds = glfwGetTime ();
		double current_seconds = glfwGetTime ();
		double elapsed_seconds = current_seconds - previous_seconds;
		previous_seconds = current_seconds;
	
		_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 ();
		
/*-----------------------------move camera here-------------------------------*/
		// control keys
		bool cam_moved = false;
		if (glfwGetKey (g_window, GLFW_KEY_A)) {
			cam_pos[0] -= cam_speed * elapsed_seconds;
			cam_moved = true;
		}
		if (glfwGetKey (g_window, GLFW_KEY_D)) {
			cam_pos[0] += cam_speed * elapsed_seconds;
			cam_moved = true;
		}
		if (glfwGetKey (g_window, GLFW_KEY_PAGE_UP)) {
			cam_pos[1] += cam_speed * elapsed_seconds;
			cam_moved = true;
		}
		if (glfwGetKey (g_window, GLFW_KEY_PAGE_DOWN)) {
			cam_pos[1] -= cam_speed * elapsed_seconds;
			cam_moved = true;
		}
		if (glfwGetKey (g_window, GLFW_KEY_W)) {
			cam_pos[2] -= cam_speed * elapsed_seconds;
			cam_moved = true;
		}
		if (glfwGetKey (g_window, GLFW_KEY_S)) {
			cam_pos[2] += cam_speed * elapsed_seconds;
			cam_moved = true;
		}
		if (glfwGetKey (g_window, GLFW_KEY_LEFT)) {
			cam_yaw += cam_yaw_speed * elapsed_seconds;
			cam_moved = true;
		}
		if (glfwGetKey (g_window, GLFW_KEY_RIGHT)) {
			cam_yaw -= cam_yaw_speed * elapsed_seconds;
			cam_moved = true;
		}
		/* update view matrix */
		if (cam_moved) {
			mat4 T = translate (identity_mat4 (), vec3 (-cam_pos[0], -cam_pos[1], -cam_pos[2])); // cam translation
			mat4 R = rotate_y_deg (identity_mat4 (), -cam_yaw); // 
			mat4 view_mat = R * T;
			glUniformMatrix4fv (view_mat_location, 1, GL_FALSE, view_mat.m);
		}
		
		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;
}