/* * This program is WAY overkill for what we need, * but it works fine on Cocoa * It sets up a minimalist OpenGL Cocoa program with compatibility */ //Copyright (c) 2017 <>< David Chapman - Under the MIT/x11 or NewBSD License you choose. #import // ToDo: This shouldn't need OpenGL, just to draw to framebuffer // but if you have Cocoa, you should have OpenGL, so it's okay #import #import #include "CNFGFunctions.h" #include "CNFGRasterizer.h" // NSEvent enum types #define EVENT_KEY_DOWN 10 #define EVENT_KEY_UP 11 #define EVENT_LEFT_MOUSE_DOWN 1 #define EVENT_LEFT_MOUSE_UP 2 #define MultMatrix4x4_internal(A,B,C) { \ int _y,_x,_k;\ for (_y=0; _y<4; _y++) { \ for (_x=0; _x<4; _x++) { \ C[_y][_x] = 0.0f; \ for (_k=0; _k<4; _k++) { \ C[_y][_x] += B[_y][_k] * A[_k][_x]; \ } \ } \ } \ } #define PrintMatrix4x4(A) { \ int _y,_x;\ printf(#A "\n"); \ for (_y=0; _y<4; _y++) { \ for (_x=0; _x<4; _x++) { \ printf("%0.6f\t", A[_y][_x]); \ } \ printf("\n"); \ } \ } \ typedef struct { float x,y,z, // Position r,g,b,a, // Color u,v,w, // Tex Coord nx,ny,nz; // Normals } VertexArrayVert; #define VertexArrayVertSet(_p,_x,_y,_z,_r,_g,_b,_a,_u,_v,_w) { _p.x=(_x); _p.y=(_y); _p.z=(_z); _p.r=(_r); _p.g=(_g); _p.b=(_b); _p.a=(_a); _p.u=(_u); _p.v=(_v); _p.w=(_w); } typedef struct { VertexArrayVert *vert; // An Interleaved Vertex Array int nVert; // Numver of vertices } VertexArray; /* * VertexArrayDraw(A, mode) * Draws an interleaved vertex array 'A' * mode must be GL_TRIANGLES or GL_QUADS */ // Deprecated, OGL 1.1 code (vertex arrays) #define VertexArrayDraw(A,mode) { \ glEnableClientState(GL_VERTEX_ARRAY); \ glEnableClientState(GL_COLOR_ARRAY); \ glEnableClientState(GL_TEXTURE_COORD_ARRAY); \ glVertexPointer (3, GL_FLOAT, sizeof(VertexArrayVert), &((A).vert[0].x)); \ glColorPointer (4, GL_FLOAT, sizeof(VertexArrayVert), &((A).vert[0].r)); \ glTexCoordPointer(3, GL_FLOAT, sizeof(VertexArrayVert), &((A).vert[0].u)); \ glDrawArrays ((mode), 0, (A).nVert); \ glDisableClientState(GL_VERTEX_ARRAY); \ glDisableClientState(GL_COLOR_ARRAY); \ glDisableClientState(GL_TEXTURE_COORD_ARRAY); } /* * Compatibility layer */ void oglCompatibilityInit(int maxVerts); extern GLuint ogl_compat_shader_program; extern GLuint ogl_compat_position_attribute; extern GLuint ogl_compat_colour_attribute; extern GLuint ogl_compat_texcoord_attribute; extern GLuint ogl_compat_texcoord_enabled; extern GLuint ogl_compat_texUnit; extern GLuint ogl_compat_modelview_projection; extern GLuint ogl_compat_vertex_array_object; extern GLuint ogl_compat_vertex_buffer; extern int ogl_compat_vertex_array_mode; extern VertexArrayVert ogl_compat_vertex_array_prev_vert; extern VertexArray ogl_compat_vertex_array; #define oglEnableTexCoord() { glUniform1i(ogl_compat_texcoord_enabled,1); } #define oglDisableTexCoord() { glUniform1i(ogl_compat_texcoord_enabled,0); } #define oglBindTexture(_tex) { glProgramUniform1i(ogl_compat_shader_program, ogl_compat_texUnit, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D,_tex); } #define oglBegin(mode) { ogl_compat_vertex_array_mode = mode; ogl_compat_vertex_array.nVert = 0; } #define oglVertex3f(_x,_y,_z) { \ ogl_compat_vertex_array_prev_vert.x = (_x); ogl_compat_vertex_array_prev_vert.y = (_y); ogl_compat_vertex_array_prev_vert.z = (_z); \ ogl_compat_vertex_array.vert[ogl_compat_vertex_array.nVert] = ogl_compat_vertex_array_prev_vert; \ ogl_compat_vertex_array.nVert++; } #define oglVertex2f(_x,_y) oglVertex3f(_x,_y,0.0f) #define oglTexCoord3f(_u,_v,_w) { ogl_compat_vertex_array_prev_vert.u = (_u); ogl_compat_vertex_array_prev_vert.v = (_v); ogl_compat_vertex_array_prev_vert.w = (_w); } #define oglTexCoord2f(_u,_v) oglTexCoord3f(_u,_v,0.0f) #define oglColor4f(_r,_g,_b,_a) { ogl_compat_vertex_array_prev_vert.r = (_r); ogl_compat_vertex_array_prev_vert.g = (_g); ogl_compat_vertex_array_prev_vert.b = (_b); ogl_compat_vertex_array_prev_vert.a = (_a); } #define oglColor3f(r,g,b) oglColor4f(r,g,b,1.0f) #define oglEnd() { \ glBindVertexArray(ogl_compat_vertex_array_object); \ glBindBuffer(GL_ARRAY_BUFFER, ogl_compat_vertex_buffer); \ glBufferData(GL_ARRAY_BUFFER, ogl_compat_vertex_array.nVert*sizeof(VertexArrayVert), ogl_compat_vertex_array.vert, GL_DYNAMIC_DRAW); \ glEnableVertexAttribArray((GLuint)ogl_compat_position_attribute); \ glEnableVertexAttribArray((GLuint)ogl_compat_colour_attribute ); \ glEnableVertexAttribArray((GLuint)ogl_compat_texcoord_attribute ); \ glVertexAttribPointer((GLuint)ogl_compat_position_attribute, 3, GL_FLOAT, GL_FALSE, sizeof(VertexArrayVert), (GLvoid *)(0)); \ glVertexAttribPointer((GLuint)ogl_compat_colour_attribute , 4, GL_FLOAT, GL_FALSE, sizeof(VertexArrayVert), (GLvoid *)(3*sizeof(float))); \ glVertexAttribPointer((GLuint)ogl_compat_texcoord_attribute, 3, GL_FLOAT, GL_FALSE, sizeof(VertexArrayVert), (GLvoid *)(7*sizeof(float))); \ glUseProgram(ogl_compat_shader_program); \ float (*_modelview)[4] = ogl_compat_matrix[ ogl_compat_matrix_level[OGL_MODELVIEW] ][ OGL_MODELVIEW ]; \ float (*_projection)[4] = ogl_compat_matrix[ ogl_compat_matrix_level[OGL_PROJECTION] ][ OGL_PROJECTION ]; \ float _MVP[4][4]; MultMatrix4x4_internal(_projection,_modelview,_MVP); \ glUniformMatrix4fv( ogl_compat_modelview_projection, 1, 0, (GLfloat*)(_MVP)); \ glDrawArrays(ogl_compat_vertex_array_mode, 0, ogl_compat_vertex_array.nVert); \ glDisableVertexAttribArray((GLuint)ogl_compat_position_attribute); \ glDisableVertexAttribArray((GLuint)ogl_compat_colour_attribute ); \ glDisableVertexAttribArray((GLuint)ogl_compat_texcoord_attribute); } //PrintMatrix4x4(_modelview); PrintMatrix4x4(_projection); PrintMatrix4x4(_MVP); \ //printf("mode %d nVerts %d\n", ogl_compat_vertex_array_mode, ogl_compat_vertex_array.nVert); PrintMatrix4x4(_MVP); \ /* Matrix math */ #define OGL_MODELVIEW 0 #define OGL_PROJECTION 1 #define OGL_MAX_MATRIX_PUSH 64 // how many? m/p dims extern float ogl_compat_matrix[OGL_MAX_MATRIX_PUSH][2][4][4]; // the matrices extern int ogl_compat_matrix_level[2]; // how many times have we pushed? extern int ogl_compat_matrix_mode; #define oglMatrixMode(mode) { ogl_compat_matrix_mode=mode; } #define oglLoadIdentity() { \ float (*m)[4] = ogl_compat_matrix[ ogl_compat_matrix_level[ogl_compat_matrix_mode] ][ ogl_compat_matrix_mode ]; \ m[0][0] = 1.0f; m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f; \ m[1][0] = 0.0f; m[1][1] = 1.0f; m[1][2] = 0.0f; m[1][3] = 0.0f; \ m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = 1.0f; m[2][3] = 0.0f; \ m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = 0.0f; m[3][3] = 1.0f; } #define oglPushMatrix() { \ if ( ogl_compat_matrix_level[ogl_compat_matrix_mode] >= OGL_MAX_MATRIX_PUSH ) { printf("ERROR oglPushMatrix max push level (%d) exceeded\n", OGL_MAX_MATRIX_PUSH); exit(1); } \ memcpy(ogl_compat_matrix[ogl_compat_matrix_level[0]+1], ogl_compat_matrix[ogl_compat_matrix_level[0]], 16*sizeof(float)); \ memcpy(ogl_compat_matrix[ogl_compat_matrix_level[1]+1], ogl_compat_matrix[ogl_compat_matrix_level[1]], 16*sizeof(float)); \ ogl_compat_matrix_level[0]++; ogl_compat_matrix_level[1]++; } #define oglPopMatrix() { \ if ( ogl_compat_matrix_level[ogl_compat_matrix_mode] < 0 ) { printf("ERROR oglPopMatrix pop level underflow ( < 0 )\n"); exit(1); } \ ogl_compat_matrix_level[0]--; ogl_compat_matrix_level[1]--; } #define oglMultMatrixf(A) {\ float (*B)[4] = ogl_compat_matrix[ ogl_compat_matrix_level[ogl_compat_matrix_mode] ][ ogl_compat_matrix_mode ]; \ float C[4][4]; \ MultMatrix4x4_internal(B,A,C); \ memcpy(B, C, 16*sizeof(float)); } #define oglRotatef(deg,ux,uy,uz) { \ float _rad=(deg)*(PI/180.0); \ float _inv_len=sqrt((ux)*(ux) + (uy)*(uy) + (uz)*(uz)); \ float _ux=(ux)*_inv_len, _uy=(uy)*_inv_len, _uz=(uz)*_inv_len; \ float _c=cos(_rad), _s=sin(_rad); \ float m[4][4]; \ m[0][0] = _c +_ux*_ux*(1.0f-_c); m[0][1] = _ux*_uy*(1.0f-_c) - _uz*_s; m[0][2] = _ux*_uz*(1.0f-_c) + _uy*_s; m[0][3] = 0.0f; \ m[1][0] = _uy*_ux*(1.0f-_c) + _uz*_s; m[1][1] = _c + _uy*_uy*(1.0f-_c); m[1][2] = _uy*_uz*(1.0f-_c) - _ux*_s; m[1][3] = 0.0f; \ m[2][0] = _uz*_ux*(1.0f-_c) - _uy*_s; m[2][1] = _uz*_uy*(1.0f-_c) + _ux*_s; m[2][2] = _c + _uz*_uz*(1.0f-_c); m[2][3] = 0.0f; \ m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = 0.0f; m[3][3] = 1.0f; \ oglMultMatrixf(m); } #define oglTranslatef(_x,_y,_z) { \ float (*m)[4] = ogl_compat_matrix[ ogl_compat_matrix_level[ogl_compat_matrix_mode] ][ ogl_compat_matrix_mode ]; \ m[3][0]+=_x; m[3][1]+=_y; m[3][2]+=_z; } #define oglScalef(_x,_y,_z) { \ float (*m)[4] = ogl_compat_matrix[ ogl_compat_matrix_level[ogl_compat_matrix_mode] ][ ogl_compat_matrix_mode ];\ m[0][3]+=_x; m[1][3]+=_y; m[2][3]+=_z; } #define ogluPerspective(_fovy,_aspect,_zNear,_zFar) { \ float _rad=0.5f*(_fovy)*PI/180.0; \ float _f=cos(_rad) / sin(_rad); \ float _form1 = ((float)(_zFar) + (float)(_zNear)) / ((float)(_zNear) - (float)(_zFar)); \ float _form2 = (2.0f * (float)(_zFar) * (float)(_zNear)) / ((float)(_zNear) - (float)(_zFar)); \ float m[4][4]; \ m[0][0] = (_f) / (_aspect); m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f; \ m[1][0] = 0.0f; m[1][1] = (_f); m[1][2] = 0.0f; m[1][3] = 0.0f; \ m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = (_form1); m[2][3] = -1.0f; \ m[3][0] = 0.0f; m[3][1] = 0.0f; m[3][2] = (_form2); m[3][3] = 0.0f; \ oglMultMatrixf(m); } #define oglOrtho(l,r,b,t,n,f) { \ float _l=(float)l, _r=(float)r, _b=(float)b, _t=(float)t, _n=(float)n, _f=(float)f;\ float _trx=-(_r+_l)/(_r-_l), _try=-(_t+_b)/(_t-_b), _trz=-(_f+_n)/(_f-_n); \ float m[4][4]; \ m[0][0] = 2.0 / (_r-_l); m[0][1] = 0.0f; m[0][2] = 0.0f; m[0][3] = 0.0f; \ m[1][0] = 0.0f; m[1][1] = 2.0 / (_t-_b); m[1][2] = 0.0f; m[1][3] = 0.0f; \ m[2][0] = 0.0f; m[2][1] = 0.0f; m[2][2] = -2.0f / (_f - _n); m[2][3] = 0.0f; \ m[3][0] = _trx; m[3][1] = _try; m[3][2] = _trz; m[3][3] = 1.0f; \ oglMultMatrixf(m); } int CompileGLSLShader(const char *vert, const char *frag) { GLint rt; // return codes GLsizei logLen; char log[4096]; // for error messages // Create Shader And Program Objects int my_program = glCreateProgram(); int my_vertex_shader = glCreateShader(GL_VERTEX_SHADER); int my_fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); // Load Shader Sources glShaderSource(my_vertex_shader, 1, &vert, NULL); glShaderSource(my_fragment_shader, 1, &frag, NULL); // Compile The Shaders glCompileShader(my_vertex_shader); glGetShaderiv(my_vertex_shader, GL_COMPILE_STATUS, &rt); if (!rt) { glGetShaderInfoLog(my_vertex_shader, 4096, &logLen, log); printf("vert log (code %d): %s\n", rt, log); exit(1); } glCompileShader(my_fragment_shader); glGetShaderiv(my_fragment_shader, GL_COMPILE_STATUS, &rt); if (!rt) { glGetShaderInfoLog(my_fragment_shader, 4096, &logLen, log); printf("frag log (code %d): %s\n", rt, log); exit(1); } // Attach The Shader Objects To The Program Object glAttachShader(my_program, my_vertex_shader); glAttachShader(my_program, my_fragment_shader); glBindFragDataLocation(my_program, 0, "fragColour"); // Link The Program Object glLinkProgram(my_program); glGetShaderiv(my_program, GL_LINK_STATUS, &rt); if (!rt) { glGetShaderInfoLog(my_program, 4096, &logLen, log); printf("prog log: (code %d) %s\n", rt, log); exit(0); } // Use The Program Object Instead Of Fixed Function OpenGL glUseProgram(my_program); return my_program; } /* * * * * * * * * * * * * * * * * * * * * * * * Minimal Compatibility Layer * * * * * * * * * * * * * * * * * * * * * * */ GLuint ogl_compat_shader_program; GLuint ogl_compat_position_attribute; GLuint ogl_compat_hasTex_attribute; GLuint ogl_compat_colour_attribute; GLuint ogl_compat_texcoord_attribute; GLuint ogl_compat_texcoord_enabled; GLuint ogl_compat_texUnit; GLuint ogl_compat_modelview_projection; GLuint ogl_compat_vertex_array_object; GLuint ogl_compat_vertex_buffer; int ogl_compat_vertex_array_mode; VertexArrayVert ogl_compat_vertex_array_prev_vert; VertexArray ogl_compat_vertex_array; void oglCompatibilityInit(int maxVerts) { // Initialize the state machine ogl_compat_vertex_array.nVert = 0; ogl_compat_vertex_array.vert = (VertexArrayVert*)malloc( maxVerts * sizeof(VertexArrayVert) ); VertexArrayVert v; v.r=1.0f; v.g=1.0f; v.b=1.0f; v.a=1.0f; v.x=0.0f; v.y=0.0f; v.z=0.0f; v.u=0.0f; v.v=0.0f; v.w=0.0f; ogl_compat_vertex_array_prev_vert = v; // Create the vertex buffers glGenVertexArrays(1, &ogl_compat_vertex_array_object); glBindVertexArray(ogl_compat_vertex_array_object); glGenBuffers(1, &ogl_compat_vertex_buffer); glBindBuffer(GL_ARRAY_BUFFER, ogl_compat_vertex_buffer); // Create the fixed function shader const char *vss="#version 150\n\ uniform mat4 MVP;\n\ in vec4 position;\n\ in vec4 colour;\n\ in vec3 texCoord;\n\ out vec4 colourV;\n\ out vec3 texCoordV;\n\ void main (void) {\n\ vec4 pos = vec4(position.xyz, 1.0f);\n\ colourV = colour;\n\ texCoordV = texCoord;\n\ gl_Position = MVP * pos;\n\ }"; const char *fss="#version 150\n\ uniform int hasTex;\n\ uniform sampler2D texUnit;\n\ in vec4 colourV;\n\ in vec3 texCoordV;\n\ out vec4 fragColour;\n\ void main(void) { \n\ vec4 texColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);\n\ if (hasTex==1) { texColor = texture(texUnit, texCoordV.xy); } \n\ fragColour = colourV * texColor;\n\ }"; ogl_compat_shader_program = CompileGLSLShader(vss, fss); // 5. Get pointers to uniforms and attributes ogl_compat_texcoord_enabled = glGetUniformLocation(ogl_compat_shader_program, "hasTex"); ogl_compat_texUnit = glGetUniformLocation(ogl_compat_shader_program, "texUnit"); ogl_compat_modelview_projection = glGetUniformLocation(ogl_compat_shader_program, "MVP"); ogl_compat_colour_attribute = glGetAttribLocation (ogl_compat_shader_program, "colour"); ogl_compat_texcoord_attribute = glGetAttribLocation (ogl_compat_shader_program, "texCoord"); ogl_compat_position_attribute = glGetAttribLocation (ogl_compat_shader_program, "position"); printf("ogl_compat_texcoord_enabled: %d ogl_compat_texUnit %d ogl_compat_colour_attribute: %d ogl_compat_texcoord_attribute: %d ogl_compat_position_attribute: %d\n", ogl_compat_texcoord_enabled, ogl_compat_texUnit, ogl_compat_colour_attribute, ogl_compat_texcoord_attribute, ogl_compat_position_attribute); } // how many? m/p dims float ogl_compat_matrix[OGL_MAX_MATRIX_PUSH][2][4][4]; // the matrices int ogl_compat_matrix_level[2] = {0, 0}; // how many times have we pushed? int ogl_compat_matrix_mode = OGL_MODELVIEW; //window context functions. id app_oglContext; id app_menubar, app_appMenuItem, app_appMenu, app_appName, app_quitMenuItem, app_quitTitle, app_quitMenuItem, app_window; id app_oglView; NSAutoreleasePool *app_pool; NSDate *app_currDate; int app_sw=-999, app_sh=-999; int app_mouseX=0, app_mouseY=0; char app_mouseDown[3] = {0,0,0}; //------------------------ // ToDo: It may be possible to programmatically use // NSOpenGLView directly, and extract the opengl context // in "main". For the time being, this does the trick. //------------------------ @interface MyOpenGLView : NSOpenGLView @end @implementation MyOpenGLView - (id)initWithFrame:(NSRect)frame { // 1. Create a context with opengl pixel format NSOpenGLPixelFormatAttribute pixelFormatAttributes[] = { NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, NSOpenGLPFAColorSize , 24 , NSOpenGLPFAAlphaSize , 8 , NSOpenGLPFADepthSize , 16 , NSOpenGLPFADoubleBuffer , NSOpenGLPFAAccelerated , NSOpenGLPFANoRecovery , 0 }; NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:pixelFormatAttributes]; self = [super initWithFrame:frame pixelFormat:pixelFormat]; // 2. Make the context current [[self openGLContext] makeCurrentContext]; app_oglContext = [self openGLContext]; return self; } @end static int w, h; void CNFGGetDimensions( short * x, short * y ) { *x = w; *y = h; } static void InternalLinkScreenAndGo( const char * WindowName ) { } void CNFGSetupFullscreen( const char * WindowName, int screen_no ) { CNFGSetup( WindowName, 640, 480 ); } void CNFGTearDown() { } void CNFGSetup( const char * WindowName, int sw, int sh ) { w = sw; h = sh; app_sw=sw; app_sh=sh; printf("CNFGSetup\n"); const char * winName = (WindowName!=NULL) ? WindowName : winName; //---------------------------------- // Create a programmatic Cocoa OpenGL window // This code is slightly modified from // CocoaWithLove's Minimalist Cocoa tutorial //---------------------------------- [NSAutoreleasePool new]; [NSApplication sharedApplication]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; app_menubar = [[NSMenu new] autorelease]; app_appMenuItem = [[NSMenuItem new] autorelease]; [app_menubar addItem:app_appMenuItem]; [NSApp setMainMenu:app_menubar]; app_appMenu = [[NSMenu new] autorelease]; app_appName = [[NSProcessInfo processInfo] processName]; app_quitTitle = [@"Quit " stringByAppendingString:app_appName]; app_quitMenuItem = [[[NSMenuItem alloc] initWithTitle:app_quitTitle action:@selector(terminate:) keyEquivalent:@"q"] autorelease]; [app_appMenu addItem:app_quitMenuItem]; [app_appMenuItem setSubmenu:app_appMenu]; app_window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, sw, sh) styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO] autorelease]; app_oglView = [[[MyOpenGLView alloc] initWithFrame:NSMakeRect(0, 0, sw, sh) ] autorelease]; [app_window setContentView:app_oglView]; [app_window cascadeTopLeftFromPoint:NSMakePoint(20,20)]; [app_window setTitle:app_appName]; [app_window makeKeyAndOrderFront:nil]; [NSApp activateIgnoringOtherApps:YES]; app_pool = [[NSAutoreleasePool alloc] init]; app_currDate = [[NSDate alloc] init]; oglCompatibilityInit(sw*sh); // Initialize the OpenGL compatibility layer //-------------------- // Clear the screen to black //-------------------- [app_pool release]; //[currDate release]; app_pool = [[NSAutoreleasePool alloc] init]; // Peek at the next event app_currDate = [[NSDate alloc] init]; NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:app_currDate inMode:NSEventTrackingRunLoopMode dequeue:YES]; [app_currDate release]; [NSApp updateWindows]; glClearColor(0.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); [app_oglContext flushBuffer]; // Set up a 2D projection //oglMatrixMode(OGL_PROJECTION); // Select The Projection Matrix //oglLoadIdentity(); // Reset The Projection Matrix //oglOrtho(0.0, WIDTH, 0.0, HEIGHT, -10.0, 10.0); //oglMatrixMode(OGL_MODELVIEW); // Select The Modelview Matrix //oglLoadIdentity(); // Reset The Modelview Matrix //glDisable(GL_DEPTH_TEST); } #define XK_Left 0xff51 /* Move left, left arrow */ #define XK_Up 0xff52 /* Move up, up arrow */ #define XK_Right 0xff53 /* Move right, right arrow */ #define XK_Down 0xff54 /* Move down, down arrow */ #define KEY_UNDEFINED 255 #define KEY_LEFT_MOUSE 0 static int keycode(key) { if (key < 256) return key; switch(key) { case 63232: return XK_Up; case 63233: return XK_Down; case 63234: return XK_Left; case 63235: return XK_Right; } return KEY_UNDEFINED; } void CNFGHandleInput() { int i; [app_pool release]; //[currDate release]; app_pool = [[NSAutoreleasePool alloc] init]; //---------------------- // Check for mouse motion (NOTE: the mouse move event // has complex behavior after a mouse click. // we can work around this by checking mouse motion explicitly) //---------------------- NSPoint location = [app_window mouseLocationOutsideOfEventStream]; if ((int)location.x != app_mouseX || (int)location.y != app_mouseY) { app_mouseX = (int)location.x; app_mouseY = (int)location.y; if (app_mouseX >= 0 && app_mouseX < app_sw && app_mouseY >= 0 && app_mouseY < app_sh) { HandleMotion(app_mouseX, app_mouseY, app_mouseDown[0]||app_mouseDown[1]||app_mouseDown[2]); } } //---------------------- // Peek at the next event //---------------------- app_currDate = [[NSDate alloc] init]; NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:app_currDate inMode:NSEventTrackingRunLoopMode dequeue:YES]; [app_currDate release]; // If we have an event, handle it! if (event) { NSEventType type = [event type]; switch (type) { case EVENT_KEY_DOWN: for (i=0; i<[event.characters length]; i++) { unichar ch = [event.characters characterAtIndex: i]; HandleKey(keycode(ch), 1); } break; case EVENT_KEY_UP: for (i=0; i<[event.characters length]; i++) { unichar ch = [event.characters characterAtIndex: i]; HandleKey(keycode(ch), 0); } break; case EVENT_LEFT_MOUSE_DOWN: HandleButton(app_mouseX, app_mouseY, KEY_LEFT_MOUSE, 1); app_mouseDown[0]=1; break; case EVENT_LEFT_MOUSE_UP: HandleButton(app_mouseX, app_mouseY, KEY_LEFT_MOUSE, 0); app_mouseDown[0]=0; break; default: break; } //printf("type %d\n", (int)type); } } void CNFGUpdateScreenWithBitmap( unsigned long * data, int w, int h ) { unsigned char *rgba=data; // printf("data %p w %d h %d sw %d sh %d\n", data, w, h, app_sw, app_sh); // exit(1); /* */ [NSApp updateWindows]; //-------------------- // Draw the scene //-------------------- glClearColor(1.0,0.0,0.0,0.0); glClear(GL_COLOR_BUFFER_BIT); oglMatrixMode(OGL_PROJECTION); // Select The Projection Matrix oglLoadIdentity(); // Reset The Projection Matrix oglOrtho(0.0, app_sw, app_sh-1, -1.0, -10.0, 10.0); oglMatrixMode(OGL_MODELVIEW); // Select The Modelview Matrix oglLoadIdentity(); // Reset The Modelview Matrix int i=0,x,y; oglBegin(GL_POINTS); const float scale = 1.0 / 255; for (y=0; y>24), scale*((data[i]>>16)&0xff), scale*((data[i]>>8)&0xff)); oglColor3f(scale*rgba[4*i+2],scale*rgba[4*i+1],scale*rgba[4*i+0]); oglVertex2f(x,y); i++; } } oglEnd(); // glRasterPos2i(0,0); // glDrawPixels(w,h,GL_RGBA,GL_UNSIGNED_BYTE,(const GLvoid*) data); [app_oglContext flushBuffer]; } #ifndef RASTERIZER uint32_t CNFGColor( uint32_t RGB ) { } void CNFGClearFrame() { } void CNFGSwapBuffers() { } void CNFGTackSegment( short x1, short y1, short x2, short y2 ) { } void CNFGTackPixel( short x1, short y1 ) { } void CNFGTackRectangle( short x1, short y1, short x2, short y2 ) { } void CNFGTackPoly( RDPoint * points, int verts ) { } #endif