OSDN Git Service

616531d004c843fb5fc0b1b26e92d700fe5b0d04
[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);\r
73                         GLenum vramFormat = Image::PixCompSize_[img.pixcomp_];\r
74                         /*\r
75                         if(img.pixprec_==Image::FLOAT) {\r
76                                 switch(img.pixcomp_) {\r
77                                 case Image::GRAY:\r
78                                         vramFormat = GL_R16UI;\r
79                                         break;\r
80                                 case Image::RGB:\r
81                                         vramFormat = GL_RGB16UI;\r
82                                         break;\r
83                                 case Image::RGBA:\r
84                                         vramFormat = GL_RGBA16UI;\r
85                                         break;\r
86                                 }\r
87                         }\r
88                         */
89                         glTexImage2D(GL_TEXTURE_2D, 0, vramFormat, api_->tex_width, api_->tex_height, 0, APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], tmp->getBitmapPtr());
90                         glDisable(GL_TEXTURE_2D);
91
92 //                              APIImageProperties::regist((int)Display::getWidth(), (int)Display::getHeight(), width_, height_, VRAMleft_, VRAMtop_);
93 //                              glDisable(GL_BLEND);
94 //                              glDrawBuffer(GL_AUX1);
95 //                              for(int y=0; y<height_; y++) {
96 //                                      for(int x=0; x<width_; x++) {
97 //                                              Display::pix(x+VRAMleft_, y+VRAMtop_, getPix(x, y));
98 //                                      }
99 //                              }
100 //                              glDrawBuffer(GL_BACK);
101 //                              glEnable(GL_BLEND);
102
103                 }
104                 glDrawBuffer(GL_AUX1);
105                 glColor4f(1.0,1.0,1.0,1.0);
106                 glEnable(GL_TEXTURE_2D);
107                 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
108                 glBegin(GL_QUADS);
109                         glTexCoord2d(0 , img.height_);
110                                 glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getTop());
111                         glTexCoord2d(img.width_ , img.height_);
112                                 glVertex2f(img.targetarea_.getRight()+1, img.targetarea_.getTop());
113                         glTexCoord2d(img.width_ , 0);
114                                 glVertex2f(img.targetarea_.getRight()+1, img.targetarea_.getBottom()+1);
115                         glTexCoord2d(0, 0);
116                                 glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getBottom()+1);
117                 glEnd();
118                 glDisable(GL_TEXTURE_2D);
119                 glDrawBuffer(GL_BACK);
120                 delete tmp;
121         }
122
123         void Canvas::uncacheImageBody(Image &img) {
124                 APIImageCache *api_ = 0;
125                 if(img.caches.count(this)!=0) {
126                         api_ = img.caches[this].id;
127                         if(api_->VRAMoffset!=0) glDeleteTextures(1, &(api_->VRAMoffset));
128                         api_->VRAMoffset = 0;
129                         img.caches.erase(this);
130                 }
131         }
132
133
134         void Canvas::drawImage(const Image &img, const double left, const double top) {
135                 //int left = Math::round(left__);
136                 //int top = Math::round(top__);
137
138                 if(img.caches.count(this)!=0) {
139                         APIImageCache *api_ = img.caches[this].id;
140                         double tex_top = 1.0;
141                         double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;
142
143                         glColor4f(1.0,1.0,1.0,1.0);
144                         glEnable(GL_TEXTURE_2D);
145                         glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
146                         glBegin(GL_QUADS);
147 /*                              glTexCoord2d(0 , img.height_/img.api->tex_height);
148                                         glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getTop());
149                                 glTexCoord2d(img.width_/img.api->tex_width , img.height_/img.api->tex_height);
150                                         glVertex2f(img.targetarea_.getRight()+1 , img.targetarea_.getTop());
151                                 glTexCoord2d(img.width_/img.api->tex_width , 0);
152                                         glVertex2f(img.targetarea_.getRight()+1, img.targetarea_.getBottom()+1);
153                                 glTexCoord2d(0, 0);
154                                         glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getBottom()+1);
155 */
156                                 glTexCoord2d(0, tex_top);
157                                         glVertex2f(left, top);
158                                 glTexCoord2d((double)img.width_/api_->tex_width , tex_top);
159                                         glVertex2f(left+img.targetarea_.getWidth(), top);
160                                 glTexCoord2d((double)img.width_/api_->tex_width , tex_bottom);
161                                         glVertex2f(left+img.targetarea_.getWidth(), top+img.targetarea_.getHeight());
162                                 glTexCoord2d(0 , tex_bottom);
163                                         glVertex2f(left, top+img.targetarea_.getHeight());
164
165                         glEnd();
166                         glDisable(GL_TEXTURE_2D);
167                 } else {
168                         glRasterPos2d(left,img.height_+top);
169                         if( img.pixcomp_==Image::RGBA ) {
170                                 glPushAttrib(GL_ALL_ATTRIB_BITS);
171                                 glEnable(GL_BLEND);
172                                 glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
173                                 glDrawPixels((GLsizei)img.getWidth(), (GLsizei)img.getHeight(), APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], img.getBitmapPtr());
174                                 glDisable(GL_BLEND);
175                                 glPopAttrib();
176                         } else {
177                                 glDrawPixels((GLsizei)img.getWidth(), (GLsizei)img.getHeight(), APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], img.getBitmapPtr());
178                         }
179                 }
180         }\r
181 \r
182         void Canvas::drawImage(Image &img, const Rectangle &target_area)\r
183         {\r
184                 if(img.caches.count(this)==0) {\r
185                         img.cache(*this);\r
186                 }\r
187                 APIImageCache *api_ = img.caches[this].id;\r
188                 double tex_top = 1.0;\r
189                 double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;\r
190 \r
191                 glColor4f(1.0,1.0,1.0,1.0);\r
192                 glEnable(GL_TEXTURE_2D);\r
193                 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());\r
194                 glBegin(GL_QUADS);\r
195                         glTexCoord2d(0, tex_top);\r
196                                 glVertex2f(target_area.left, target_area.top);\r
197                         glTexCoord2d((double)img.width_/api_->tex_width , tex_top);\r
198                                 glVertex2f(target_area.right, target_area.top);\r
199                         glTexCoord2d((double)img.width_/api_->tex_width , tex_bottom);\r
200                                 glVertex2f(target_area.right, target_area.bottom);\r
201                         glTexCoord2d(0 , tex_bottom);\r
202                                 glVertex2f(target_area.left, target_area.bottom);\r
203 \r
204                 glEnd();\r
205                 glDisable(GL_TEXTURE_2D);\r
206         }
207 \r
208         Canvas& Canvas::image(Image &img, const Rectangle &target_area, const Rectangle &source_rect)\r
209         {\r
210                 if(img.caches.count(this)==0) {\r
211                         img.cache(*this);\r
212                 }\r
213                 APIImageCache *api_ = img.caches[this].id;\r
214 //              double right = left + source_rect.getWidth();\r
215 //              double bottom = top + source_rect.getHeight();\r
216                 double tex_top = 1.0;\r
217                 double tex_bottom = ((double)api_->tex_height-img.height_)/api_->tex_height;\r
218                 double tex_left = 0.0;\r
219                 double tex_right = (double)img.width_/api_->tex_width;\r
220                 double tex_height = tex_top - tex_bottom;\r
221                 double tex_width  = tex_right - tex_left;\r
222                 tex_left = tex_width * source_rect.getLeft() / (img.getWidth()-1.0);\r
223                 tex_top = 1.0 - tex_height * source_rect.getTop() / (img.getHeight()-1.0);\r
224                 tex_right = tex_width * source_rect.getRight() / (img.getWidth()-1.0);\r
225                 tex_bottom = 1.0 - tex_height * source_rect.getBottom() / (img.getHeight()-1.0);\r
226 //std::cout << "D   " << tex_left << " " << tex_top << " " << tex_right << " " << tex_bottom << std::endl;\r
227 \r
228                 glColor4f(1.0,1.0,1.0,1.0);\r
229                 glEnable(GL_TEXTURE_2D);\r
230                 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());\r
231                 glBegin(GL_QUADS);\r
232 \r
233                 glTexCoord2d(tex_left, tex_top);\r
234 //              glVertex2f(left, top);\r
235                 glVertex2f(target_area.left, target_area.top);\r
236 \r
237                 glTexCoord2d(tex_right, tex_top);\r
238 //              glVertex2f(right, top);\r
239                 glVertex2f(target_area.right+1, target_area.top);\r
240 \r
241                 glTexCoord2d(tex_right , tex_bottom);\r
242 //              glVertex2f(right, bottom);\r
243                 glVertex2f(target_area.right+1, target_area.bottom+1);\r
244 \r
245                 glTexCoord2d(tex_left , tex_bottom);\r
246 //              glVertex2f(left, bottom);\r
247                 glVertex2f(target_area.left, target_area.bottom+1);\r
248 \r
249 \r
250                 glEnd();\r
251                 glDisable(GL_TEXTURE_2D);\r
252                 return *this;\r
253         }\r
254 \r
255
256         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) {
257 /*              double x_begin_shift;
258                 switch(horiz_align) {
259                 case Letters::TEXT_ALIGN_RIGHT:
260                         x_begin_shift = -letters.width_;
261                         break;
262                 case Letters::TEXT_ALIGN_CENTER:
263                         x_begin_shift = -letters.width_/2;
264                         break;
265                 case Letters::TEXT_ALIGN_LEFT:
266                 default:
267                         x_begin_shift = 0.0;
268                         break;
269                 }
270                 api->drawLetters(letters, x+x_begin_shift, y, col.Red, col.Green, col.Blue, col.Alpha, horiz_align, vertical_align, max_width);\r
271 */
272                 api->draw(letters, x, y, col.Red, col.Green, col.Blue, col.Alpha, horiz_align, vertical_align, max_width);\r
273                 return 1;
274         }
275
276
277 }       /*      <- namespace Psycholops         */
278