Blame c++/contourgl/utils.cpp

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