Blame c++/contourgl/shaders.cpp

7c6b57
/*
7c6b57
    ......... 2015 Ivan Mahonin
7c6b57
7c6b57
    This program is free software: you can redistribute it and/or modify
7c6b57
    it under the terms of the GNU General Public License as published by
7c6b57
    the Free Software Foundation, either version 3 of the License, or
7c6b57
    (at your option) any later version.
7c6b57
7c6b57
    This program is distributed in the hope that it will be useful,
7c6b57
    but WITHOUT ANY WARRANTY; without even the implied warranty of
7c6b57
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
7c6b57
    GNU General Public License for more details.
7c6b57
7c6b57
    You should have received a copy of the GNU General Public License
7c6b57
    along with this program.  If not, see <http: licenses="" www.gnu.org="">.</http:>
7c6b57
*/
7c6b57
7c6b57
#include <cassert></cassert>
7c6b57
7c6b57
#include <iostream></iostream>
7c6b57
7c6b57
#include "shaders.h"
7c6b57
7c6b57
7c6b57
using namespace std;
7c6b57
7c6b57
7c6b57
Shaders::Shaders():
7c6b57
	simple_vertex_id(),
7c6b57
	simpleProgramId(),
7c6b57
	color_fragment_id(),
7c6b57
	colorProgramId(),
7c6b57
	colorUniform()
7c6b57
{
7c6b57
	// simple
7c6b57
	const char *simpleVertexSource =
7c6b57
		"in vec2 position;\n"
7c6b57
		"void main() { gl_Position = vec4(position, 0.0, 1.0); }\n";
7c6b57
7c6b57
	simple_vertex_id = glCreateShader(GL_VERTEX_SHADER);
7c6b57
	glShaderSource(simple_vertex_id, 1, &simpleVertexSource, NULL);
7c6b57
	glCompileShader(simple_vertex_id);
7c6b57
	check_shader(simple_vertex_id, simpleVertexSource);
7c6b57
7c6b57
	simpleProgramId = glCreateProgram();
7c6b57
	glAttachShader(simpleProgramId, simple_vertex_id);
7c6b57
	glBindAttribLocation(simpleProgramId, 0, "position");
7c6b57
	glLinkProgram(simpleProgramId);
7c6b57
	check_program(simpleProgramId, "simple");
7c6b57
7c6b57
	// color
7c6b57
	const char *colorFragmentSource =
7c6b57
		"uniform vec4 color;\n"
7c6b57
		//"out vec4 colorOut;\n"
7c6b57
		"void main() { gl_FragColor = color; }\n";
7c6b57
7c6b57
	color_fragment_id = glCreateShader(GL_FRAGMENT_SHADER);
7c6b57
	glShaderSource(color_fragment_id, 1, &colorFragmentSource, NULL);
7c6b57
	glCompileShader(color_fragment_id);
7c6b57
	check_shader(color_fragment_id, colorFragmentSource);
7c6b57
7c6b57
	colorProgramId = glCreateProgram();
7c6b57
	glAttachShader(colorProgramId, simple_vertex_id);
7c6b57
	glAttachShader(colorProgramId, color_fragment_id);
7c6b57
	glBindAttribLocation(colorProgramId, 0, "position");
7c6b57
	//glBindFragDataLocation(color_program_id, 0, "colorOut");
7c6b57
	glLinkProgram(colorProgramId);
7c6b57
	check_program(colorProgramId, "color");
7c6b57
	colorUniform = glGetUniformLocation(colorProgramId, "color");
7c6b57
}
7c6b57
7c6b57
Shaders::~Shaders() {
7c6b57
	glUseProgram(0);
7c6b57
	glDeleteProgram(colorProgramId);
7c6b57
	glDeleteProgram(simpleProgramId);
7c6b57
	glDeleteShader(color_fragment_id);
7c6b57
	glDeleteShader(simple_vertex_id);
7c6b57
}
7c6b57
7c6b57
void Shaders::check_shader(GLuint id, const char *src) {
7c6b57
	GLint compileStatus = 0;
7c6b57
	glGetShaderiv(id, GL_COMPILE_STATUS, &compileStatus);
7c6b57
	if (!compileStatus) {
7c6b57
		GLint infoLogLength = 0;
7c6b57
		glGetShaderiv(id, GL_INFO_LOG_LENGTH, &infoLogLength);
7c6b57
		std::string infoLog;
7c6b57
		infoLog.resize(infoLogLength);
7c6b57
		glGetShaderInfoLog(id, infoLog.size(), &infoLogLength, &infoLog[0]);
7c6b57
		infoLog.resize(infoLogLength);
7c6b57
		cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl
7c6b57
			 << "cannot compile shader:" << endl
7c6b57
			 << "~~~~~~source~~~~~~~~~~~~~~~" << endl
7c6b57
			 << src << endl
7c6b57
			 << "~~~~~~log~~~~~~~~~~~~~~~~~~" << endl
7c6b57
			 << infoLog << endl
7c6b57
			 << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
7c6b57
	}
7c6b57
}
7c6b57
7c6b57
void Shaders::check_program(GLuint id, const char *name) {
7c6b57
 	GLint linkStatus = 0;
7c6b57
	glGetProgramiv(id, GL_LINK_STATUS, &linkStatus);
7c6b57
	if (!linkStatus) {
7c6b57
		GLint infoLogLength = 0;
7c6b57
		glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLogLength);
7c6b57
		std::string infoLog;
7c6b57
		infoLog.resize(infoLogLength);
7c6b57
		glGetProgramInfoLog(id, infoLog.size(), &infoLogLength, &infoLog[0]);
7c6b57
		infoLog.resize(infoLogLength);
7c6b57
		cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl
7c6b57
			 << "cannot link program " << name <<  ":" << endl
7c6b57
			 << "~~~~~~name~~~~~~~~~~~~~~~~~" << endl
7c6b57
			 << name << endl
7c6b57
			 << "~~~~~~log~~~~~~~~~~~~~~~~~~" << endl
7c6b57
			 << infoLog << endl
7c6b57
			 << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
7c6b57
	}
7c6b57
7c6b57
	glValidateProgram(id);
7c6b57
	GLint validateStatus = 0;
7c6b57
	glGetProgramiv(id, GL_VALIDATE_STATUS, &validateStatus);
7c6b57
	if (!validateStatus) {
7c6b57
		GLint infoLogLength = 0;
7c6b57
		glGetProgramiv(id, GL_INFO_LOG_LENGTH, &infoLogLength);
7c6b57
		std::string infoLog;
7c6b57
		infoLog.resize(infoLogLength);
7c6b57
		glGetProgramInfoLog(id, infoLog.size(), &infoLogLength, &infoLog[0]);
7c6b57
		infoLog.resize(infoLogLength);
7c6b57
		cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl
7c6b57
			 << "program not validated " << name <<  ":" << endl
7c6b57
			 << "~~~~~~name~~~~~~~~~~~~~~~~~" << endl
7c6b57
			 << name << endl
7c6b57
			 << "~~~~~~log~~~~~~~~~~~~~~~~~~" << endl
7c6b57
			 << infoLog << endl
7c6b57
			 << "~~~~~~~~~~~~~~~~~~~~~~~~~~~" << endl;
7c6b57
	}
7c6b57
}
7c6b57
7c6b57
void Shaders::simple() {
49e693
	glUseProgram(simpleProgramId);
7c6b57
}
7c6b57
7c6b57
void Shaders::color(const Color &c) {
49e693
	glUseProgram(colorProgramId);
49e693
	glUniform4fv(colorUniform, 1, c.channels);
7c6b57
}
7c6b57
7c6b57