OSDN Git Service

add JPG and TIFF Support via OpenCV for Image::load and Image::save
[psychlops/cpp.git] / psychlops / platform / win32gl / psychlops_g_canvas_win32gl.cpp
1 /*
2  *  psychlops_g_canvas_Win32_GL.cpp
3  *  Psychlops Standard Library (Universal)
4  *
5  *  Last Modified 2007/07/07 by Kenchi HOSOKAWA
6  *  (C) 2006 Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
7  */
8
9 #include <stdlib.h>
10 #include <Math.h>
11 #include <string>
12
13
14 #include <windows.h>
15 #include <gl/gl.h>
16
17 #include "../../core/ApplicationInterfaces/psychlops_app_info.h"
18 #include "../../core/devices/psychlops_io_hid.h"
19 #include "../../core/devices/psychlops_io_file.h"
20 #include "../../core/math/psychlops_math.h"
21 #include "../../core/graphic/psychlops_g_fundamental.h"
22 #include "../../core/graphic/psychlops_g_color.h"
23 #include "../../core/graphic/psychlops_g_shape.h"
24 #include "../../core/graphic/psychlops_g_canvas.h"
25 #include "../../core/graphic/psychlops_g_image.h"
26
27 #define PSYCHLOPS_WINDOW_API_PLATFORM
28 #include "../psychlops_platform_selector.h"
29
30
31 namespace Psychlops {
32
33
34
35         void Canvas::cacheImageBody(Image &img) {
36                 APIImageCache *api_ = 0;
37                 int tex_width = 0, tex_height = 0;
38
39                 if(img.caches.count(this)==0) {
40                         int i;
41                         i=0;
42                         while(pow(2.0,++i)<img.width_) {}
43                         tex_width = pow(2.0,i);
44                         i=0;
45                         while(pow(2.0,++i)<img.height_) {}
46                         tex_height = pow(2.0,i);
47                 } else {
48                         api_ = img.caches[this].id;
49                         tex_width = api_->tex_width;
50                         tex_height = api_->tex_height;
51                 }\r
52
53                 Image *tmp = new Image(tex_width, tex_height, img.pixcomp_, img.pixprec_);
54                 for(int y=0; y<img.height_; y++) Image::line_direct_copy_(img, *tmp, y);\r
55
56                 if(img.caches.count(this)!=0) {\r
57                         glEnable(GL_TEXTURE_2D);
58                         glBindTexture(GL_TEXTURE_2D, api_->VRAMoffset);
59                         glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, api_->tex_width, api_->tex_height, APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], tmp->getBitmapPtr());
60                         glDisable(GL_TEXTURE_2D);\r
61                 } else {
62                         api_ = new APIImageCache;
63                         img.caches.insert(std::pair<DrawableWithCache*, ImageCache_>(this, ImageCache_(api_, false)));
64                         api_->tex_width = tex_width;
65                         api_->tex_height = tex_height;
66                         glEnable(GL_TEXTURE_2D);
67                         glGenTextures(1, &api_->VRAMoffset);
68                         glBindTexture(GL_TEXTURE_2D, api_->VRAMoffset);
69                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
70                         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
71 //                              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
72 //                              glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
73                         glTexImage2D(GL_TEXTURE_2D, 0, Image::PixCompSize_[img.pixcomp_], api_->tex_width, api_->tex_height, 0, APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], tmp->getBitmapPtr());
74                         glDisable(GL_TEXTURE_2D);
75
76 //                              APIImageProperties::regist((int)Display::getWidth(), (int)Display::getHeight(), width_, height_, VRAMleft_, VRAMtop_);
77 //                              glDisable(GL_BLEND);
78 //                              glDrawBuffer(GL_AUX1);
79 //                              for(int y=0; y<height_; y++) {
80 //                                      for(int x=0; x<width_; x++) {
81 //                                              Display::pix(x+VRAMleft_, y+VRAMtop_, getPix(x, y));
82 //                                      }
83 //                              }
84 //                              glDrawBuffer(GL_BACK);
85 //                              glEnable(GL_BLEND);
86
87                 }
88                 glDrawBuffer(GL_AUX1);
89                 glColor4f(1.0,1.0,1.0,1.0);
90                 glEnable(GL_TEXTURE_2D);
91                 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
92                 glBegin(GL_QUADS);
93                         glTexCoord2d(0 , img.height_);
94                                 glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getTop());
95                         glTexCoord2d(img.width_ , img.height_);
96                                 glVertex2f(img.targetarea_.getRight()+1, img.targetarea_.getTop());
97                         glTexCoord2d(img.width_ , 0);
98                                 glVertex2f(img.targetarea_.getRight()+1, img.targetarea_.getBottom()+1);
99                         glTexCoord2d(0, 0);
100                                 glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getBottom()+1);
101                 glEnd();
102                 glDisable(GL_TEXTURE_2D);
103                 glDrawBuffer(GL_BACK);
104                 delete tmp;
105         }
106
107         void Canvas::uncacheImageBody(Image &img) {
108                 APIImageCache *api_ = 0;
109                 if(img.caches.count(this)!=0) {
110                         api_ = img.caches[this].id;
111                         if(api_->VRAMoffset!=0) glDeleteTextures(1, &(api_->VRAMoffset));
112                         api_->VRAMoffset = 0;
113                         img.caches.erase(this);
114                 }
115         }
116
117
118         void Canvas::drawImage(const Image &img, const double left, const double top) {
119                 //int left = Math::round(left__);
120                 //int top = Math::round(top__);
121
122                 if(img.caches.count(this)!=0) {
123                         APIImageCache *api_ = img.caches[this].id;
124                         double tex_top = 1.0;
125                         double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;
126
127                         glColor4f(1.0,1.0,1.0,1.0);
128                         glEnable(GL_TEXTURE_2D);
129                         glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
130                         glBegin(GL_QUADS);
131 /*                              glTexCoord2d(0 , img.height_/img.api->tex_height);
132                                         glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getTop());
133                                 glTexCoord2d(img.width_/img.api->tex_width , img.height_/img.api->tex_height);
134                                         glVertex2f(img.targetarea_.getRight()+1 , img.targetarea_.getTop());
135                                 glTexCoord2d(img.width_/img.api->tex_width , 0);
136                                         glVertex2f(img.targetarea_.getRight()+1, img.targetarea_.getBottom()+1);
137                                 glTexCoord2d(0, 0);
138                                         glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getBottom()+1);
139 */
140                                 glTexCoord2d(0, tex_top);
141                                         glVertex2f(left, top);
142                                 glTexCoord2d((double)img.width_/api_->tex_width , tex_top);
143                                         glVertex2f(left+img.targetarea_.getWidth(), top);
144                                 glTexCoord2d((double)img.width_/api_->tex_width , tex_bottom);
145                                         glVertex2f(left+img.targetarea_.getWidth(), top+img.targetarea_.getHeight());
146                                 glTexCoord2d(0 , tex_bottom);
147                                         glVertex2f(left, top+img.targetarea_.getHeight());
148
149                         glEnd();
150                         glDisable(GL_TEXTURE_2D);
151                 } else {
152                         glRasterPos2d(left,img.height_+top);
153                         if( img.pixcomp_==Image::RGBA ) {
154                                 glPushAttrib(GL_ALL_ATTRIB_BITS);
155                                 glEnable(GL_BLEND);
156                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
157                                 glDrawPixels((GLsizei)img.getWidth(), (GLsizei)img.getHeight(), APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], img.getBitmapPtr());
158                                 glDisable(GL_BLEND);
159                                 glPopAttrib();
160                         } else {
161                                 glDrawPixels((GLsizei)img.getWidth(), (GLsizei)img.getHeight(), APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], img.getBitmapPtr());
162                         }
163                 }
164         }\r
165 \r
166         void Canvas::drawImage(Image &img, const Rectangle &target_area)\r
167         {\r
168                 if(img.caches.count(this)==0) {\r
169                         img.cache(*this);\r
170                 }\r
171                 APIImageCache *api_ = img.caches[this].id;\r
172                 double tex_top = 1.0;\r
173                 double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;\r
174 \r
175                 glColor4f(1.0,1.0,1.0,1.0);\r
176                 glEnable(GL_TEXTURE_2D);\r
177                 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());\r
178                 glBegin(GL_QUADS);\r
179                         glTexCoord2d(0, tex_top);\r
180                                 glVertex2f(target_area.left, target_area.top);\r
181                         glTexCoord2d((double)img.width_/api_->tex_width , tex_top);\r
182                                 glVertex2f(target_area.right, target_area.top);\r
183                         glTexCoord2d((double)img.width_/api_->tex_width , tex_bottom);\r
184                                 glVertex2f(target_area.right, target_area.bottom);\r
185                         glTexCoord2d(0 , tex_bottom);\r
186                                 glVertex2f(target_area.left, target_area.bottom);\r
187 \r
188                 glEnd();\r
189                 glDisable(GL_TEXTURE_2D);\r
190         }
191 \r
192         Canvas& Canvas::image(Image &img, const Rectangle &target_area, const Rectangle &source_rect)\r
193         {\r
194                 if(img.caches.count(this)==0) {\r
195                         img.cache(*this);\r
196                 }\r
197                 APIImageCache *api_ = img.caches[this].id;\r
198 //              double right = left + source_rect.getWidth();\r
199 //              double bottom = top + source_rect.getHeight();\r
200                 double tex_top = 1.0;\r
201                 double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;\r
202                 double tex_left = 0.0;\r
203                 double tex_right = (double)img.width_/api_->tex_width;\r
204                 double tex_height = tex_top - tex_bottom;\r
205                 double tex_width  = tex_right - tex_left;\r
206                 tex_left = tex_width * source_rect.getLeft() / (img.getWidth()-1.0);\r
207                 tex_top = 1.0 - tex_height * source_rect.getTop() / (img.getHeight()-1.0);\r
208                 tex_right = tex_width * source_rect.getRight() / (img.getWidth()-1.0);\r
209                 tex_bottom = 1.0 - tex_height * source_rect.getBottom() / (img.getHeight()-1.0);\r
210 //std::cout << "D   " << tex_left << " " << tex_top << " " << tex_right << " " << tex_bottom << std::endl;\r
211 \r
212                 glColor4f(1.0,1.0,1.0,1.0);\r
213                 glEnable(GL_TEXTURE_2D);\r
214                 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());\r
215                 glBegin(GL_QUADS);\r
216 \r
217                 glTexCoord2d(tex_left, tex_top);\r
218 //              glVertex2f(left, top);\r
219                 glVertex2f(target_area.left, target_area.top);\r
220 \r
221                 glTexCoord2d(tex_right, tex_top);\r
222 //              glVertex2f(right, top);\r
223                 glVertex2f(target_area.right+1, target_area.top);\r
224 \r
225                 glTexCoord2d(tex_right , tex_bottom);\r
226 //              glVertex2f(right, bottom);\r
227                 glVertex2f(target_area.right+1, target_area.bottom+1);\r
228 \r
229                 glTexCoord2d(tex_left , tex_bottom);\r
230 //              glVertex2f(left, bottom);\r
231                 glVertex2f(target_area.left, target_area.bottom+1);\r
232 \r
233 \r
234                 glEnd();\r
235                 glDisable(GL_TEXTURE_2D);\r
236                 return *this;\r
237         }\r
238 \r
239
240         int Canvas::msg(Letters &letters, const double x, const double y, const Color &col, const int horiz_align, const int vertical_align, const double max_width) {
241 /*              double x_begin_shift;
242                 switch(horiz_align) {
243                 case Letters::TEXT_ALIGN_RIGHT:
244                         x_begin_shift = -letters.width_;
245                         break;
246                 case Letters::TEXT_ALIGN_CENTER:
247                         x_begin_shift = -letters.width_/2;
248                         break;
249                 case Letters::TEXT_ALIGN_LEFT:
250                 default:
251                         x_begin_shift = 0.0;
252                         break;
253                 }
254                 api->drawLetters(letters, x+x_begin_shift, y, col.Red, col.Green, col.Blue, col.Alpha, horiz_align, vertical_align, max_width);\r
255 */
256                 api->draw(letters, x, y, col.Red, col.Green, col.Blue, col.Alpha, horiz_align, vertical_align, max_width);\r
257                 return 1;
258         }
259
260
261 }       /*      <- namespace Psycholops         */
262