0
我使用攪拌器創建了一個簡單的3D立方體對象,並使用Jeff Lamarche的攪拌器導出將其存儲在頭文件中,並將其添加到我的項目中。但是我無法渲染它。如何使用OpenGL ES爲iPhone開發渲染3D對象(頂點和法線存儲在頭文件中)?
頭文件:
//If not using MC3D, change 1 to 0 to add needed types
#if 0
#import "MC3DTypes.h"
#else
struct texCoord
{
GLfloat u;
GLfloat v;
};
typedef struct texCoord texCoord;
typedef texCoord* texCoordPtr;
typedef struct vec2 vec2;
typedef vec2* vec2Ptr;
struct vec3
{
GLfloat x;
GLfloat y;
GLfloat z;
};
typedef struct vec3 vec3;
typedef vec3* vec3Ptr;
struct vec4
{
GLfloat x;
GLfloat y;
GLfloat z;
GLfloat w;
};
typedef struct vec4 vec4;
typedef vec4* vec4Ptr;
#endif
struct vertexData
{
vec3 vertex;
vec3 normal;
};
typedef struct vertexData vertexData;
typedef vertexData* vertexDataPtr;
static const vertexData MeshVertexData[] = {
{/*v:*/{1.000000, -1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, -0.577349} },
{/*v:*/{1.000000, -1.000000, 1.000000}, /*n:*/{0.577349, -0.577349, -0.577349} },
{/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
{/*v:*/{1.000000, 1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, 0.577349} },
{/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
{/*v:*/{0.999999, 1.000000, 1.000001}, /*n:*/{0.577349, -0.577349, 0.577349} },
{/*v:*/{1.000000, -1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, -0.577349} },
{/*v:*/{1.000000, 1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, 0.577349} },
{/*v:*/{1.000000, -1.000000, 1.000000}, /*n:*/{0.577349, -0.577349, -0.577349} },
{/*v:*/{1.000000, -1.000000, 1.000000}, /*n:*/{0.577349, -0.577349, -0.577349} },
{/*v:*/{0.999999, 1.000000, 1.000001}, /*n:*/{0.577349, -0.577349, 0.577349} },
{/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
{/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
{/*v:*/{-1.000000, 1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, 0.577349} },
{/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
{/*v:*/{1.000000, 1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, 0.577349} },
{/*v:*/{1.000000, -1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, -0.577349} },
{/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
{/*v:*/{-1.000000, -1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, -0.577349} },
{/*v:*/{1.000000, -1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, -0.577349} },
{/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
{/*v:*/{1.000000, 1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, 0.577349} },
{/*v:*/{0.999999, 1.000000, 1.000001}, /*n:*/{0.577349, -0.577349, 0.577349} },
{/*v:*/{1.000000, -1.000000, 1.000000}, /*n:*/{0.577349, -0.577349, -0.577349} },
{/*v:*/{1.000000, -1.000000, -1.000000}, /*n:*/{0.577349, 0.577349, -0.577349} },
{/*v:*/{-1.000000, -1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, -0.577349} },
{/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
{/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
{/*v:*/{-1.000000, 1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, 0.577349} },
{/*v:*/{0.999999, 1.000000, 1.000001}, /*n:*/{0.577349, -0.577349, 0.577349} },
{/*v:*/{-1.000000, -1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, -0.577349} },
{/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
{/*v:*/{-1.000000, 1.000000, -1.000000}, /*n:*/{-0.577349, 0.577349, 0.577349} },
{/*v:*/{0.999999, 1.000000, 1.000001}, /*n:*/{0.577349, -0.577349, 0.577349} },
{/*v:*/{-1.000000, 1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, 0.577349} },
{/*v:*/{-1.000000, -1.000000, 1.000000}, /*n:*/{-0.577349, -0.577349, -0.577349} },
};
// Example OpenGL ES 1.1 Drawing Code:
// glEnableClientState(GL_VERTEX_ARRAY);
// glEnableClientState(GL_NORMAL_ARRAY);
// glVertexPointer(3, GL_FLOAT, sizeof(VertexData3D), &MeshVertexData[0].vertex);
// glNormalPointer(GL_FLOAT, sizeof(VertexData3D), &MeshVertexData[0].normal);
// glDrawArrays(GL_TRIANGLES, 0, kMeshNumberOfVertices);
// glDisableClientState(GL_VERTEX_ARRAY);
// glDisableClientState(GL_NORMAL_ARRAY);
這裏是我使用的代碼:
//
// ES1Renderer.m
// glTestingGround
//
// Created by David Jacobs on 3/8/10.
// Copyright Stanford University 2010. All rights reserved.
//
#import "ES1Renderer.h"
#import "banana.h"
#import "PVRTexture.h"
#import "cubefr.h"
#define BUFFER_OFFSET(x)((char *)NULL+(x))
@implementation ES1Renderer
// Create an ES 1.1 context
- (id) init
{
if (self = [super init])
{
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
if (!context || ![EAGLContext setCurrentContext:context])
{
[self release];
return nil;
}
// Create default framebuffer object. The backing will be allocated for the current layer in -resizeFromLayer
glGenFramebuffersOES(1, &defaultFramebuffer);
glGenRenderbuffersOES(1, &colorRenderbuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, colorRenderbuffer);
glEnable(GL_CULL_FACE);
glEnable(GL_CCW);
// ###################### Texture Demo #################################
/*NSString * path = [[NSBundle mainBundle] pathForResource: @"banana" ofType:@"pvrtc"];
texture = [[PVRTexture alloc] initWithContentsOfFile:path];
glBindTexture(GL_TEXTURE_2D, texture.name);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);*/
// #####################################################################
}
return self;
}
- (void) render
{
// 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.
glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer);
//obj2opengl.pl banana.obj
//To include the converted object all you have to do is
// include generated arrays
// ---------------------------------------------------------------
// Determines the Normalized Device Coordinate -> Window Coordinate Transform
// ---------------------------------------------------------------
glViewport(0, 0, backingWidth, backingHeight);
// ---------------------------------------------------------------
// Determines the Eye Coordinate -> Clip Coordinate Transform
// ---------------------------------------------------------------
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustumf(-2, 2, -3, 3, 5, 20);
// ---------------------------------------------------------------
// Determines the Object Coordinate -> Eye Coordinate Transform
// ---------------------------------------------------------------
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0, 0, -8);
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// ####################### Geometry Demo #########################
/*
#define TETRA_FRONT 0.0, 0.0, 1.0
#define TETRA_RIGHT 0.943, 0.0, -0.333
#define TETRA_TOP -0.471, 0.816, -0.333
#define TETRA_LEFT -0.471, -0.816, -0.333
#define v1 1.000000, -1.000000, -1.000000
#define v2 1.000000, -1.000000, 1.000000
#define v3 -1.000000, -1.000000, 1.000000
#define v4 -1.000000, -1.000000, -1.000000
#define v5 1.000000, 1.000000, -1.000000
#define v6 0.999999, 1.000000, 1.000001
#define v7 -1.000000, 1.000000, 1.000000
#define v8 -1.000000, 1.000000, -1.000000
static const GLfloat tetraVertices[] = {
TETRA_TOP,
TETRA_RIGHT,
TETRA_LEFT,
TETRA_FRONT,
TETRA_TOP,
TETRA_RIGHT,
};
static const GLfloat newVertices[] = {
v1,
v2,
v3,
v4,
v5,
v6,
v7,
v8
};
#define RED 255, 0, 0,255
#define GREEN 0,255, 0,255
#define BLUE 0, 0,255,255
#define YELLOW 255,255, 0,255
static const GLubyte tetraColors[] = {
RED,
GREEN,
BLUE,
YELLOW,
RED,
GREEN,
};
static const GLubyte newColors[] = {
RED,
RED,
RED,
RED,
RED,
RED,
RED,
RED
};
static float t = 0.0;
t += 1/30.f;
//glVertexPointer(3, GL_FLOAT, 0, tetraVertices);
glVertexPointer(3, GL_FLOAT, 0, newVertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, newColors);
//glColorPointer(4, GL_UNSIGNED_BYTE,0, tetraColors);
glEnableClientState(GL_COLOR_ARRAY);
glPushMatrix();
glTranslatef(0, 0, -3);
glRotatef(30*t, 0, 1, 0);
glScalef(3, 3, 3);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
glPopMatrix();
glPushMatrix();
glTranslatef(2, 2, 0);
glRotatef(-30*t, 1, 0, 0);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
glPopMatrix();
glPushMatrix();
glTranslatef(2, -2, 0);
glRotatef(-60*t, 1, 0, 1);
glScalef(2, 2, 2);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
glPopMatrix();
*/
//glDisableClientState(GL_VERTEX_ARRAY);
//glDisableClientState(GL_NORMAL_ARRAY);
// set input data to arrays
//glVertexPointer(3, GL_FLOAT, 0, MeshVertexData);
//glEnableClientState(GL_VERTEX_ARRAY);
//glNormalPointer(GL_FLOAT, 0,indexes);
//glEnableClientState(GL_NORMAL_ARRAY);
//glTexCoordPointer(2, GL_FLOAT, 0, bananaTexCoords);
//glEnableClientState(GL_TEXTURE_COORD_ARRAY);
//glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(MeshVertexData), &MeshVertexData[0].vertex);
glNormalPointer(GL_FLOAT, sizeof(MeshVertexData), &MeshVertexData[0].normal);
//glTexCoordPointer(2, GL_FLOAT, sizeof(TexturedVertexData3D), &VertexData[0].texCoord);
static float t = 0.0;
t += 1/30.f;
glPushMatrix();
glTranslatef(0, 0, 0);
glRotatef(30*t, 0, 1, 0);
glScalef(1, 1, 1);
//glDrawArrays(GL_TRIANGLES, 0, vertex_count);
glDrawArrays(GL_TRIANGLES, 0, sizeof(&MeshVertexData[0].vertex));
glPopMatrix();
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glLoadIdentity();
//glDisableClientState(GL_TEXTURE_COORD_ARRAY);
//glDisable(GL_TEXTURE_2D);
// ###############################################################
// Enable lighting
// 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.
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
- (BOOL) resizeFromLayer:(CAEAGLLayer *)layer
{
// Allocate color buffer backing based on the current layer size
glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer);
[context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:layer];
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
{
NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
return YES;
}
- (void) dealloc
{
// Tear down GL
if (defaultFramebuffer)
{
glDeleteFramebuffersOES(1, &defaultFramebuffer);
defaultFramebuffer = 0;
}
if (colorRenderbuffer)
{
glDeleteRenderbuffersOES(1, &colorRenderbuffer);
colorRenderbuffer = 0;
}
// Tear down context
if ([EAGLContext currentContext] == context)
[EAGLContext setCurrentContext:nil];
[context release];
context = nil;
[super dealloc];
}
@end
任何幫助是極大的讚賞。還有關於OpenGL ES的任何教程都會很棒。 在此先感謝