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


#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



#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




#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

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

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.