OSDN Git Service

first
[psychlops/cpp.git] / psychlops / platform / osx / psychlops_g_canvas_OSX.cpp
1 /*
2  *  psychlops_g_image_GL.h
3  *  Psychlops Standard Library (Universal)
4  *
5  *  Last Modified 2007/07/07 by Kenchi HOSOKAWA
6  *  (C) 2007 Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
7  */
8
9
10 #include <stdlib.h>
11 #include <Math.h>
12 #include <iostream>
13 #include <string>
14
15 #include <OpenGL/gl.h>
16 #include <OpenGL/glu.h>
17
18
19 #include "../../core/ApplicationInterfaces/psychlops_app_info.h"
20 #include "../../core/devices/psychlops_io_file.h"
21 #include "../../core/math/psychlops_math.h"
22 #include "../../core/graphic/psychlops_g_fundamental.h"
23 #include "../../core/graphic/psychlops_g_color.h"
24 #include "../../core/graphic/psychlops_g_module.h"
25 #include "../../core/graphic/psychlops_g_shape.h"
26 #include "../../core/graphic/psychlops_g_canvas.h"
27 #include "../../core/graphic/psychlops_g_image.h"
28
29 #include "psychlops_g_API_OSX.h"
30
31
32 namespace Psychlops {
33
34
35
36         void Canvas::cacheImageBody(Image &img) {
37                 APIImageCache *api_ = 0;
38                 int tex_width = 0, tex_height = 0;
39
40                 if(img.caches.count(this)==0) {
41                         int i;
42                         i=0;
43                         while(pow(2.0,++i)<img.width_) {}
44                         tex_width = pow(2.0,i);
45                         i=0;
46                         while(pow(2.0,++i)<img.height_) {}
47                         tex_height = pow(2.0,i);
48                 } else {
49                         api_ = img.caches[this].id;
50                         tex_width = api_->tex_width;
51                         tex_height = api_->tex_height;
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);
55
56                 if(img.caches.count(this)!=0) {
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);
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         }
165
166         void Canvas::drawImage(Image &img, const Rectangle &target_area)
167         {
168                 if(img.caches.count(this)==0) {
169                         img.cache(*this);
170                 }
171                 APIImageCache *api_ = img.caches[this].id;
172                 double tex_top = 1.0;
173                 double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;
174                 
175                 glColor4f(1.0,1.0,1.0,1.0);
176                 glEnable(GL_TEXTURE_2D);
177                 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
178                 glBegin(GL_QUADS);
179                 glTexCoord2d(0, tex_top);
180                 glVertex2f(target_area.left, target_area.top);
181                 glTexCoord2d((double)img.width_/api_->tex_width , tex_top);
182                 glVertex2f(target_area.right, target_area.top);
183                 glTexCoord2d((double)img.width_/api_->tex_width , tex_bottom);
184                 glVertex2f(target_area.right, target_area.bottom);
185                 glTexCoord2d(0 , tex_bottom);
186                 glVertex2f(target_area.left, target_area.bottom);
187                 
188                 glEnd();
189                 glDisable(GL_TEXTURE_2D);
190         }
191         
192         Canvas& Canvas::image(Image &img, const Rectangle &target_area, const Rectangle &source_rect)
193         {
194                 if(img.caches.count(this)==0) {
195                         img.cache(*this);
196                 }
197                 APIImageCache *api_ = img.caches[this].id;
198 //              double right = left + source_rect.getWidth();
199 //              double bottom = top + source_rect.getHeight();
200                 double tex_top = 1.0;
201                 double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;
202                 double tex_left = 0.0;
203                 double tex_right = (double)img.width_/api_->tex_width;
204                 double tex_height = tex_top - tex_bottom;
205                 double tex_width  = tex_right - tex_left;
206                 tex_left = tex_width * source_rect.getLeft() / (img.getWidth()-1.0);
207                 tex_top = 1.0 - tex_height * source_rect.getTop() / (img.getHeight()-1.0);
208                 tex_right = tex_width * source_rect.getRight() / (img.getWidth()-1.0);
209                 tex_bottom = 1.0 - tex_height * source_rect.getBottom() / (img.getHeight()-1.0);
210 //std::cout << "D   " << tex_left << " " << tex_top << " " << tex_right << " " << tex_bottom << std::endl;
211                 
212                 glColor4f(1.0,1.0,1.0,1.0);
213                 glEnable(GL_TEXTURE_2D);
214                 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
215                 glBegin(GL_QUADS);
216
217                 glTexCoord2d(tex_left, tex_top);
218 //              glVertex2f(left, top);
219                 glVertex2f(target_area.left, target_area.top);
220
221                 glTexCoord2d(tex_right, tex_top);
222 //              glVertex2f(right, top);
223                 glVertex2f(target_area.right+1, target_area.top);
224
225                 glTexCoord2d(tex_right , tex_bottom);
226 //              glVertex2f(right, bottom);
227                 glVertex2f(target_area.right+1, target_area.bottom+1);
228
229                 glTexCoord2d(tex_left , tex_bottom);
230 //              glVertex2f(left, bottom);
231                 glVertex2f(target_area.left, target_area.bottom+1);
232
233
234                 glEnd();
235                 glDisable(GL_TEXTURE_2D);
236                 return *this;
237         }
238
239         
240 /*
241         void Canvas::cacheImageBody(Image &img) {
242                 APIImageCache *api_ = 0;
243                 if(img.caches.count(this)!=0) {
244                         api_ = img.caches[this].id;
245                         glEnable(GL_TEXTURE_RECTANGLE_EXT);
246                         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, api_->VRAMoffset);
247                         glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, img.width_, img.height_, APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], img.getBitmapPtr());
248                         glDisable(GL_TEXTURE_RECTANGLE_EXT);
249                 } else {
250                         api_ = new APIImageCache;
251                         img.caches.insert(std::pair<DrawableWithCache*, ImageCache_>(this, ImageCache_(api_, false)));
252                         glEnable(GL_TEXTURE_RECTANGLE_EXT);
253                         glGenTextures(1, &api_->VRAMoffset);
254                         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, api_->VRAMoffset);
255                         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
256                         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
257                         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
258                         glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
259                         glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, Image::PixCompSize_[img.pixcomp_], img.width_, img.height_, 0, APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], img.getBitmapPtr());
260                         glDisable(GL_TEXTURE_RECTANGLE_EXT);
261                         //quickened_ = true;
262                         /*
263                         APIImageProperties::regist((int)Display::getWidth(), (int)Display::getHeight(), width_, height_, VRAMleft_, VRAMtop_);
264                         glDisable(GL_BLEND);
265                         glDrawBuffer(GL_AUX1);
266                         for(int y=0; y<height_; y++) {
267                                 for(int x=0; x<width_; x++) {
268                                         Display::pix(x+VRAMleft_, y+VRAMtop_, getPix(x, y));
269                                 }
270                         }
271                         glDrawBuffer(GL_BACK);
272                         glEnable(GL_BLEND);
273                         * /
274                 }
275                 glDrawBuffer(GL_AUX1);
276                 glColor4f(1.0,1.0,1.0,1.0);
277                 glEnable(GL_TEXTURE_RECTANGLE_EXT);
278                 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, api_->getTexIndex());
279                 glBegin(GL_QUADS);
280                         glTexCoord2d(0 , img.height_);
281                                 glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getTop());
282                         glTexCoord2d(img.width_ , img.height_);
283                                 glVertex2f(img.targetarea_.getRight()+1 , img.targetarea_.getTop());
284                         glTexCoord2d(img.width_ , 0);
285                                 glVertex2f(img.targetarea_.getRight()+1, img.targetarea_.getBottom()+1);
286                         glTexCoord2d(0, 0);
287                                 glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getBottom()+1);
288                 glEnd();
289                 glDisable(GL_TEXTURE_RECTANGLE_EXT);
290                 glDrawBuffer(GL_BACK);
291         }
292
293         void Canvas::uncacheImageBody(Image &img) {
294                 APIImageCache *api_ = 0;
295                 if(img.caches.count(this)!=0) {
296                         api_ = img.caches[this].id;                     
297                         if(api_->VRAMoffset!=0) glDeleteTextures(1, &(api_->VRAMoffset));
298                         api_->VRAMoffset = 0;
299                         img.caches.erase(this);
300                 }
301         }
302
303         void Canvas::drawImage(const Image &img, Point lt, Point rt, Point rb, Point lb) {
304                 if(img.caches.count(this)!=0) {
305                         glColor4f(1.0,1.0,1.0,1.0);
306                         glEnable(GL_TEXTURE_RECTANGLE_EXT);
307                         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, img.caches[this].id->getTexIndex());
308                         glBegin(GL_QUADS);
309                         glTexCoord2d(0 , img.height_);
310                         glVertex2f(lt.x, lt.y);
311                         glTexCoord2d(img.width_ , img.height_);
312                         glVertex2f(rt.x , rt.y);
313                         glTexCoord2d(img.width_ , 0);
314                         glVertex2f(rb.x, rb.y);
315                         glTexCoord2d(0, 0);
316                         glVertex2f(lb.x, lb.y);
317                         glEnd();
318                         glDisable(GL_TEXTURE_RECTANGLE_EXT);
319                 }
320         }
321         void Canvas::drawImage(const Image &img, const double left, const double top) {
322                 if(img.caches.count(this)!=0) {
323                         //                      glReadBuffer(GL_AUX1);
324 //                      glDrawBuffer(GL_BACK);
325 //                      glCopyPixels(img.VRAMleft_, (int)getHeight()-img.VRAMtop_-img.height_, img.width_, img.height_, GL_COLOR);
326                         glColor4f(1.0,1.0,1.0,1.0);
327 //                      glEnable(GL_BLEND);
328                         glEnable(GL_TEXTURE_RECTANGLE_EXT);
329                         glBindTexture(GL_TEXTURE_RECTANGLE_EXT, img.caches[this].id->getTexIndex());
330                         glBegin(GL_QUADS);
331                                 glTexCoord2d(0 , img.height_);
332                                         glVertex2f(left, top);
333                                 glTexCoord2d(img.width_ , img.height_);
334                                         glVertex2f(left+img.targetarea_.getWidth() , top);
335                                 glTexCoord2d(img.width_ , 0);
336                                         glVertex2f(left+img.targetarea_.getWidth(), top+img.targetarea_.getHeight());
337                                 glTexCoord2d(0, 0);
338                                         glVertex2f(left , top+img.targetarea_.getHeight());
339                         glEnd();
340                         glDisable(GL_TEXTURE_RECTANGLE_EXT);
341                 } else {
342                         glRasterPos2d(left,img.height_+top);
343                         if( img.pixcomp_==Image::RGBA ) {
344                                 glPushAttrib(GL_ALL_ATTRIB_BITS);
345                                 glEnable(GL_BLEND);
346                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
347                                 glDrawPixels((GLsizei)img.getWidth(), (GLsizei)img.getHeight(), APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], img.getBitmapPtr());
348                                 glDisable(GL_BLEND);
349                                 glPopAttrib();
350                         } else {
351                                 glDrawPixels((GLsizei)img.getWidth(), (GLsizei)img.getHeight(), APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], img.getBitmapPtr());
352                         }
353                 }
354         }
355 */
356
357
358         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) {
359                 double x_begin_shift;
360                 switch(horiz_align) {
361                 case Letters::TEXT_ALIGN_RIGHT:
362                         x_begin_shift = -letters.width_;
363                         break;
364                 case Letters::TEXT_ALIGN_CENTER:
365                         x_begin_shift = -letters.width_/2;
366                         break;
367                 case Letters::TEXT_ALIGN_LEFT:
368                 default:
369                         x_begin_shift = 0.0;
370                         break;
371                 }
372                 api->drawLetters(letters, x+x_begin_shift, y, col, horiz_align, vertical_align, max_width);
373                 return 1;
374         }
375
376
377 }       /*      <- namespace Psycholops         */
378