dungeon_crawler
view prototype/src/colgrade.cc @ 78:12a1dcfe91fa
gamma correct rendering
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Fri, 26 Oct 2012 21:22:14 +0300 |
parents | 5981917093ff |
children |
line source
1 #include <stdio.h>
2 #include <string.h>
3 #include "opengl.h"
4 #include "colgrade.h"
5 #include "imago2.h"
7 GradePalette::GradePalette()
8 {
9 tex = 0;
10 palette = 0;
11 }
13 GradePalette::~GradePalette()
14 {
15 destroy();
16 }
18 bool GradePalette::create(int sz)
19 {
20 unsigned int clamp = GLEW_ARB_texture_border_clamp ? GL_CLAMP_TO_EDGE : GL_CLAMP;
22 destroy();
24 this->size = sz;
26 int nbytes = sz * sz * sz * 3;
27 printf("allocating %d bytes for a color grading palette\n", nbytes);
28 palette = new unsigned char[nbytes];
30 unsigned char *scanline = palette;
32 for(int i=0; i<sz; i++) { // for each slice...
33 int b = 255 * i / (sz - 1);
34 for(int j=0; j<sz; j++) { // for each scanline...
35 int g = 255 * j / (sz - 1);
37 for(int k=0; k<sz; k++) {
38 int r = 255 * k / (sz - 1);
40 scanline[k * 3] = r;
41 scanline[k * 3 + 1] = g;
42 scanline[k * 3 + 2] = b;
43 }
44 scanline += sz * 3;
45 }
46 }
48 glGenTextures(1, &tex);
49 glBindTexture(GL_TEXTURE_3D, tex);
50 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
51 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
52 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, clamp);
53 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, clamp);
54 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, clamp);
55 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, sz, sz, sz, 0, GL_RGB, GL_UNSIGNED_BYTE, palette);
57 return true;
58 }
60 void GradePalette::destroy()
61 {
62 if(tex) {
63 glDeleteTextures(1, &tex);
64 tex = 0;
65 }
66 delete [] palette;
67 palette = 0;
68 }
70 bool GradePalette::save_shot(const char *fname) const
71 {
72 if(!tex) {
73 return false;
74 }
76 int slice_bytes = size * size * 3;
77 int nslices = size;
79 int vp[4];
80 glGetIntegerv(GL_VIEWPORT, vp);
82 int xsz = vp[2];
83 int ysz = vp[3];
85 // allocate more scanlines to cram the palette slices in there
86 unsigned char *img = new unsigned char[xsz * (ysz + nslices) * 3];
88 glReadPixels(0, 0, vp[2], vp[3], GL_RGB, GL_UNSIGNED_BYTE, img);
90 // invert the image
91 unsigned char *top = img;
92 unsigned char *bot = img + xsz * (ysz - 1) * 3;
94 while(top < bot) {
95 for(int j=0; j<xsz * 3; j++) {
96 unsigned char tmp = top[j];
97 top[j] = bot[j];
98 bot[j] = tmp;
99 }
100 top += xsz * 3;
101 bot -= xsz * 3;
102 }
104 unsigned char *pal = img + xsz * ysz * 3;
105 memset(pal, 0, nslices * xsz * 3);
107 for(int i=0; i<nslices; i++) {
108 memcpy(pal, palette + i * slice_bytes, slice_bytes);
109 pal += xsz * 3;
110 }
112 int res = img_save_pixels(fname, img, xsz, ysz + nslices, IMG_FMT_RGB24);
113 delete [] img;
115 return res == 0;
116 }
118 bool GradePalette::load_shot(const char *fname)
119 {
120 int xsz, ysz;
121 unsigned char *img = (unsigned char*)img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGB24);
122 if(!img) {
123 fprintf(stderr, "failed to open image: %s\n", fname);
124 return false;
125 }
127 int nslices = size;
128 int slice_sz = size * size * 3;
129 unsigned char *pal = img + xsz * (ysz - nslices) * 3;
131 for(int i=0; i<nslices; i++) {
132 memcpy(palette + i * slice_sz, pal, slice_sz);
133 pal += xsz * 3;
134 }
135 img_free_pixels(img);
137 glBindTexture(GL_TEXTURE_3D, tex);
138 glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, size, size, size, 0, GL_RGB,
139 GL_UNSIGNED_BYTE, palette);
141 return true;
142 }
144 unsigned int GradePalette::get_texture() const
145 {
146 return tex;
147 }