|
|
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 |
}
|