00001
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005
00006
00007
00008
00009 #include "vgui_section_render.h"
00010
00011 #include <vcl_cmath.h>
00012 #include <vcl_cassert.h>
00013 #include <vcl_climits.h>
00014
00015 #include <vgui/internals/vgui_rasterpos.h>
00016 #include <vgui/internals/vgui_accelerate.h>
00017
00018 static inline float fsm_max(float x, float y) { return x>y ? x : y; }
00019 static inline float fsm_min(float x, float y) { return x<y ? x : y; }
00020
00021
00022 #if 0
00023 # include <vcl_cstdio.h>
00024 # define fsm_debug vcl_printf
00025 #else
00026 static inline void fsm_debug(char const *, ...) { }
00027 #endif
00028 static bool clamped_viewport(float x0, float y0, float x1, float y1,
00029 unsigned& i0, unsigned& j0,
00030 unsigned& ni, unsigned& nj,
00031 float& zoomx, float& zoomy)
00032 {
00033
00034 double Pt[4][4], Mt[4][4];
00035 glGetDoublev(GL_PROJECTION_MATRIX, &Pt[0][0]);
00036 glGetDoublev(GL_MODELVIEW_MATRIX, &Mt[0][0]);
00037
00038
00039
00040
00041
00042
00043
00044
00045 double T[4][4];
00046 for (unsigned i=0; i<4; ++i) {
00047 for (unsigned j=0; j<4; ++j) {
00048 T[i][j] = 0;
00049 for (unsigned k=0; k<4; ++k)
00050 T[i][j] += Pt[k][i] * Mt[j][k];
00051 }
00052 }
00053 if (!T[0][0]|| T[0][1] || T[0][2] ||
00054 T[1][0] ||!T[1][1] || T[1][2] ||
00055 T[2][0] || T[2][1] ||!T[2][2] ||
00056 T[3][0] || T[3][1] || T[3][2] || !T[3][3])
00057 return false;
00058
00059
00060
00061
00062 float a = float(T[0][0]/T[3][3]), b = float(T[1][1]/T[3][3]);
00063 float u = float(T[0][3]/T[3][3]), v = float(T[1][3]/T[3][3]);
00064
00065
00066 GLint vp[4];
00067 glGetIntegerv(GL_VIEWPORT, vp);
00068
00069
00070 int vp_w = vp[2];
00071 int vp_h = vp[3];
00072 if (vp_w <= 0 || vp_h <= 0)
00073 return true;
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 zoomx = a*vp_w/2;
00084 zoomy = b*vp_h/2;
00085
00086
00087
00088
00089
00090
00091
00092 if (a>0) {
00093
00094 x0 = fsm_max(x0, (-1-u)/a);
00095 x1 = fsm_min(x1, (+1-u)/a);
00096 }
00097 else {
00098
00099 x0 = fsm_max(x0, (+1-u)/a);
00100 x1 = fsm_min(x1, (-1-u)/a);
00101 }
00102 if (b>0) {
00103
00104 y0 = fsm_max(y0, (-1-v)/b);
00105 y1 = fsm_min(y1, (+1-v)/b);
00106 }
00107 else {
00108
00109 y0 = fsm_max(y0, (+1-v)/b);
00110 y1 = fsm_min(y1, (-1-v)/b);
00111 }
00112 if (x0 > x1 || y0 > y1) {
00113 fsm_debug("nothing to render\n");
00114 return true;
00115 }
00116
00117
00118
00119
00120
00121
00122
00123
00124 int i_x0 = int(vcl_floor(x0)), i_y0 = int(vcl_floor(y0));
00125 int i_x1 = int(vcl_ceil (x1)), i_y1 = int(vcl_ceil (y1));
00126
00127 vgui_rasterpos2i( i_x0, i_y0 );
00128
00129 i0 = static_cast<unsigned>(i_x0); ni = static_cast<unsigned>(i_x1-i_x0);
00130 j0 = static_cast<unsigned>(i_y0); nj = static_cast<unsigned>(i_y1-i_y0);
00131 return true;
00132 }
00133
00134 bool pixel_view(unsigned& i0, unsigned& ni, unsigned& j0, unsigned& nj,
00135 float& zoomx, float& zoomy)
00136 {
00137 float x0 = i0, x1 = ni, y0 = j0, y1 = nj;
00138 return clamped_viewport(x0, y0, x1, y1, i0, j0, ni, nj, zoomx, zoomy);
00139 }
00140
00141 static void GL_setup(GLenum format, GLenum type , bool hardware_map,
00142 GLint& alignment, GLint& row_length, GLint& skip_pixels,
00143 GLint& skip_rows, GLint& table_size, GLboolean& map_color,
00144 vbl_array_1d<float>* fLmap, vbl_array_1d<float>* fRmap,
00145 vbl_array_1d<float>* fGmap, vbl_array_1d<float>* fBmap,
00146 vbl_array_1d<float>* fAmap)
00147 {
00148 glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
00149 glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
00150 glGetIntegerv(GL_UNPACK_SKIP_PIXELS, &skip_pixels);
00151 glGetIntegerv(GL_UNPACK_SKIP_ROWS, &skip_rows);
00152 glGetIntegerv(GL_MAX_PIXEL_MAP_TABLE, &table_size);
00153 glGetBooleanv(GL_MAP_COLOR, &map_color);
00154
00155
00156 if (hardware_map&&type == GL_UNSIGNED_BYTE&&table_size>=(UCHAR_MAX+1))
00157 {
00158 if (format == GL_LUMINANCE)
00159 {
00160 glPixelTransferi(GL_MAP_COLOR, GL_TRUE);
00161 float* tfLmap = fLmap->begin();
00162 glPixelMapfv(GL_PIXEL_MAP_R_TO_R, UCHAR_MAX, tfLmap);
00163 glPixelMapfv(GL_PIXEL_MAP_G_TO_G, UCHAR_MAX, tfLmap);
00164 glPixelMapfv(GL_PIXEL_MAP_B_TO_B, UCHAR_MAX, tfLmap);
00165 }
00166 else if (format == GL_RGB)
00167 {
00168 glPixelTransferi(GL_MAP_COLOR, GL_TRUE);
00169 float* tfRmap = fRmap->begin();
00170 float* tfGmap = fGmap->begin();
00171 float* tfBmap = fBmap->begin();
00172 glPixelMapfv(GL_PIXEL_MAP_R_TO_R, UCHAR_MAX, tfRmap);
00173 glPixelMapfv(GL_PIXEL_MAP_G_TO_G, UCHAR_MAX, tfGmap);
00174 glPixelMapfv(GL_PIXEL_MAP_B_TO_B, UCHAR_MAX, tfBmap);
00175 }
00176 else if (format == GL_RGBA)
00177 {
00178 glPixelTransferi(GL_MAP_COLOR, GL_TRUE);
00179 float* tfRmap = fRmap->begin();
00180 float* tfGmap = fGmap->begin();
00181 float* tfBmap = fBmap->begin();
00182 float* tfAmap = fAmap->begin();
00183 glPixelMapfv(GL_PIXEL_MAP_R_TO_R, UCHAR_MAX, tfRmap);
00184 glPixelMapfv(GL_PIXEL_MAP_G_TO_G, UCHAR_MAX, tfGmap);
00185 glPixelMapfv(GL_PIXEL_MAP_B_TO_B, UCHAR_MAX, tfBmap);
00186 glPixelMapfv(GL_PIXEL_MAP_A_TO_A, UCHAR_MAX, tfAmap);
00187 }
00188 }
00189 if (hardware_map&&format == GL_LUMINANCE&&type == GL_UNSIGNED_SHORT
00190 && table_size>=USHRT_MAX)
00191 {
00192 glPixelTransferi(GL_MAP_COLOR, GL_TRUE);
00193 float* tfLmap = fLmap->begin();
00194 glPixelMapfv(GL_PIXEL_MAP_R_TO_R, USHRT_MAX, tfLmap);
00195 glPixelMapfv(GL_PIXEL_MAP_G_TO_G, USHRT_MAX, tfLmap);
00196 glPixelMapfv(GL_PIXEL_MAP_B_TO_B, USHRT_MAX, tfLmap);
00197 }
00198 }
00199
00200 static void GL_restore(GLboolean& map_color, GLint alignment, GLint row_length,
00201 GLint skip_pixels, GLint skip_rows)
00202 {
00203
00204 glPixelTransferi(GL_MAP_COLOR, map_color);
00205 glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
00206 glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
00207 glPixelStorei(GL_UNPACK_SKIP_ROWS , skip_pixels);
00208 glPixelStorei(GL_UNPACK_SKIP_PIXELS, skip_rows);
00209 }
00210
00211 bool vgui_section_render(void const *pixels,
00212 unsigned w, unsigned h,
00213 float x0, float y0,
00214 float x1, float y1,
00215 GLenum format,
00216 GLenum type ,
00217 bool hardware_map,
00218 vbl_array_1d<float>* fLmap,
00219 vbl_array_1d<float>* fRmap,
00220 vbl_array_1d<float>* fGmap,
00221 vbl_array_1d<float>* fBmap,
00222 vbl_array_1d<float>* fAmap)
00223 {
00224 assert(h>0);
00225 assert(pixels);
00226 assert(x0 <= x1);
00227 assert(y0 <= y1);
00228
00229 assert(!hardware_map||format != GL_LUMINANCE||fLmap);
00230 assert(!hardware_map||format != GL_RGB||(fRmap&&fGmap&&fBmap));
00231 assert(!hardware_map||format != GL_RGBA||(fRmap&&fGmap&&fBmap&&fAmap));
00232 float zoomx=1.0f, zoomy=1.0f;
00233 unsigned i0=0, j0=0, ni=0, nj=0;
00234 if (!clamped_viewport(x0, y0, x1, y1, i0, j0, ni, nj, zoomx, zoomy))
00235 return false;
00236 int i_x0 = i0, i_y0 = j0, i_x1 = i0+ni, i_y1 = j0+nj;
00237
00238 GLint alignment, row_length, skip_pixels, skip_rows, table_size;
00239 GLboolean map_color;
00240 GL_setup(format, type, hardware_map, alignment, row_length,
00241 skip_pixels, skip_rows, table_size, map_color, fLmap, fRmap,
00242 fGmap, fBmap, fAmap);
00243
00244 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00245 glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
00246 glPixelStorei(GL_UNPACK_SKIP_PIXELS, i_x0);
00247 glPixelStorei(GL_UNPACK_SKIP_ROWS, i_y0);
00248
00249 glPixelZoom( zoomx, zoomy );
00250 vgui_accelerate::instance()->vgui_glDrawPixels(i_x1 - i_x0,
00251 i_y1 - i_y0,
00252 format,
00253 type,
00254 pixels);
00255 GL_restore(map_color, alignment, row_length, skip_pixels, skip_rows);
00256 return true;
00257 }
00258
00259 bool vgui_view_render(void const *pixels,
00260 unsigned w, unsigned h,
00261 float zoomx, float zoomy,
00262 GLenum format,
00263 GLenum type ,
00264 bool hardware_map,
00265 vbl_array_1d<float>* fLmap,
00266 vbl_array_1d<float>* fRmap,
00267 vbl_array_1d<float>* fGmap,
00268 vbl_array_1d<float>* fBmap,
00269 vbl_array_1d<float>* fAmap)
00270 {
00271 assert(pixels);
00272 assert(!hardware_map||format != GL_LUMINANCE||fLmap);
00273 assert(!hardware_map||format != GL_RGB||(fRmap&&fGmap&&fBmap));
00274 assert(!hardware_map||format != GL_RGBA||(fRmap&&fGmap&&fBmap&&fAmap));
00275
00276
00277 GLint alignment, row_length, table_size, skip_pixels, skip_rows;
00278 GLboolean map_color;
00279 GL_setup(format, type, hardware_map, alignment, row_length,
00280 skip_pixels, skip_rows, table_size, map_color, fLmap, fRmap,
00281 fGmap, fBmap, fAmap);
00282
00283 glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
00284 glPixelStorei(GL_UNPACK_ROW_LENGTH, w);
00285 glPixelZoom( zoomx+0.001f, zoomy+0.001f );
00286
00287 vgui_accelerate::instance()->vgui_glDrawPixels(w,
00288 h,
00289 format,
00290 type,
00291 pixels);
00292
00293 GL_restore(map_color, alignment, row_length, skip_pixels, skip_rows);
00294 return true;
00295 }
00296
00297