#import "ViewController.h"
#import "sphere.h"
typedef struct {
GLKVector3 position;
GLKVector3 normal;
GLKVector4 color;
}SceneVertex;
SceneVertex vertex[3888];
@interface ViewController ()
@property(nonatomic,assign)GLuint program;
@property(nonatomic,assign)GLint modelMat;
@property(nonatomic,assign)GLint viewMat;
@property(nonatomic,assign)GLint projectionMat;
@property(nonatomic,assign)GLint tex;
@property(nonatomic,assign)GLint color;
@end
@implementation ViewController
{
GLKMatrix4 modelMatrix;
GLKMatrix4 viewMatrix;
GLKMatrix4 projectionMatrix;
GLuint earth;
GLuint moon;
GLuint tx[2];
GLKMatrix4 moonMatrix;
GLfloat moonDepth;
}
-
(void)viewDidLoad {
[super viewDidLoad];
//初始化绘图上下文
moonDepth = 0.0f;
GLKView *view = (GLKView *)self.view;
view.context = [[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:view.context];
view.drawableDepthFormat = GLKViewDrawableDepthFormat16;
//初始化绘图上下文
for (int i=0; i<1944; i++) {
vertex[i].position.x = sphereVerts[3*i];
vertex[i].position.y = sphereVerts[3*i+1];
vertex[i].position.z = sphereVerts[3*i+2];
vertex[i].color = GLKVector4Make(1, 1, 1, 1);
vertex[i].normal.x = sphereNormals[3*i];
vertex[i].normal.y = sphereNormals[3*i+1];
vertex[i].normal.z = sphereNormals[3*i+2];
}for (int i=0; i<1944; i++) {
vertex[i+1944].position.x = sphereVerts[3*i]+0.3;
vertex[i+1944].position.y = sphereVerts[3*i+1];
vertex[i+1944].position.z = sphereVerts[3*i+2];
vertex[i+1944].normal.x = sphereNormals[3*i];
vertex[i+1944].normal.y = sphereNormals[3*i+1];
vertex[i+1944].normal.z = sphereNormals[3*i+2];
vertex[i+1944].color = GLKVector4Make(1, 0.5, 1, 1);
}glEnable(GL_CULL_FACE|GL_DEPTH_TEST);
glClearColor(0, 0, 0, 1);
glGenBuffers(1, &earth);
glBindBuffer(GL_ARRAY_BUFFER, earth);
ssize_t number = sizeof(vertex) / sizeof(SceneVertex);NSLog(@"%li",number);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL);glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, 0, sizeof(SceneVertex), NULL+offsetof(SceneVertex, color));glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL+offsetof(SceneVertex, normal));
glBindBuffer(GL_ARRAY_BUFFER, 0);[self loadShaders];
modelMatrix = GLKMatrix4Identity;
viewMatrix = GLKMatrix4Identity;
projectionMatrix = GLKMatrix4Identity;
moonMatrix = GLKMatrix4Identity;
viewMatrix = GLKMatrix4MakeLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
projectionMatrix = GLKMatrix4MakeFrustum(-1, 1, -1, 1, 8, 1000);
}
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect{
float aspect = (GLfloat)view.drawableWidth / (GLfloat)view.drawableHeight;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, earth);
glUseProgram(_program);
modelMatrix = GLKMatrix4MakeScale(1, aspect, 1);
glUniformMatrix4fv(_modelMat, 1, 0, modelMatrix.m);
glUniformMatrix4fv(_viewMat, 1, 0, viewMatrix.m);
glUniformMatrix4fv(_projectionMat, 1, 0, projectionMatrix.m);
moonMatrix = GLKMatrix4MakeScale(1, aspect, 1);
moonMatrix = GLKMatrix4Translate(moonMatrix, 0.5, 0, moonDepth);
glUniformMatrix4fv(_modelMat, 1, 0, moonMatrix.m);
glDrawArrays(GL_TRIANGLES, 1944, 1944);
glDrawArrays(GL_TRIANGLES, 0, 1944);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
(IBAction)changeEyePosition:(id)sender {
static float i = 0.1;
viewMatrix = GLKMatrix4MakeLookAt(0, 0, 10-i, 0, 0, 0, 0, 1, 0);
i+=0.1;
}(IBAction)changeDistance:(id)sender {
moonDepth += 0.1;
// NSLog(@"%f",moonDepth);
for (int i=0; i<1944; i++) {
vertex[i+1944].position.x = sphereVerts[3*i]+0.1;
vertex[i+1944].position.y = sphereVerts[3*i+1];
vertex[i+1944].position.z = sphereVerts[3*i+2]+moonDepth;
vertex[i+1944].normal.x = sphereNormals[3*i];
vertex[i+1944].normal.y = sphereNormals[3*i+1];
vertex[i+1944].normal.z = sphereNormals[3*i+2];
vertex[i+1944].color = GLKVector4Make(1, 0.5, 1, 1);
}
}(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}-
(BOOL)loadShaders
{
GLuint vertShader, fragShader;
NSString *vertShaderPathname, *fragShaderPathname;// Create shader program.
_program = glCreateProgram();// Create and compile vertex shader.
vertShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"vsh"];
if (![self compileShader:&vertShader type:GL_VERTEX_SHADER file:vertShaderPathname]) {
NSLog(@"Failed to compile vertex shader");
return NO;
}// Create and compile fragment shader.
fragShaderPathname = [[NSBundle mainBundle] pathForResource:@"Shader" ofType:@"fsh"];
if (![self compileShader:&fragShader type:GL_FRAGMENT_SHADER file:fragShaderPathname]) {
NSLog(@"Failed to compile fragment shader");
return NO;
}// Attach vertex shader to program.
glAttachShader(_program, vertShader);// Attach fragment shader to program.
glAttachShader(_program, fragShader);// Bind attribute locations.
// This needs to be done prior to linking.
glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
glBindAttribLocation(_program, GLKVertexAttribNormal, "normal");
glBindAttribLocation(_program, GLKVertexAttribColor, "color");if (![self linkProgram:_program]) {
NSLog(@"Failed to link program: %d", _program);if (vertShader) { glDeleteShader(vertShader); vertShader = 0; } if (fragShader) { glDeleteShader(fragShader); fragShader = 0; } if (_program) { glDeleteProgram(_program); _program = 0; } return NO;
}
//modelMatrix = glGetUniformLocation(_program, "modelMatrix");
_modelMat = glGetUniformLocation(_program, "modelMatrix");
_viewMat = glGetUniformLocation(_program, "viewMatrix");
_projectionMat = glGetUniformLocation(_program, "projectionMatrix");
// _color = glGetUniformLocation(_program, "color");
// Release vertex and fragment shaders.
if (vertShader) {
glDetachShader(_program, vertShader);
glDeleteShader(vertShader);
}if (fragShader) {
glDetachShader(_program, fragShader);
glDeleteShader(fragShader);
}return YES;
} -
(BOOL)compileShader:(GLuint *)shader type:(GLenum)type file:(NSString *)file
{
GLint status;
const GLchar *source;source = (GLchar *)[[NSString stringWithContentsOfFile:file encoding:NSUTF8StringEncoding error:nil] UTF8String];
if (!source) {
NSLog(@"Failed to load vertex shader");
return NO;
}*shader = glCreateShader(type);
glShaderSource(*shader, 1, &source, NULL);
glCompileShader(*shader);
#if defined(DEBUG)
GLint logLength;
glGetShaderiv(*shader, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetShaderInfoLog(*shader, logLength, &logLength, log);
NSLog(@"Shader compile log:\n%s", log);
free(log);
}
#endif
glGetShaderiv(*shader, GL_COMPILE_STATUS, &status);
if (status == 0) {
glDeleteShader(*shader);
return NO;
}
return YES;
}
- (BOOL)linkProgram:(GLuint)prog { GLint status; glLinkProgram(prog);
#if defined(DEBUG)
GLint logLength;
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(prog, logLength, &logLength, log);
NSLog(@"Program link log:\n%s", log);
free(log);
}
#endif
glGetProgramiv(prog, GL_LINK_STATUS, &status);
if (status == 0) {
return NO;
}
return YES;
}
-
(BOOL)validateProgram:(GLuint)prog
{
GLint logLength, status;glValidateProgram(prog);
glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logLength);
if (logLength > 0) {
GLchar *log = (GLchar *)malloc(logLength);
glGetProgramInfoLog(prog, logLength, &logLength, log);
NSLog(@"Program validate log:\n%s", log);
free(log);
}glGetProgramiv(prog, GL_VALIDATE_STATUS, &status);
if (status == 0) {
return NO;
}return YES;
}
@end
shader
attribute vec3 position;
attribute vec3 normal;
attribute vec4 color;
attribute vec2 TextureCoords;
uniform lowp mat4 modelMatrix;
uniform lowp mat4 viewMatrix;
uniform lowp mat4 projectionMatrix;
varying lowp vec4 colorVarying;
varying vec2 TextureCoordsOut;
void main()
{
vec4 pointNormal = normalize(projectionMatrix * viewMatrix * modelMatrix * vec4(normal,1));
vec3 pNormal = normalize(vec3(pointNormal.x,pointNormal.y,pointNormal.z));
vec4 lightColor = vec4(1,0,1,1);
vec3 lightDirection = normalize(vec3(1,0,1));
float lightStrength = dot(lightDirection,pNormal);
colorVarying = color + lightStrength * lightColor;
gl_Position = vec4(position,1);//projectionMatrix * viewMatrix * modelMatrix * vec4(position,1);
}