Results 1 to 2 of 2

Thread: draw 3D cube

  1. #1
    Junior Member
    Join Date
    Jun 2010
    Posts
    3

    draw 3D cube

    Hye,

    I have encountered serious problem to draw a simple cube. Now I can't understand why the depth buffer doesn't work.
    I probably have a lot of mistakes but where.

    Any clues :
    EAGLView.m
    Code :
    #import "EAGLView.h"
     
    #import "ES1Renderer.h"
    #import "ES2Renderer.h"
     
    @implementation EAGLView
     
    @synthesize animating;
    @dynamic animationFrameInterval;
     
    // You must implement this method
    + (Class)layerClass
    {
        return [CAEAGLLayer class];
    }
     
    //The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
    - (id)initWithCoder:(NSCoder*)coder
    {    
        if ((self = [super initWithCoder:coder]))
        {
            // Get the layer
            CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
     
            eaglLayer.opaque = TRUE;
            eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                            [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];
     
            renderer = [[ES2Renderer alloc] init];
     
            if (!renderer)
            {
                renderer = [[ES1Renderer alloc] init];
     
                if (!renderer)
                {
                    [self release];
                    return nil;
                }
            }
     
            animating = FALSE;
            displayLinkSupported = FALSE;
            animationFrameInterval = 1;
            displayLink = nil;
            animationTimer = nil;
     
    		glEnable(GL_DEPTH_TEST);
    		glDepthFunc(GL_LESS);
            // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer
            // class is used as fallback when it isn't available.
            NSString *reqSysVer = @"3.1";
            NSString *currSysVer = [[UIDevice currentDevice] systemVersion];
            if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending)
                displayLinkSupported = TRUE;
        }
     
        return self;
    }
     
    - (void)drawView:(id)sender
    {
        [renderer render];
    }
     
    - (void)layoutSubviews
    {
        [renderer resizeFromLayer:(CAEAGLLayer*)self.layer];
        [self drawView:nil];
    }
     
    - (NSInteger)animationFrameInterval
    {
        return animationFrameInterval;
    }
     
    - (void)setAnimationFrameInterval:(NSInteger)frameInterval
    {
        // Frame interval defines how many display frames must pass between each time the
        // display link fires. The display link will only fire 30 times a second when the
        // frame internal is two on a display that refreshes 60 times a second. The default
        // frame interval setting of one will fire 60 times a second when the display refreshes
        // at 60 times a second. A frame interval setting of less than one results in undefined
        // behavior.
        if (frameInterval >= 1)
        {
            animationFrameInterval = frameInterval;
     
            if (animating)
            {
                [self stopAnimation];
                [self startAnimation];
            }
        }
    }
     
    - (void)startAnimation
    {
        if (!animating)
        {
            if (displayLinkSupported)
            {
                // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed
                // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will
                // not be called in system versions earlier than 3.1.
     
                displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)];
                [displayLink setFrameInterval:animationFrameInterval];
                [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
            }
            else
                animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0 / 60.0) * animationFrameInterval) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE];
     
            animating = TRUE;
        }
    }
     
    - (void)stopAnimation
    {
        if (animating)
        {
            if (displayLinkSupported)
            {
                [displayLink invalidate];
                displayLink = nil;
            }
            else
            {
                [animationTimer invalidate];
                animationTimer = nil;
            }
     
            animating = FALSE;
        }
    }
     
    - (void)dealloc
    {
        [renderer release];
     
        [super dealloc];
    }
     
    @end

    ES2Rendered.m
    Code :
     
    #import "ES2Renderer.h"
    #define USE_DEPTH_BUFFER 1
     
    @implementation ES2Renderer
     
    // Create an OpenGL ES 2.0 context
    - (id)init
    {
        if ((self = [super init]))
        {
            context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
     
            if (!context || ![EAGLContext setCurrentContext:context]/* || ![self loadShaders]*/)
            {
                [self release];
                return nil;
            }
     
     
    		if (USE_DEPTH_BUFFER) {
    			glGenRenderbuffers(1, &depthRenderbuffer);
    			glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer);
    			glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, backingWidth, backingHeight);
    			glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer);
    		}
     
            // Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
            glGenFramebuffers(1, &defaultFramebuffer);
            glGenRenderbuffers(1, &colorRenderbuffer);
            glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
            glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer);
     
    		mainScene = [[Scene alloc] init];
    		[mainScene addCube:[[Cube alloc]initWithDim:big atX:0.0f andY:0.0f andZ:0.0f]];
        }
     
        return self;
    }
     
    - (void)render{
    	[mainScene update];
        // Replace the implementation of this method to do your own custom drawing
     
     
        // This application only creates a single context which is already set current at this point.
        // This call is redundant, but needed if dealing with multiple contexts.
        [EAGLContext setCurrentContext:context];
     
        // This application only creates a single default framebuffer which is already bound at this point.
        // This call is redundant, but needed if dealing with multiple framebuffers.
        glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
        glViewport(0, 0, backingWidth, backingHeight);
     
    	/*************** Debut du nouveau code ******************/
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     
     
    	glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
     
        // Validate program before drawing. This is a good check, but only really necessary in a debug build.
        // DEBUG macro must be defined in your debug configurations if that's not already the case
    	[mainScene render];
     
        // This application only creates a single color renderbuffer which is already bound at this point.
        // This call is redundant, but needed if dealing with multiple renderbuffers.
        glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
        [context presentRenderbuffer:GL_RENDERBUFFER];
    }
     
    - (BOOL)resizeFromLayer:(CAEAGLLayer *)layer{
        // Allocate color buffer backing based on the current layer size
        glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
        [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:layer];
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
        glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &backingHeight);
     
        if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
        {
            NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
            return NO;
        }
     
        return YES;
    }
     
    - (void)dealloc
    {
        // Tear down GL
        if (defaultFramebuffer){
            glDeleteFramebuffers(1, &defaultFramebuffer);
            defaultFramebuffer = 0;
        }
     
        if (colorRenderbuffer){
            glDeleteRenderbuffers(1, &colorRenderbuffer);
            colorRenderbuffer = 0;
        }
     
        if (program){
            glDeleteProgram(program);
            program = 0;
        }
     
    	if(depthRenderbuffer) {
            glDeleteRenderbuffers(1, &depthRenderbuffer);
            depthRenderbuffer = 0;
        }
     
        // Tear down context
        if ([EAGLContext currentContext] == context)
            [EAGLContext setCurrentContext:nil];
     
        [context release];
        context = nil;
     
    	[mainScene release];
    	mainScene = nil;
        [super dealloc];
    }
     
    @end

    Cube.m
    Code :
     
     
    #import "Cube.h"
     
     
    @implementation Cube
     
    const GLfloat cubeVertices[] = {
    	// face de devant
    	-0.5, 0.5, 0.5,            
    	-0.5, -0.5, 0.5,          
    	0.5, -0.5, 0.5,            
    	0.5, 0.5, 0.5,             
     
    	// haut
    	-0.5, 0.5, -0.5,          
    	-0.5, 0.5, 0.5,            
    	0.5, 0.5, 0.5,             
    	0.5, 0.5, -0.5,            
     
    	// arrière
    	0.5, 0.5, -0.5,        
    	0.5, -0.5, -0.5,          
    	-0.5, -0.5, -0.5,          
    	-0.5, 0.5, -0.5,           
     
    	// dessous
    	-0.5, -0.5, 0.5,
    	-0.5, -0.5, -0.5,
    	0.5, -0.5, -0.5,
    	0.5, -0.5, 0.5,
     
    	// gauche
    	-0.5, 0.5, -0.5,
    	-0.5, 0.5, 0.5,
    	-0.5, -0.5, 0.5,
    	-0.5, -0.5, -0.5,
     
    	// droit
    	0.5, 0.5, 0.5,
    	0.5, 0.5, -0.5,
    	0.5, -0.5, -0.5,
    	0.5, -0.5, 0.5
    }; 
     
    static const GLubyte squareColors[] = {
    	0, 0, 204, 255,
    	0, 204, 0, 255,
    	204, 0, 0, 255,
    	204, 0, 204, 255,
    	0, 0, 204, 255,
    	0, 204, 0, 255,
    	204, 0, 0, 255,
    	204, 0, 204, 255,
    	0, 0, 204, 255,
    	0, 204, 0, 255,
    	204, 0, 0, 255,
    	204, 0, 204, 255,
    	0, 0, 204, 255,
    	0, 204, 0, 255,
    	204, 0, 0, 255,
    	204, 0, 204, 255,
    	0, 0, 204, 255,
    	0, 204, 0, 255,
    	204, 0, 0, 255,
    	204, 0, 204, 255,
    	0, 0, 204, 255,
    	0, 204, 0, 255,
    	204, 0, 0, 255,
    	204, 0, 204, 255,
    };
     
    -(id)initWithDim:(cubeCategory)cat atX:(CGFloat)_x andY:(CGFloat)_y andZ:(CGFloat)_z{
    	if(self = [super initAtX:_x andY:_y andZ:_z]){
    		cubeType = cat;
    		s_loader = [[ShaderLoader alloc] init];
    		[s_loader setProgramShader:@"rotationShader"];
    		if((s_loader != nil) && ([s_loader getProgramIdentifier] != 0)){
    			attribPositionOnShader = glGetAttribLocation([s_loader getProgramIdentifier], "position");
    			attribColorOnShader = glGetAttribLocation([s_loader getProgramIdentifier], "color");
    			uniformTranslateOnShader = glGetUniformLocation([s_loader getProgramIdentifier], "translate");
    			projMatOnShader = glGetUniformLocation([s_loader getProgramIdentifier], "orthoMat");
    		}
    	}
     
    	return self;
    }
     
    -(void)render{
     
    	Mat4x4 proj;
    	Mat4x4::setOrtho(proj, -2.0f, 2.0f, -3.0f, 3.0f, -2.0f, 2.0f);
     
    	r_angle += 0.02f;
     
    	Mat4x4 rot;
    	rot.rotY(r_angle);
    	Mat4x4 mvp = rot * proj;
     
     
    	//Matrix4x4 mvp;
    	//Matrix4x4Utils::Mul(mvp, rot, proj);
     
    	glUseProgram([s_loader getProgramIdentifier]);
    	glUniform1f(uniformTranslateOnShader, (GLfloat)center->getY());
    	glVertexAttribPointer(attribPositionOnShader, 3, GL_FLOAT, 0, 0, cubeVertices);
    	glEnableVertexAttribArray(attribPositionOnShader);
    	glVertexAttribPointer(attribColorOnShader, 4, GL_UNSIGNED_BYTE, 1, 0, squareColors);
    	glEnableVertexAttribArray(attribColorOnShader);
    	glUniformMatrix4fv(projMatOnShader, 16, GL_FALSE, mvp.toArray()/*proj.toArray()*/);
     
    	glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
    	glDrawArrays(GL_TRIANGLE_FAN, 4, 4);
    	glDrawArrays(GL_TRIANGLE_FAN, 8, 4);
    	glDrawArrays(GL_TRIANGLE_FAN, 12, 4);
    	glDrawArrays(GL_TRIANGLE_FAN, 16, 4);
    	glDrawArrays(GL_TRIANGLE_FAN, 20, 4);
    	glDrawArrays(GL_TRIANGLE_FAN, 24, 4);
     
    	glUseProgram(0);
     
    }
     
    -(void)update{
    }
     
    -(void)dealloc{
    	[s_loader release];
    	[super dealloc];
    }
     
    @end




    I have to say that the difference between openGL ES1.0 and openGL ES 2.0 was a little confusing for me ...
    Thanks for any help

  2. #2
    Junior Member
    Join Date
    Jun 2010
    Posts
    3

    Re: draw 3D cube

    I find the solution for the weird shape: it's was due to matrix multiplication however I have always a depth buffer problem

Similar Threads

  1. about draw a cube with diffeient matrix
    By freesui1984 in forum OpenGL ES general technical discussions
    Replies: 1
    Last Post: 07-31-2008, 02:12 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •