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