dungeon_crawler

annotate prototype/src/colgrade.cc @ 74:5981917093ff

color grading palette output done, all is left is the input
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 21 Oct 2012 15:56:47 +0300
parents a27528035e20
children b05ab29cd17d
rev   line source
nuclear@72 1 #include <stdio.h>
nuclear@74 2 #include <string.h>
nuclear@72 3 #include "opengl.h"
nuclear@72 4 #include "colgrade.h"
nuclear@74 5 #include "imago2.h"
nuclear@72 6
nuclear@72 7 GradePalette::GradePalette()
nuclear@72 8 {
nuclear@72 9 tex = 0;
nuclear@74 10 palette = 0;
nuclear@72 11 }
nuclear@72 12
nuclear@72 13 GradePalette::~GradePalette()
nuclear@72 14 {
nuclear@72 15 destroy();
nuclear@72 16 }
nuclear@72 17
nuclear@72 18 bool GradePalette::create(int sz)
nuclear@72 19 {
nuclear@72 20 unsigned int clamp = GLEW_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP;
nuclear@72 21
nuclear@72 22 destroy();
nuclear@72 23
nuclear@74 24 this->size = sz;
nuclear@72 25
nuclear@74 26 int nbytes = sz * sz * sz * 3;
nuclear@74 27 printf("allocating %d bytes for a color grading palette\n", nbytes);
nuclear@74 28 palette = new unsigned char[nbytes];
nuclear@72 29
nuclear@74 30 unsigned char *scanline = palette;
nuclear@74 31
nuclear@72 32 for(int i=0; i<sz; i++) { // for each slice...
nuclear@72 33 int b = 255 * i / (sz - 1);
nuclear@72 34 for(int j=0; j<sz; j++) { // for each scanline...
nuclear@72 35 int g = 255 * j / (sz - 1);
nuclear@72 36
nuclear@72 37 for(int k=0; k<sz; k++) {
nuclear@72 38 int r = 255 * k / (sz - 1);
nuclear@72 39
nuclear@72 40 scanline[k * 3] = r;
nuclear@72 41 scanline[k * 3 + 1] = g;
nuclear@72 42 scanline[k * 3 + 2] = b;
nuclear@72 43 }
nuclear@74 44 scanline += sz * 3;
nuclear@72 45 }
nuclear@72 46 }
nuclear@72 47
nuclear@74 48 glGenTextures(1, &tex);
nuclear@74 49 glBindTexture(GL_TEXTURE_3D, tex);
nuclear@74 50 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
nuclear@74 51 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
nuclear@74 52 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, clamp);
nuclear@74 53 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, clamp);
nuclear@74 54 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, clamp);
nuclear@74 55 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, sz, sz, sz, 0, GL_RGB, GL_UNSIGNED_BYTE, palette);
nuclear@74 56
nuclear@72 57 return true;
nuclear@72 58 }
nuclear@72 59
nuclear@72 60 void GradePalette::destroy()
nuclear@72 61 {
nuclear@72 62 if(tex) {
nuclear@72 63 glDeleteTextures(1, &tex);
nuclear@74 64 tex = 0;
nuclear@72 65 }
nuclear@74 66 delete [] palette;
nuclear@74 67 palette = 0;
nuclear@72 68 }
nuclear@72 69
nuclear@72 70 bool GradePalette::save_shot(const char *fname) const
nuclear@72 71 {
nuclear@74 72 if(!tex) {
nuclear@74 73 return false;
nuclear@74 74 }
nuclear@74 75
nuclear@74 76 int slice_bytes = size * size * 3;
nuclear@74 77 int nslices = size;
nuclear@74 78
nuclear@74 79 int vp[4];
nuclear@74 80 glGetIntegerv(GL_VIEWPORT, vp);
nuclear@74 81
nuclear@74 82 int xsz = vp[2];
nuclear@74 83 int ysz = vp[3];
nuclear@74 84
nuclear@74 85 // allocate more scanlines to cram the palette slices in there
nuclear@74 86 unsigned char *img = new unsigned char[xsz * (ysz + nslices) * 3];
nuclear@74 87
nuclear@74 88 glReadPixels(0, 0, vp[2], vp[3], GL_RGB, GL_UNSIGNED_BYTE, img);
nuclear@74 89
nuclear@74 90 // invert the image
nuclear@74 91 unsigned char *top = img;
nuclear@74 92 unsigned char *bot = img + xsz * (ysz - 1) * 3;
nuclear@74 93
nuclear@74 94 while(top < bot) {
nuclear@74 95 for(int j=0; j<xsz * 3; j++) {
nuclear@74 96 unsigned char tmp = top[j];
nuclear@74 97 top[j] = bot[j];
nuclear@74 98 bot[j] = tmp;
nuclear@74 99 }
nuclear@74 100 top += xsz * 3;
nuclear@74 101 bot -= xsz * 3;
nuclear@74 102 }
nuclear@74 103
nuclear@74 104 unsigned char *pal = img + xsz * ysz * 3;
nuclear@74 105 memset(pal, 0, nslices * xsz * 3);
nuclear@74 106
nuclear@74 107 for(int i=0; i<nslices; i++) {
nuclear@74 108 memcpy(pal, palette + i * slice_bytes, slice_bytes);
nuclear@74 109 pal += xsz * 3;
nuclear@74 110 }
nuclear@74 111
nuclear@74 112 int res = img_save_pixels(fname, img, xsz, ysz + nslices, IMG_FMT_RGB24);
nuclear@74 113 delete [] img;
nuclear@74 114
nuclear@74 115 return res == 0;
nuclear@72 116 }
nuclear@72 117
nuclear@72 118 bool GradePalette::load_shot(const char *fname)
nuclear@72 119 {
nuclear@72 120 return false; // TODO
nuclear@72 121 }
nuclear@72 122
nuclear@72 123 unsigned int GradePalette::get_texture() const
nuclear@72 124 {
nuclear@72 125 return tex;
nuclear@72 126 }