Blame c++/contourgl/utils.cpp

Ivan Mahonin 49e693
/*
Ivan Mahonin 49e693
    ......... 2015 Ivan Mahonin
Ivan Mahonin 49e693
Ivan Mahonin 49e693
    This program is free software: you can redistribute it and/or modify
Ivan Mahonin 49e693
    it under the terms of the GNU General Public License as published by
Ivan Mahonin 49e693
    the Free Software Foundation, either version 3 of the License, or
Ivan Mahonin 49e693
    (at your option) any later version.
Ivan Mahonin 49e693
Ivan Mahonin 49e693
    This program is distributed in the hope that it will be useful,
Ivan Mahonin 49e693
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Ivan Mahonin 49e693
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Ivan Mahonin 49e693
    GNU General Public License for more details.
Ivan Mahonin 49e693
Ivan Mahonin 49e693
    You should have received a copy of the GNU General Public License
Ivan Mahonin 49e693
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
Ivan Mahonin 49e693
*/
Ivan Mahonin 49e693
Ivan Mahonin 49e693
#include <fstream>
Ivan Mahonin 49e693
Ivan Mahonin 49e693
#include "utils.h"
Ivan Mahonin 49e693
#include "glcontext.h"
Ivan Mahonin 49e693
Ivan Mahonin 49e693
Ivan Mahonin 49e693
using namespace std;
Ivan Mahonin 49e693
Ivan Mahonin 49e693
Ivan Mahonin 49e693
Vector Utils::get_frame_size() {
Ivan Mahonin 49e693
	int vp[4] = {};
Ivan Mahonin 49e693
	glGetIntegerv(GL_VIEWPORT, vp);
Ivan Mahonin 49e693
	return Vector((Real)vp[2], (Real)vp[3]);
Ivan Mahonin 49e693
}
Ivan Mahonin 49e693
Ivan Mahonin 49e693
void Utils::save_rgba(
Ivan Mahonin 49e693
	const void *buffer,
Ivan Mahonin 49e693
	int width,
Ivan Mahonin 49e693
	int height,
Ivan Mahonin 49e693
	bool flip,
Ivan Mahonin 49e693
	const string &filename )
Ivan Mahonin 49e693
{
Ivan Mahonin 49e693
	// create file
Ivan Mahonin 49e693
	ofstream f(("results/" + filename).c_str(), ofstream::out | ofstream::trunc | ofstream::binary);
Ivan Mahonin 49e693
Ivan Mahonin 49e693
	// write header
Ivan Mahonin 49e693
	unsigned char targa_header[] = {
Ivan Mahonin 49e693
		0,    // Length of the image ID field (0 - no ID field)
Ivan Mahonin 49e693
		0,    // Whether a color map is included (0 - no colormap)
Ivan Mahonin 49e693
		2,    // Compression and color types (2 - uncompressed true-color image)
Ivan Mahonin 49e693
		0, 0, 0, 0, 0, // Color map specification (not need for us)
Ivan Mahonin 49e693
		0, 0, // X-origin
Ivan Mahonin 49e693
		0, 0, // Y-origin
Ivan Mahonin 49e693
		(unsigned char)(width & 0xff), // Image width
Ivan Mahonin 49e693
		(unsigned char)(width >> 8),
Ivan Mahonin 49e693
		(unsigned char)(height & 0xff), // Image height
Ivan Mahonin 49e693
		(unsigned char)(height >> 8),
Ivan Mahonin 49e693
		32,   // Bits per pixel
Ivan Mahonin 49e693
		0     // Image descriptor (keep zero for capability)
Ivan Mahonin 49e693
	};
Ivan Mahonin 49e693
	f.write((char*)targa_header, sizeof(targa_header));
Ivan Mahonin 49e693
Ivan Mahonin 49e693
	// write data
Ivan Mahonin 49e693
	if (flip) {
Ivan Mahonin 49e693
		int line_size = 4*width;
Ivan Mahonin 49e693
		const char *end = (char*)buffer;
Ivan Mahonin 49e693
		const char *current = end + height*line_size;
Ivan Mahonin 49e693
		while(current > end) {
Ivan Mahonin 49e693
			current -= line_size;
Ivan Mahonin 49e693
			f.write(current, line_size);
Ivan Mahonin 49e693
		}
Ivan Mahonin 49e693
	} else {
Ivan Mahonin 49e693
		f.write((const char*)buffer, 4*width*height);
Ivan Mahonin 49e693
	}
Ivan Mahonin 49e693
}
Ivan Mahonin 49e693
Ivan Mahonin 49e693
void Utils::save_viewport(const string &filename) {
Ivan Mahonin 49e693
	glFinish();
Ivan Mahonin 49e693
Ivan Mahonin 49e693
	GLint  vp[4] = {};
Ivan Mahonin 49e693
	glGetIntegerv(GL_VIEWPORT, vp);
Ivan Mahonin 49e693
Ivan Mahonin 49e693
	GLint draw_buffer = 0, read_buffer = 0;
Ivan Mahonin 49e693
	glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &draw_buffer);
Ivan Mahonin 49e693
	glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &read_buffer);
Ivan Mahonin 49e693
	if (draw_buffer != read_buffer) {
Ivan Mahonin 49e693
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint)read_buffer);
Ivan Mahonin 49e693
		glBindFramebuffer(GL_READ_FRAMEBUFFER, (GLuint)draw_buffer);
Ivan Mahonin 49e693
		glBlitFramebuffer(vp[0], vp[1], vp[2], vp[3], vp[0], vp[1], vp[2], vp[3], GL_COLOR_BUFFER_BIT, GL_NEAREST);
Ivan Mahonin 49e693
		glFinish();
Ivan Mahonin 49e693
		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, (GLuint)draw_buffer);
Ivan Mahonin 49e693
		glBindFramebuffer(GL_READ_FRAMEBUFFER, (GLuint)read_buffer);
Ivan Mahonin 49e693
	}
Ivan Mahonin 49e693
Ivan Mahonin 49e693
	char *buffer = new char[vp[2]*vp[3]*4];
Ivan Mahonin 49e693
	glReadPixels(vp[0], vp[1], vp[2], vp[3], GL_BGRA, GL_UNSIGNED_BYTE, buffer);
Ivan Mahonin 49e693
Ivan Mahonin 49e693
Ivan Mahonin 49e693
	save_rgba(buffer, vp[2], vp[3], false, filename);
Ivan Mahonin 49e693
	delete buffer;
Ivan Mahonin 49e693
}
Ivan Mahonin 49e693
Ivan Mahonin 49e693
void Utils::save_surface(const Surface &surface, const string &filename) {
Ivan Mahonin 49e693
	unsigned char *buffer = new unsigned char[4*surface.count()];
Ivan Mahonin 49e693
	unsigned char *j = buffer;
Ivan Mahonin 49e693
	for(Color *i = surface.data, *end = i + surface.count(); i != end; ++i, j += 4) {
Ivan Mahonin 49e693
		j[0] = (unsigned char)roundf(max(0.f, min(1.f, i->b))*255.f);
Ivan Mahonin 49e693
		j[1] = (unsigned char)roundf(max(0.f, min(1.f, i->g))*255.f);
Ivan Mahonin 49e693
		j[2] = (unsigned char)roundf(max(0.f, min(1.f, i->r))*255.f);
Ivan Mahonin 49e693
		j[3] = (unsigned char)roundf(max(0.f, min(1.f, i->a))*255.f);
Ivan Mahonin 49e693
	}
Ivan Mahonin 49e693
	save_rgba(buffer, surface.width, surface.height, false, filename);
Ivan Mahonin 49e693
	delete buffer;
Ivan Mahonin 49e693
}