[Vm-dev] [commit] r2308 - iOS add openGL render that uses sub rectangles

commits at squeakvm.org commits at squeakvm.org
Tue Sep 14 02:30:48 UTC 2010


Author: johnmci
Date: 2010-09-13 19:30:48 -0700 (Mon, 13 Sep 2010)
New Revision: 2308

Added:
   trunk/platforms/iOS/vm/iPhone/Classes/SqueakUIViewOpenGLAlternate.m
Log:
iOS add openGL render that uses sub rectangles

Added: trunk/platforms/iOS/vm/iPhone/Classes/SqueakUIViewOpenGLAlternate.m
===================================================================
--- trunk/platforms/iOS/vm/iPhone/Classes/SqueakUIViewOpenGLAlternate.m	                        (rev 0)
+++ trunk/platforms/iOS/vm/iPhone/Classes/SqueakUIViewOpenGLAlternate.m	2010-09-14 02:30:48 UTC (rev 2308)
@@ -0,0 +1,206 @@
+//
+//  SqueakUIViewOpenGL.m
+//  SqueakPureObjc
+//
+//  Created by John M McIntosh on 10-09-09.
+//  Copyright 2010 Corporate Smalltalk Consulting Ltd. All rights reserved.
+/*
+ Copyright (c) 2008 Corporate Smalltalk Consulting Ltd. All rights reserved.
+ MIT License
+ Permission is hereby granted, free of charge, to any person
+ obtaining a copy of this software and associated documentation
+ files (the "Software"), to deal in the Software without
+ restriction, including without limitation the rights to use,
+ copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the
+ Software is furnished to do so, subject to the following
+ conditions:
+ 
+ The above copyright notice and this permission notice shall be
+ included in all copies or substantial portions of the Software.
+ 
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ OTHER DEALINGS IN THE SOFTWARE.
+ 
+ The end-user documentation included with the redistribution, if any, must include the following acknowledgment: 
+ "This product includes software developed by Corporate Smalltalk Consulting Ltd (http://www.smalltalkconsulting.com) 
+ and its contributors", in the same place and form as other third-party acknowledgments. 
+ Alternately, this acknowledgment may appear in the software itself, in the same form and location as other 
+ such third-party acknowledgments.
+ */
+//
+
+#import "SqueakUIViewOpenGL.h"
+#import "sq.h"
+
+// A class extension to declare private methods
+ at interface SqueakUIViewOpenGL ()
+ at property (nonatomic, retain) EAGLContext *context;
+ at end
+
+const GLfloat spriteTexcoords[] = {
+	0.0f, 1.0f,
+	1.0f, 1.0f,
+	0.0f, 0.0f,
+	1.0f, 0.0f,
+};
+
+ at implementation SqueakUIViewOpenGL
+ at synthesize context;
+
++ (Class)layerClass {
+    return [CAEAGLLayer class];
+}
+
+- (id)initWithFrame:(CGRect) aFrame {
+	self = [super initWithFrame: aFrame];
+	clippyIsEmpty = YES;
+	syncNeeded = NO;
+
+	// Get the layer
+	CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
+	eaglLayer.opaque = YES;
+	eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
+									[NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking,
+									kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
+									nil];
+	
+	//other choice is kEAGLColorFormatRGB565
+	
+	context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];        
+	if (!context || ![EAGLContext setCurrentContext:context]) {
+		[self release];
+		return nil;
+	}
+
+	[self setupOpenGL];
+	return self;
+}
+
+-(void)setupOpenGL {	
+	// Create system framebuffer object. The backing will be allocated in -reshapeFramebuffer
+	
+	glGenFramebuffersOES(1, &viewFramebuffer);glCheckError();
+	glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);glCheckError();
+	glGenRenderbuffersOES(1, &viewRenderbuffer);glCheckError();
+	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);glCheckError();
+	glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer);glCheckError();
+}
+
+-(GLuint)createTextuerUsingWidth:(GLuint)w Height:(GLuint)h
+{
+	GLuint handle;
+
+	glGenTextures(1, &handle);glCheckError();
+	glBindTexture(GL_TEXTURE_2D, handle);glCheckError();
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glCheckError();
+	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glCheckError();
+	
+	// http://www.khronos.org/registry/gles/extensions/APPLE/APPLE_texture_2D_limited_npot.txt
+		
+	glDisable(GL_DEPTH_TEST);glCheckError();
+	glDisableClientState(GL_COLOR_ARRAY);glCheckError();
+	glEnable(GL_TEXTURE_2D);glCheckError();
+	glEnableClientState(GL_VERTEX_ARRAY);glCheckError();
+	glEnableClientState(GL_TEXTURE_COORD_ARRAY);glCheckError();
+
+	return handle;
+}
+
+- (void)dealloc {        
+    if ([EAGLContext currentContext] == context)
+        [EAGLContext setCurrentContext:nil];
+    
+    self.context = nil;
+    [super dealloc];
+}
+
+- (void)layoutSubviews {
+    // Allocate GL color buffer backing, matching the current layer size
+	[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer*)self.layer]; glCheckError();
+	glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);glCheckError();
+    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);glCheckError();
+	rt_assert(GL_FRAMEBUFFER_COMPLETE_OES == glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
+	if (textureId) {
+		glDeleteTextures(1,&textureId);
+		textureId = 0;
+	}
+}
+
+- (void) drawImageUsingClip: (CGRect) clip {
+	if (clippyIsEmpty){
+		clippy = clip;
+		clippyIsEmpty = NO;
+	} else {
+		clippy = CGRectUnion(clippy, clip);
+	}
+	syncNeeded = YES;
+}
+
+- (void) drawThelayers {
+	if (syncNeeded) { 
+		[self drawRect: clippy];
+		syncNeeded = NO;
+		clippyIsEmpty = YES;
+//		glFlush();
+		[EAGLContext setCurrentContext:context];
+		[context presentRenderbuffer:GL_RENDERBUFFER_OES];
+	}
+}
+
+- (void)loadTexturesFrom: (void*) lastBitsIndex subRectangle: (CGRect) subRectSqueak { 
+	CGRect subRect = subRectSqueak;
+	NSUInteger imageWidth = (NSUInteger)self.bounds.size.width*4;
+	GLfloat spriteVertices[] =  {
+		0.0f,0.0f,   
+		subRect.size.width,0.0f,   
+		0.0f,subRect.size.height, 
+		subRect.size.width,subRect.size.height};
+
+	subRect.origin.y = self.bounds.size.height-subRectSqueak.origin.y-subRectSqueak.size.height;
+	void *span = lastBitsIndex+(NSUInteger)subRect.origin.y*imageWidth + (NSUInteger)subRect.origin.x* 4;
+	
+	if (!textureId) {
+		textureId = [self createTextuerUsingWidth: backingWidth Height: backingHeight];
+	} else {
+		glBindTexture(GL_TEXTURE_2D, textureId);glCheckError();
+	}
+	
+	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (GLsizei)subRect.size.width, (GLsizei)subRect.size.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);glCheckError();
+	for( GLint y = 0; y < (GLint) subRect.size.height; y++ ) {
+		 void *row =  imageWidth*y + span;
+		 glTexSubImage2D( GL_TEXTURE_2D, 0, 0, y, 
+						 (GLsizei)subRect.size.width, 1, GL_BGRA, GL_UNSIGNED_BYTE, row );glCheckError();
+	 }
+		
+    glViewport( subRect.origin.x, subRectSqueak.origin.y, subRect.size.width, subRect.size.height);glCheckError();	
+	glMatrixMode(GL_PROJECTION);glCheckError();
+	glLoadIdentity();glCheckError();
+    glMatrixMode(GL_MODELVIEW);glCheckError();
+    glLoadIdentity();glCheckError();
+	glVertexPointer(2, GL_FLOAT, 0, spriteVertices);glCheckError();
+	glTexCoordPointer(2, GL_FLOAT, 0, spriteTexcoords);	glCheckError();
+	glOrthof(0, (GLfloat) subRect.size.width, 0, (GLfloat) subRect.size.height, 0, 1);glCheckError();
+	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);glCheckError();
+}
+
+
+-(void)drawRect:(CGRect)rect {
+	//	NSLog(@" drawRect %f %f %f %f",rect.origin.x,rect.origin.y,rect.size.width,rect.size.height);
+	sqInt formObj = interpreterProxy->displayObject();
+	sqInt formPtrOop = interpreterProxy->fetchPointerofObject(0, formObj);	
+	void* dispBitsIndex = interpreterProxy->firstIndexableField(formPtrOop);
+    if ( dispBitsIndex ) {
+		[self loadTexturesFrom:dispBitsIndex subRectangle: rect];
+	}
+}
+
+ at end
\ No newline at end of file



More information about the Vm-dev mailing list