2 * psychlops_g_image_GL.h
3 * Psychlops Standard Library (Universal)
5 * Last Modified 2007/07/07 by Kenchi HOSOKAWA
6 * (C) 2007 Kenchi HOSOKAWA, Kazushi MARUYA and Takao SATO
15 #include <OpenGL/gl.h>
16 #include <OpenGL/glu.h>
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"
29 #include "psychlops_g_API_OSX.h"
36 void Canvas::cacheImageBody(Image &img) {
37 APIImageCache *api_ = 0;
38 int tex_width = 0, tex_height = 0;
40 if(img.caches.count(this)==0) {
43 while(pow(2.0,++i)<img.width_) {}
44 tex_width = pow(2.0,i);
46 while(pow(2.0,++i)<img.height_) {}
47 tex_height = pow(2.0,i);
49 api_ = img.caches[this].id;
50 tex_width = api_->tex_width;
51 tex_height = api_->tex_height;
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);
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);
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);
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));
84 // glDrawBuffer(GL_BACK);
85 // glEnable(GL_BLEND);
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());
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);
100 glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getBottom()+1);
102 glDisable(GL_TEXTURE_2D);
103 glDrawBuffer(GL_BACK);
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);
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__);
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;
127 glColor4f(1.0,1.0,1.0,1.0);
128 glEnable(GL_TEXTURE_2D);
129 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
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);
138 glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getBottom()+1);
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());
150 glDisable(GL_TEXTURE_2D);
152 glRasterPos2d(left,img.height_+top);
153 if( img.pixcomp_==Image::RGBA ) {
154 glPushAttrib(GL_ALL_ATTRIB_BITS);
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());
161 glDrawPixels((GLsizei)img.getWidth(), (GLsizei)img.getHeight(), APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], img.getBitmapPtr());
166 void Canvas::drawImage(Image &img, const Rectangle &target_area)
168 if(img.caches.count(this)==0) {
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;
175 glColor4f(1.0,1.0,1.0,1.0);
176 glEnable(GL_TEXTURE_2D);
177 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
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);
189 glDisable(GL_TEXTURE_2D);
192 Canvas& Canvas::image(Image &img, const Rectangle &target_area, const Rectangle &source_rect)
194 if(img.caches.count(this)==0) {
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;
212 glColor4f(1.0,1.0,1.0,1.0);
213 glEnable(GL_TEXTURE_2D);
214 glBindTexture(GL_TEXTURE_2D, api_->getTexIndex());
217 glTexCoord2d(tex_left, tex_top);
218 // glVertex2f(left, top);
219 glVertex2f(target_area.left, target_area.top);
221 glTexCoord2d(tex_right, tex_top);
222 // glVertex2f(right, top);
223 glVertex2f(target_area.right+1, target_area.top);
225 glTexCoord2d(tex_right , tex_bottom);
226 // glVertex2f(right, bottom);
227 glVertex2f(target_area.right+1, target_area.bottom+1);
229 glTexCoord2d(tex_left , tex_bottom);
230 // glVertex2f(left, bottom);
231 glVertex2f(target_area.left, target_area.bottom+1);
235 glDisable(GL_TEXTURE_2D);
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);
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);
263 APIImageProperties::regist((int)Display::getWidth(), (int)Display::getHeight(), width_, height_, VRAMleft_, VRAMtop_);
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));
271 glDrawBuffer(GL_BACK);
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());
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);
287 glVertex2f(img.targetarea_.getLeft() , img.targetarea_.getBottom()+1);
289 glDisable(GL_TEXTURE_RECTANGLE_EXT);
290 glDrawBuffer(GL_BACK);
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);
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());
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);
316 glVertex2f(lb.x, lb.y);
318 glDisable(GL_TEXTURE_RECTANGLE_EXT);
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());
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());
338 glVertex2f(left , top+img.targetarea_.getHeight());
340 glDisable(GL_TEXTURE_RECTANGLE_EXT);
342 glRasterPos2d(left,img.height_+top);
343 if( img.pixcomp_==Image::RGBA ) {
344 glPushAttrib(GL_ALL_ATTRIB_BITS);
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());
351 glDrawPixels((GLsizei)img.getWidth(), (GLsizei)img.getHeight(), APIImageProperties::PixCompGL_[img.pixcomp_], APIImageProperties::PixPrecGL_[img.pixprec_], img.getBitmapPtr());
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_;
364 case Letters::TEXT_ALIGN_CENTER:
365 x_begin_shift = -letters.width_/2;
367 case Letters::TEXT_ALIGN_LEFT:
372 api->drawLetters(letters, x+x_begin_shift, y, col, horiz_align, vertical_align, max_width);
377 } /* <- namespace Psycholops */