1/*************************************************************************** 2 PluginGLView.m 3 PeopsSoftGPU 4 5 Created by Gil Pedersen on Sun April 18 2004. 6 Copyright (c) 2004 Gil Pedersen. 7 ***************************************************************************/ 8 9/*************************************************************************** 10 * * 11 * This program is free software; you can redistribute it and/or modify * 12 * it under the terms of the GNU General Public License as published by * 13 * the Free Software Foundation; either version 2 of the License, or * 14 * (at your option) any later version. See also the license.txt file for * 15 * additional informations. * 16 * * 17 ***************************************************************************/ 18 19#import <Cocoa/Cocoa.h> 20#include <OpenGL/gl.h> 21#include <OpenGL/glext.h> 22#include <OpenGL/glu.h> 23#include <GLUT/glut.h> 24#import "PluginGLView.h" 25#import "SGPUPreferences.h" 26#include "externals.h" 27#undef BOOL 28#include "gpu.h" 29#include "swap.h" 30 31#include <time.h> 32extern time_t tStart; 33 34static int mylog2(int val) 35{ 36 int i; 37 for (i=1; i<31; i++) 38 if (val <= (1 << i)) 39 return (1 << i); 40 41 return -1; 42} 43 44 45@implementation PluginGLView 46{ 47 GLubyte *image_base; 48 GLubyte *image[IMAGE_COUNT]; 49 50 GLboolean useShader; 51 float shaderQuality; 52 GLint buffers; 53 GLuint vertexShader; 54 GLuint fragmentShader; 55 GLuint program; 56 //GLint frame_rate; 57 58 GLenum texture_hint; 59 GLboolean rect_texture; 60 GLboolean client_storage; 61 GLboolean texture_range; 62 63 struct timeval cycle_time; 64 65 BOOL noDisplay; 66 BOOL drawBG; 67 68 int image_width; 69 int image_height; 70 int image_width2; 71 int image_height2; 72 int image_depth; 73 int image_type; 74 float image_tx; 75 float image_ty; 76 int whichImage; 77 BOOL isFullscreen; 78} 79@synthesize glLock; 80 81//- (id)initWithFrame:(NSRect)frameRect 82- (id) initWithCoder: (NSCoder *) coder 83{ 84 if ((self = [super initWithCoder:coder]) == nil) 85 return nil; 86 87 glLock = [[NSLock alloc] init]; 88 if (nil == glLock) { 89 return nil; 90 } 91 92 const GLubyte * strExt; 93 94 // Init pixel format attribs 95 static const NSOpenGLPixelFormatAttribute attrs[] = 96 { 97 NSOpenGLPFAAccelerated, 98 NSOpenGLPFANoRecovery, 99 NSOpenGLPFADoubleBuffer, 100 0 101 }; 102 103 // Get pixel format from OpenGL 104 NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs]; 105 if (!pixFmt) 106 { 107 NSLog(@"No Accelerated OpenGL pixel format found\n"); 108 109 static const NSOpenGLPixelFormatAttribute attrs2[] = 110 { 111 NSOpenGLPFANoRecovery, 112 0 113 }; 114 115 // Get pixel format from OpenGL 116 pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs2]; 117 if (!pixFmt) { 118 NSLog(@"No OpenGL pixel format found!\n"); 119 120 return nil; 121 } 122 } 123 124 [self setPixelFormat:pixFmt]; 125 126 /* 127 long swapInterval = 1 ; 128 [[self openGLContext] 129 setValues:&swapInterval 130 forParameter:NSOpenGLCPSwapInterval]; 131 */ 132 [glLock lock]; 133 [[self openGLContext] makeCurrentContext]; 134 135 // Init object members 136 strExt = glGetString (GL_EXTENSIONS); 137 texture_range = gluCheckExtension ((const unsigned char *)"GL_APPLE_texture_range", strExt) ? GL_TRUE : GL_FALSE; 138 texture_hint = GL_STORAGE_SHARED_APPLE ; 139 client_storage = gluCheckExtension ((const unsigned char *)"GL_APPLE_client_storage", strExt) ? GL_TRUE : GL_FALSE; 140 rect_texture = gluCheckExtension((const unsigned char *)"GL_EXT_texture_rectangle", strExt) ? GL_TRUE : GL_FALSE; 141 142 // Setup some basic OpenGL stuff 143 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); 144 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); 145 glColor4f(1.0f, 1.0f, 1.0f, 1.0f); 146 glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 147 glClear(GL_COLOR_BUFFER_BIT); 148 149 // Loads the shaders 150 151 if(isShaderEnabled()){ 152 rect_texture = GL_FALSE; 153 // --- Params --- 154 shaderQuality = PSXShaderQuality(); 155 vertexShader = [self loadShader:GL_VERTEX_SHADER location:PSXVertexShader()]; 156 fragmentShader = [self loadShader:GL_FRAGMENT_SHADER location:PSXFragmentShader()]; 157 158 //--- shader loading --- 159 program = glCreateProgram(); 160 glAttachShader(program, vertexShader); 161 glAttachShader(program, fragmentShader); 162 glLinkProgram(program); 163 glUseProgram(program); 164 } 165 166 167 [NSOpenGLContext clearCurrentContext]; 168 [glLock unlock]; 169 170 image_width = 1024; 171 image_height = 512; 172 image_depth = 16; 173 174 image_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; 175 image_base = (GLubyte *) calloc(((IMAGE_COUNT * image_width * image_height) / 3) * 4, image_depth >> 3); 176 if (image_base == nil) { 177 return nil; 178 } 179 180 // Create and load textures for the first time 181 [self loadTextures:GL_TRUE]; 182 183 // Init fps timer 184 //gettimeofday(&cycle_time, NULL); 185 186 drawBG = YES; 187 188 // Call for a redisplay 189 noDisplay = YES; 190 PSXDisplay.Disabled = 1; 191 [self setNeedsDisplay:YES]; 192 193 return self; 194} 195 196- (void)dealloc 197{ 198 int i; 199 200 [glLock lock]; 201 202 [[self openGLContext] makeCurrentContext]; 203 for(i = 0; i < IMAGE_COUNT; i++) 204 { 205 GLuint dt = i+1; 206 glDeleteTextures(1, &dt); 207 } 208 if(texture_range) 209 glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, IMAGE_COUNT * image_width * image_height * (image_depth >> 3), image_base); 210 211 [NSOpenGLContext clearCurrentContext]; 212 [glLock unlock]; 213 214 if (image_base) { 215 free(image_base); 216 } 217} 218 219- (BOOL)isOpaque 220{ 221 return YES; 222} 223 224- (BOOL)acceptsFirstResponder 225{ 226 return NO; 227} 228 229- (void)drawRect:(NSRect)aRect 230{ 231 // Check if an update has occured to the buffer 232 if ([self lockFocusIfCanDraw]) { 233 234 // Make this context current 235 if (drawBG) { 236 [[NSColor blackColor] setFill]; 237 [NSBezierPath fillRect:[self visibleRect]]; 238 } 239 240 //glFinish() ; 241 // Swap buffer to screen 242 //[[self openGLContext] flushBuffer]; 243 244 [self unlockFocus]; 245 } 246} 247 248#if 0 249- (void)update // moved or resized 250{ 251 NSRect rect; 252 253 [super update]; 254 255 [[self openGLContext] makeCurrentContext]; 256 [[self openGLContext] update]; 257 258 rect = [self bounds]; 259 260 glViewport(0, 0, (int) rect.size.width, (int) rect.size.height); 261 262 glMatrixMode(GL_PROJECTION); 263 glLoadIdentity(); 264 265 glMatrixMode(GL_MODELVIEW); 266 glLoadIdentity(); 267 268 //[self setNeedsDisplay:true]; 269} 270#endif 271 272- (void)reshape // scrolled, moved or resized 273{ 274 [glLock lock]; 275 276 [super reshape]; 277 278 NSOpenGLContext *oglContext = [self openGLContext]; 279 NSRect rect; 280 281 [oglContext makeCurrentContext]; 282 [oglContext update]; 283 284 rect = [[oglContext view] bounds]; 285 286 glViewport(0, 0, (int) rect.size.width, (int) rect.size.height); 287 288 glMatrixMode(GL_PROJECTION); 289 glLoadIdentity(); 290 291 glMatrixMode(GL_MODELVIEW); 292 glLoadIdentity(); 293 294 drawBG = YES; 295 296 [NSOpenGLContext clearCurrentContext]; 297 298 //[self setNeedsDisplay:true]; 299 [self renderScreen]; 300 [glLock unlock]; 301} 302 303- (void)renderScreen 304{ 305 int bufferIndex = whichImage; 306 307 if (1/*[glLock tryLock]*/) { 308 // Make this context current 309 [[self openGLContext] makeCurrentContext]; 310 311 if (PSXDisplay.Disabled) { 312 glClear(GL_COLOR_BUFFER_BIT); 313 } else { 314 // Bind, update and draw new image 315 if(rect_texture && isShaderEnabled() == NO) // cant go in there if we use shaders 316 { 317 //printf("Texture Rectangle\n"); 318 //glActiveTexture(bufferIndex+1); 319 glActiveTexture(GL_TEXTURE0); 320 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, bufferIndex+1); 321 322 glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, image_width, image_height, GL_BGRA, image_type, image[bufferIndex]); 323 324 325 glBegin(GL_QUADS); 326 { 327 glTexCoord2f(0.0f, 0.0f); 328 glVertex2f(-1.0f, 1.0f); 329 330 glTexCoord2f(0.0f, image_height); 331 glVertex2f(-1.0f, -1.0f); 332 333 glTexCoord2f(image_width, image_height); 334 glVertex2f(1.0f, -1.0f); 335 336 glTexCoord2f(image_width, 0.0f); 337 glVertex2f(1.0f, 1.0f); 338 } 339 glEnd(); 340 } 341 else 342 { 343 NSRect rect = [[[self openGLContext] view] bounds]; 344 //printf("Texture 2D normale de taille : %d, %d sur un ecran : %f x %f \n",image_width,image_height,rect.size.width,rect.size.height); 345 //glActiveTexture(whichImage+1); 346 glBindTexture(GL_TEXTURE_2D, whichImage+1); 347 348 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image_width2, image_height2, GL_BGRA, image_type, image[bufferIndex]); 349 350 351 if(isShaderEnabled()){ 352 glUseProgram(program); 353 354 int loc = glGetUniformLocation(program, "OGL2Texture"); 355 glUniform1i(loc,0); 356 int loc2 = glGetUniformLocation(program, "OGL2Param"); 357 float param[4]; 358 param[2] = shaderQuality; 359 param[0] = param[2] / image_width; 360 param[1] = param[2] / image_height; 361 //param[2]=2.0; 362 param[3] = 0.0; 363 int loc3 = glGetUniformLocation(program, "OGL2Size"); 364 float size[4]; 365 //NSRect rect = [[[self openGLContext] view] bounds]; 366 size[0] = image_width; 367 size[1] = image_height; 368 size[2] = rect.size.width; 369 size[3] = rect.size.height; 370 int loc4 = glGetUniformLocation(program, "OGL2InvSize"); 371 float invSize[4]; 372 invSize[0] = 1.0/size[0]; 373 invSize[1] = 1.0/size[1]; 374 invSize[2] = 1.0/size[2]; 375 invSize[3] = 1.0/size[3]; 376 //invSize[4]=1.0/size[4]; //Did we goof here? 377 glUniform4fv(loc2, 1, param); 378 glUniform4fv(loc3, 1, size); 379 glUniform4fv(loc4, 1, invSize); 380 } 381 382 glBegin(GL_QUADS); 383 { 384 glTexCoord2f(0.0f, 0.0f); 385 glVertex2f(-1.0f, 1.0f); 386 387 glTexCoord2f(0.0f, image_ty); 388 glVertex2f(-1.0f, -1.0f); 389 390 glTexCoord2f(image_tx, image_ty); 391 glVertex2f(1.0f, -1.0f); 392 393 glTexCoord2f(image_tx, 0.0f); 394 glVertex2f(1.0f, 1.0f); 395 } 396 glEnd(); 397 } 398 } 399 400 // FPS Display 401 if(ulKeybits&KEY_SHOWFPS) 402 { 403 int len, i; 404 if(szDebugText[0] && ((time(NULL) - tStart) < 2)) 405 { 406 strlcpy(szDispBuf, szDebugText, 63); 407 } 408 else 409 { 410 szDebugText[0]=0; 411 if (szMenuBuf) { 412 strncat(szDispBuf, szMenuBuf, 63 - strlen(szDispBuf)); 413 } 414 } 415 416 NSRect rect = [[[self openGLContext] view] bounds]; 417 len = (int) strlen(szDispBuf); 418 419 glMatrixMode(GL_PROJECTION); 420 glPushMatrix(); 421 422 gluOrtho2D(0.0, rect.size.width, 0.0, rect.size.height); 423 glDisable(rect_texture ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D); 424 425 glColor4f(0.0, 0.0, 0.0, 0.5); 426 glRasterPos2f(3.0, rect.size.height - 14.0); 427 for (i = 0; i < len; i++) { 428 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, szDispBuf[i]); 429 } 430 431 glColor3f(1.0, 1.0, 1.0); 432 glRasterPos2f(2.0, rect.size.height - 13.0); 433 for (i = 0; i < len; i++) { 434 glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, szDispBuf[i]); 435 } 436 437 glEnable(rect_texture ? GL_TEXTURE_RECTANGLE_EXT : GL_TEXTURE_2D); 438 glPopMatrix(); 439 } 440 441 //printProgramInfoLog(program); 442 //printf("\n\n\n"); 443 [[self openGLContext] flushBuffer]; 444 [NSOpenGLContext clearCurrentContext]; 445 //[glLock unlock]; 446 } 447} 448 449- (void)loadTextures:(GLboolean)first 450{ 451 GLint i; 452 printf("Loading texture\n"); 453 //[glLock lock]; 454 [[self openGLContext] makeCurrentContext]; 455 456 image_width = PreviousPSXDisplay.Range.x1; 457 image_height = PreviousPSXDisplay.DisplayMode.y; 458 if (PSXDisplay.RGB24) { 459 image_depth = 32; 460 image_type = GL_UNSIGNED_INT_8_8_8_8_REV; 461 } else { 462 image_depth = 16; 463 image_type = GL_UNSIGNED_SHORT_1_5_5_5_REV; 464 //image_width >>= 1; 465 } 466 467 if (image_width * image_height * (image_depth >> 3) > ((1024*512*2)/3)*4) 468 printf("Fatal error: desired dimension are too large! (%ix%i %ibpp)\n", 469 image_width, image_height, image_depth); 470 471 for(i = 0; i < IMAGE_COUNT; i++) 472 image[i] = image_base + i * image_width * image_height * (image_depth >> 3); 473 474 if(rect_texture) 475 { 476 image_width2 = image_width; 477 image_height2 = image_height; 478 image_tx = (float)image_width; 479 image_ty = (float)image_height; 480 481 if(texture_range) glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, IMAGE_COUNT * image_width * image_height * (image_depth >> 3), image_base); 482 else glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, 0, NULL); 483 484 for(i = 0; i < IMAGE_COUNT; i++) 485 { 486 if(!first) 487 { 488 GLuint dt = i+1; 489 glDeleteTextures(1, &dt); 490 } 491 492 glDisable(GL_TEXTURE_2D); 493 glActiveTexture(GL_TEXTURE0); 494 glEnable(GL_TEXTURE_RECTANGLE_EXT); 495 glBindTexture(GL_TEXTURE_RECTANGLE_EXT, i+1); 496 497 498 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , texture_hint); 499 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, client_storage); 500 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 501 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 502 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 503 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 504 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 505 506 glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, image_width, 507 image_height, 0, GL_BGRA, image_type, image[i]); 508 } 509 } 510 else 511 { 512 image_width2 = mylog2(image_width); 513 image_height2 = mylog2(image_height); 514 image_tx = (float)image_width/(float)image_width2; 515 image_ty = (float)image_height/(float)image_height2; 516 517 glTextureRangeAPPLE(GL_TEXTURE_RECTANGLE_EXT, 0, NULL); 518 if(texture_range) glTextureRangeAPPLE(GL_TEXTURE_2D, IMAGE_COUNT * image_width2 * image_height2 * (image_depth >> 3), image_base); 519 else glTextureRangeAPPLE(GL_TEXTURE_2D, 0, NULL); 520 521 for(i = 0; i < IMAGE_COUNT; i++) 522 { 523 if(!first) 524 { 525 GLuint dt = i+1; 526 glDeleteTextures(1, &dt); 527 } 528 529 glDisable(GL_TEXTURE_RECTANGLE_EXT); 530 glEnable(GL_TEXTURE_2D); 531 glBindTexture(GL_TEXTURE_2D, i+1); 532 533 //if(texture_range) glTextureRangeAPPLE(GL_TEXTURE_2D, IMAGE_COUNT * image_width2 * image_height2 * (image_depth >> 3), image_base); 534 //else glTextureRangeAPPLE(GL_TEXTURE_2D, 0, NULL); 535 536 glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE , texture_hint); 537 glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, client_storage); 538 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 539 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 540 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 541 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 542 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); 543 544 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image_width2, 545 image_height2, 0, GL_BGRA, image_type, image[i]); 546 } 547 } 548 549 [NSOpenGLContext clearCurrentContext]; 550 //[glLock unlock]; 551} 552 553- (void)swapBuffer 554{ 555 RunOnMainThreadSync(^{ 556 //printf("y=%i",PSXDisplay.DisplayPosition.y); 557 558 unsigned char * surf; 559 long x = PSXDisplay.DisplayPosition.x; 560 long y = PSXDisplay.DisplayPosition.y; 561 GLuint lu; 562 unsigned short row,column; 563 unsigned short dx=PreviousPSXDisplay.Range.x1; 564 unsigned short dy=PreviousPSXDisplay.DisplayMode.y; 565 long lPitch; 566 567 if ([glLock tryLock]) { 568 // make sure the texture area is ready to be written to 569 glFinishObjectAPPLE(GL_TEXTURE, 2-whichImage); 570 571 if ((image_width != PreviousPSXDisplay.Range.x1) || 572 (image_height != PreviousPSXDisplay.DisplayMode.y) || 573 ((PSXDisplay.RGB24 ? 32 : 16) != image_depth)) { 574 [self loadTextures:GL_FALSE]; 575 } 576 577 surf = image[1-whichImage]; 578 lPitch=image_width2<<(image_depth >> 4); 579 580 if(PreviousPSXDisplay.Range.y0) // centering needed? 581 { 582 surf+=PreviousPSXDisplay.Range.y0*lPitch; 583 dy-=PreviousPSXDisplay.Range.y0; 584 } 585 586 if(PSXDisplay.RGB24) 587 { 588 unsigned char * pD; 589 size_t startxy; 590 591 surf+=PreviousPSXDisplay.Range.x0<<2; 592 593 for(column=0;column<dy;column++) 594 { 595 startxy = (1024 * (column + y)) + x; 596 pD = (unsigned char *)&psxVuw[startxy]; 597 598 row = 0; 599 // make sure the reads are aligned 600 while ((intptr_t)pD & 0x3) { 601 *((unsigned long *)((surf)+(column*lPitch)+(row<<2))) = 602 (*(pD+0)<<16)|(*(pD+1)<<8)|*(pD+2); 603 604 pD+=3; 605 row++; 606 } 607 608 for(;row<dx;row+=4) 609 { 610 GLuint lu1 = *((GLuint *)pD); 611 GLuint lu2 = *((GLuint *)pD+1); 612 GLuint lu3 = *((GLuint *)pD+2); 613 GLuint *dst = ((GLuint *)((surf)+(column*lPitch)+(row<<2))); 614#ifdef __BIG_ENDIAN__ 615 *(dst)= 616 (((lu1>>24)&0xff)<<16)|(((lu1>>16)&0xff)<<8)|(((lu1>>8)&0xff)); 617 *(dst+1)= 618 (((lu1>>0)&0xff)<<16)|(((lu2>>24)&0xff)<<8)|(((lu2>>16)&0xff)); 619 *(dst+2)= 620 (((lu2>>8)&0xff)<<16)|(((lu2>>0)&0xff)<<8)|(((lu3>>24)&0xff)); 621 *(dst+3)= 622 (((lu3>>16)&0xff)<<16)|(((lu3>>8)&0xff)<<8)|(((lu3>>0)&0xff)); 623#else 624 *(dst)= 625 (((lu1>>0)&0xff)<<16)|(((lu1>>8)&0xff)<<8)|(((lu1>>16)&0xff)); 626 *(dst+1)= 627 (((lu1>>24)&0xff)<<16)|(((lu2>>0)&0xff)<<8)|(((lu2>>8)&0xff)); 628 *(dst+2)= 629 (((lu2>>16)&0xff)<<16)|(((lu2>>24)&0xff)<<8)|(((lu3>>0)&0xff)); 630 *(dst+3)= 631 (((lu3>>8)&0xff)<<16)|(((lu3>>16)&0xff)<<8)|(((lu3>>24)&0xff)); 632#endif 633 pD+=12; 634 } 635 636 //for(;row<dx;row+=4) 637 /*while (pD&0x3) { 638 *((unsigned long *)((surf)+(column*lPitch)+(row<<2)))= 639 (*(pD+0)<<16)|(*(pD+1)<<8)|(*(pD+2)&0xff)); 640 pD+=3; 641 row++; 642 }*/ 643 } 644 } 645 else 646 { 647 long LineOffset,SurfOffset; 648 GLuint * SRCPtr = (GLuint *)(psxVuw + (y << 10) + x); 649 GLuint * DSTPtr = 650 ((GLuint *)surf) + (PreviousPSXDisplay.Range.x0 >> 1); 651 652 dx >>= 1; 653 654 LineOffset = 512 - dx; 655 SurfOffset = (lPitch >> 2) - dx; 656 657 for(column=0;column<dy;column++) 658 { 659 for(row=0;row<dx;row++) 660 { 661#ifdef __BIG_ENDIAN__ 662 lu=GETLE16D(SRCPtr++); 663#else 664 lu=*SRCPtr++; 665#endif 666 *DSTPtr++= 667 ((lu << 10) & 0x7c007c00)| 668 ((lu) & 0x3e003e0)| 669 ((lu >> 10) & 0x1f001f); 670 } 671 SRCPtr += LineOffset; 672 DSTPtr += SurfOffset; 673 } 674 } 675 676 // Swap image buffer 677 whichImage = 1 - whichImage; 678 679 [self renderScreen]; 680 [glLock unlock]; 681 } 682 683 }); 684} 685 686- (void)clearBuffer:(BOOL)display 687{ 688 if (display == NO) { 689 //[[self openGLContext] makeCurrentContext]; 690 //glClear(GL_COLOR_BUFFER_BIT); 691 //[self loadTextures:NO]; 692 } else { 693 noDisplay = YES; 694 //[self setNeedsDisplay:true]; 695 } 696} 697 698- (GLuint)loadShader:(GLenum)type location:(NSURL*)filename 699{ 700 GLuint myShader = 0; 701 702 GLsizei logsize = 0; 703 GLint compile_status = GL_TRUE; 704 char *log = NULL; 705 char *src = NULL; 706 707 /* creation d'un shader de sommet */ 708 myShader = glCreateShader(type); 709 if(myShader == 0) 710 { 711 NSLog(@"impossible de creer le shader"); 712 return 0; 713 } 714 715 /* chargement du code source */ 716 src = [PluginGLView loadSource:filename]; 717 if(src == NULL) 718 { 719 /* theoriquement, la fonction LoadSource a deja affiche un message 720 d'erreur, nous nous contenterons de supprimer notre shader 721 et de retourner 0 */ 722 723 glDeleteShader(myShader); 724 return 0; 725 } 726 727 /* assignation du code source */ 728 glShaderSource(myShader, 1, (const GLchar**)&src, NULL); 729 730 /* compilation du shader */ 731 glCompileShader(myShader); 732 733 /* liberation de la memoire du code source */ 734 free(src); 735 src = NULL; 736 737 /* verification du succes de la compilation */ 738 glGetShaderiv(myShader, GL_COMPILE_STATUS, &compile_status); 739 if(compile_status != GL_TRUE) 740 { 741 /* erreur a la compilation recuperation du log d'erreur */ 742 743 /* on recupere la taille du message d'erreur */ 744 glGetShaderiv(myShader, GL_INFO_LOG_LENGTH, &logsize); 745 746 /* on alloue un espace memoire dans lequel OpenGL ecrira le message */ 747 log = calloc(logsize + 1, 1); 748 if(log == NULL) 749 { 750 NSLog(@"impossible d'allouer de la memoire!"); 751 return 0; 752 } 753 754 glGetShaderInfoLog(myShader, logsize, &logsize, log); 755 NSLog(@"impossible de compiler le shader '%@' :\n%s", 756 [filename path], log); 757 758 /* ne pas oublier de liberer la memoire et notre shader */ 759 free(log); 760 glDeleteShader(myShader); 761 762 return 0; 763 } 764 return myShader; 765} 766 767+ (char*)loadSource:(NSURL *)filename 768{ 769 //Since we're passing Cocoa NSURLs, let's use Cocoa's methods 770 if (filename == nil) { 771 return NULL; 772 } 773 774 NSUInteger len; 775 NSMutableData *shaderData = [[NSMutableData alloc] initWithContentsOfURL:filename]; 776 [shaderData appendBytes:"\0" length:1]; 777 len = [shaderData length]; 778 char *shaderText = malloc(len); 779 [shaderData getBytes:shaderText length:len]; 780 return shaderText; 781} 782 783@end 784