00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "mx3d_graphics.h"
00017 #include "SDL.h"
00018 #include<iostream>
00019
00020
00021
00022 namespace mx3d
00023 {
00024
00025
00026 static int max_clip_x = 640, min_clip_x = 0, max_clip_y = 480, min_clip_y = 0;
00027
00028
00029 void Swap(int& a, int& b)
00030 {
00031 int temp = a;
00032 a = b;
00033 b = temp;
00034 }
00035
00036 void Swap(float& a, float& b)
00037 {
00038 float temp = a;
00039 a = b;
00040 b = temp;
00041 }
00042
00043
00044
00045
00046
00047
00048
00049 void *buffer = 0;
00050 bool is_locked = false;
00051
00052
00053
00054 graphicsInterface::graphicsInterface(SDL_Surface *f)
00055 {
00056
00057
00058 if(f == 0) front = SDL_GetVideoSurface();
00059 else front = f;
00060
00061
00062 const struct SDL_VideoInfo *vi;
00063 vi = SDL_GetVideoInfo();
00064
00065 w = vi->current_w;
00066 h = vi->current_h;
00067 rect.x = 0;
00068 rect.y = 0;
00069 rect.w = w;
00070 rect.h = h;
00071 rect.Pitch = front->pitch;
00072
00073 std::cout << "gfx iface: " << w << ":" << h << ":" << front->pitch << "\n";
00074 SDL_FillRect(front, 0, SDL_MapRGB(front->format, 255, 255, 255));
00075
00076
00077 }
00078
00079 graphicsInterface::~graphicsInterface()
00080 {
00081
00082
00083
00084 }
00085
00086
00087
00088 void graphicsInterface::lock()
00089 {
00090
00091 SDL_LockSurface(front);
00092 buffer = (void*) front->pixels;
00093 is_locked = true;
00094
00095 }
00096
00097
00098 void graphicsInterface::unlock()
00099 {
00100 SDL_UnlockSurface(front);
00101 is_locked = false;
00102
00103 }
00104
00105
00106
00107 void graphicsInterface::fast_sp(int x, int y, int, unsigned int color)
00108 {
00109
00110 if(is_locked == false) { return; }
00111
00112 unsigned int *ptr = (unsigned int *) buffer;
00113 ptr[x+(y*w)] = color;
00114 }
00115
00116 void graphicsInterface::setpixel(int x, int y, unsigned int color)
00117 {
00118
00119 fast_sp(x,y,4,color);
00120 }
00121
00122 unsigned int graphicsInterface::fast_gp(int x, int y)
00123 {
00124
00125 unsigned int *ptr = (unsigned int *) buffer;
00126 unsigned int *p = &ptr[x+(y*w)];
00127 return *p;
00128
00129 }
00130
00131
00132 void graphicsInterface::drawrect(int x, int y, int w, int h, unsigned int color)
00133 {
00134
00135 SDL_Rect rc = { x,y,w,h };
00136 SDL_FillRect(front, &rc, color);
00137
00138 }
00139
00140 void graphicsInterface::drawbottomtri(int x1, int y1, int x2, int , int x3, int y3, unsigned int color) {
00141 float dx_right,dx_left,xs,xe,height;
00142 int temp_x,temp_y,right,left;
00143 if (x3 < x2) {
00144 temp_x = x2;
00145 x2 = x3;
00146 x3 = temp_x;
00147 }
00148 height = float(y3-y1);
00149 dx_left = (x2-x1)/height;
00150 dx_right = (x3-x1)/height;
00151
00152 xs = (float)x1;
00153 xe = (float)x1;
00154 if (y1 < min_clip_y) {
00155 xs = xs+dx_left*(float)(-y1+min_clip_y);
00156 xe = xe+dx_right*(float)(-y1+min_clip_y);
00157 y1 = min_clip_y;
00158 }
00159
00160 if (y3 > max_clip_y)
00161 y3 = max_clip_y;
00162
00163 if (x1>=min_clip_x && x1<=max_clip_x && x2>=min_clip_x && x2<=max_clip_x && x3>=min_clip_x && x3<=max_clip_x) {
00164 for (temp_y=y1; temp_y<=y3; temp_y++) {
00165 drawhline(int(xs),(int)xs+(int(xe-xs+1)),temp_y,color);
00166 xs+=dx_left;
00167 xe+=dx_right;
00168
00169 }
00170 }
00171 else
00172 {
00173 for (temp_y=y1; temp_y<=y3; temp_y++) {
00174 left = (int)xs;
00175 right = (int)xe;
00176 xs+=dx_left;
00177 xe+=dx_right;
00178
00179 if (left < min_clip_x){
00180 left = min_clip_x;
00181
00182 if (right < min_clip_x)
00183 continue;
00184 }
00185
00186 if (right > max_clip_x)
00187 {
00188 right = max_clip_x;
00189
00190 if (left > max_clip_x)
00191 continue;
00192 }
00193 drawhline(int(left),(int)left+(int(right-left+1)),temp_y,color);
00194 }
00195 }
00196 }
00197
00198
00199 void graphicsInterface::drawtoptri(int x1, int y1,int x2, int , int x3, int y3, unsigned int color) {
00200
00201 float dx_right,dx_left,xs,xe,height;
00202
00203 int temp_x,temp_y,right,left;
00204
00205 if (x2 < x1) {
00206 temp_x = x2;
00207 x2 = x1;
00208 x1 = temp_x;
00209 }
00210
00211 height = float(y3-y1);
00212
00213 dx_left = (x3-x1)/height;
00214 dx_right = (x3-x2)/height;
00215
00216 xs = (float)x1;
00217 xe = (float)x2;
00218 if (y1 < min_clip_y) {
00219 xs = xs+dx_left*(float)(-y1+min_clip_y);
00220 xe = xe+dx_right*(float)(-y1+min_clip_y);
00221 y1=min_clip_y;
00222 }
00223
00224 if (y3>max_clip_y)
00225 y3=max_clip_y;
00226
00227 if (x1>=min_clip_x && x1<=max_clip_x && x2>=min_clip_x && x2<=max_clip_x && x3>=min_clip_x && x3<=max_clip_x) {
00228 for (temp_y=y1; temp_y<=y3; temp_y++) {
00229 drawhline(int(xs),int(xs+(int)xe-xs+1),temp_y,color);
00230 xs+=dx_left;
00231 xe+=dx_right;
00232 }
00233 }
00234 else {
00235 for (temp_y=y1; temp_y<=y3; temp_y++) {
00236 left = (int)xs;
00237 right = (int)xe;
00238 xs+=dx_left;
00239 xe+=dx_right;
00240 if (left < min_clip_x) {
00241 left = min_clip_x;
00242 if (right < min_clip_x)
00243 continue;
00244 }
00245
00246 if (right > max_clip_x) {
00247 right = max_clip_x;
00248
00249 if (left > max_clip_x)
00250 continue;
00251 }
00252 drawhline((int)left,(int)left+(int)right-left+1,temp_y,color);
00253 }
00254
00255 }
00256
00257
00258 }
00259
00260
00261 void graphicsInterface::drawtri(int x1, int y1,int x2, int y2, int x3, int y3, unsigned int color) {
00262 int temp_x,temp_y,new_x;
00263
00264 if ((x1==x2 && x2==x3) || (y1==y2 && y2==y3))
00265 return;
00266
00267 if (y2<y1) {
00268 temp_x = x2;
00269 temp_y = y2;
00270 x2 = x1;
00271 y2 = y1;
00272 x1 = temp_x;
00273 y1 = temp_y;
00274 }
00275
00276 if (y3<y1) {
00277 temp_x = x3;
00278 temp_y = y3;
00279 x3 = x1;
00280 y3 = y1;
00281 x1 = temp_x;
00282 y1 = temp_y;
00283 }
00284
00285 if (y3<y2) {
00286 temp_x = x3;
00287 temp_y = y3;
00288 x3 = x2;
00289 y3 = y2;
00290 x2 = temp_x;
00291 y2 = temp_y;
00292
00293 }
00294 if ( y3<min_clip_y || y1>max_clip_y || (x1<min_clip_x && x2<min_clip_x && x3<min_clip_x) || (x1>max_clip_x && x2>max_clip_x && x3>max_clip_x) )
00295 return;
00296
00297
00298 if (y1==y2) {
00299 this->drawtoptri(x1,y1,x2,y2,x3,y3,color);
00300 }
00301 else
00302 if (y2==y3){
00303 this->drawbottomtri(x1,y1,x2,y2,x3,y3,color);
00304 }
00305 else {
00306 new_x = x1 + (int)(0.5+(float)(y2-y1)*(float)(x3-x1)/(float)(y3-y1));
00307 this->drawbottomtri(x1,y1,new_x,y2,x2,y2,color);
00308 this->drawtoptri(x2,y2,new_x,y2,x3,y3,color);
00309 }
00310 }
00311
00312 void graphicsInterface::drawhline(int x,int x2, int y,unsigned int color) {
00313 for(int p = x; p <= x2; p++)
00314 fast_sp(p,y,rect.Pitch,color);
00315 }
00316
00317 void graphicsInterface::drawtri2(float , float , float , float , float , float , unsigned int ) {
00318
00319 }
00320
00321 void graphicsInterface::drawgentri(int x0, int y0, int x1, int y1, int x2, int y2, unsigned int color) {
00322
00323 if( y1 < y0 )
00324 {
00325 Swap(y1, y0);
00326 Swap(x1, x0);
00327 }
00328 if( y2 < y0 )
00329 {
00330 Swap(y2, y0);
00331 Swap(x2, x0);
00332 }
00333
00334 if( y1 < y2 )
00335 {
00336 Swap(y2, y1);
00337 Swap(x2, x1);
00338 }
00339
00340
00341 float xl_edge = (float)x0;
00342 float xr_edge = (float)x0;
00343 float dxldy;
00344 float dxrdy;
00345 float dxdy1 = (float)(x2-x0)/(y2-y0);
00346 float dxdy2 = (float)(x1-x0)/(y1-y0);
00347 if( dxdy1 < dxdy2 )
00348 {
00349 dxldy = dxdy1;
00350 dxrdy = dxdy2;
00351 }
00352 else
00353 {
00354 dxldy = dxdy2;
00355 dxrdy = dxdy1;
00356 }
00357
00358 for(int y=y0; y<y2; y++)
00359 {
00360 for(int x=int(xl_edge); x<int(xr_edge); x++)
00361 {
00362 this->fast_sp(x, y, this->rect.Pitch, color);
00363 }
00364
00365 xl_edge = xl_edge + dxldy;
00366 xr_edge = xr_edge + dxrdy;
00367
00368 }
00369
00370 if( dxdy1 < dxdy2 )
00371 {
00372 dxldy = (float)(x2-x1)/(y2-y1);
00373 }
00374 else
00375 {
00376 dxrdy = (float)(x2-x1)/(y2-y1);
00377 }
00378 for(int y=y2; y<y1; y++)
00379 {
00380 for(int x=int(xl_edge); x<int(xr_edge); x++)
00381 {
00382 this->fast_sp(x,y,this->rect.Pitch,color);
00383 }
00384
00385 xl_edge = xl_edge + dxldy;
00386 xr_edge = xr_edge + dxrdy;
00387 }
00388 }
00389
00390
00391
00392 void graphicsInterface::drawline(int start_x, int start_y, int stop_x, int stop_y, unsigned int color) {
00393
00394
00395
00396 int y_unit,x_unit;
00397 int ydiff = stop_y-start_y;
00398 if(ydiff<0)
00399 {
00400 ydiff = -ydiff;
00401 y_unit=-1;
00402 }
00403 else
00404 {
00405 y_unit =1;
00406 }
00407 int xdiff=stop_x-start_x;
00408 if(xdiff<0)
00409 {
00410 xdiff=-xdiff;
00411 x_unit = -1;
00412 }
00413 else
00414 {
00415 x_unit = 1;
00416 }
00417
00418 int error_term=0;
00419 if(xdiff>ydiff)
00420 {
00421 int length=xdiff+1;
00422 for(int i = 0; i <length; i++)
00423 {
00424
00425 fast_sp(start_x,start_y,rect.Pitch,color);
00426 start_x += x_unit;
00427 error_term+=ydiff;
00428 if(error_term>xdiff)
00429 {
00430 error_term-=xdiff;
00431 start_y+=y_unit;
00432 }
00433 }
00434 }
00435 else
00436 {
00437 int length = ydiff+1;
00438 for(int i = 0; i < length; i++)
00439 {
00440
00441 fast_sp(start_x,start_y,rect.Pitch,color);
00442 start_y += y_unit;
00443 error_term+=xdiff;
00444 if(error_term>0)
00445 {
00446 error_term-=ydiff;
00447 start_x += x_unit;
00448 }
00449
00450 }
00451 }
00452
00453 }
00454
00455
00456
00457 }