iOS原生OPENGL之贴图
来源:互联网 发布:淘宝招聘官网首页 编辑:程序博客网 时间:2024/05/01 08:16
iOS平台上学习OpenGL的资料比较少,加上深度也不够,比如贴图,只能用系统提供的effect类去绘制,在这里我将我整理得到的一些关于贴图的知识分享出来,希望能帮到不了解又想学gl知识的人.完整代码请参照:https://github.com/xuyaxiang/TriangleMipByShader
//// ViewController.m// GoldTower//// Created by enghou on 17/3/20.// Copyright © 2017年 xyxorigation. All rights reserved.//#import "ViewController.h"typedef enum{ AGLK1 = 1, AGLK2 = 2, AGLK4 = 4, AGLK8 = 8, AGLK16 = 16, AGLK32 = 32, AGLK64 = 64, AGLK128 = 128, AGLK256 = 256, AGLK512 = 512, AGLK1024 = 1024,}AGLKPowerOf2;static NSData *AGLKDataWithResizedCGImageBytes( CGImageRef cgImage, size_t *widthPtr, size_t *heightPtr);static AGLKPowerOf2 AGLKCalculatePowerOf2ForDimension( GLuint dimension);typedef struct { GLKVector3 position; GLKVector3 normal; GLKVector4 color; GLKVector2 texCoords;}SceneVertex;typedef struct { SceneVertex vertices[3];}SceneTriangle;static const SceneVertex vertexA ={{-0.5, 0.5, 0}, {0.0, 0.0, 1.0},{1,1,1,1},{0,1}};static const SceneVertex vertexB ={{-0.5, 0.0, 0}, {0.0, 0.0, 1.0},{1,1,1,1},{0,0.5}};static const SceneVertex vertexC ={{-0.5, -0.5, 0}, {0.0, 0.0, 1.0},{1,1,1,1},{0,0}};static const SceneVertex vertexD ={{ 0.0, 0.5, 0}, {0.0, 0.0, 1.0},{1,1,1,1},{0.5,1}};static const SceneVertex vertexE ={{ 0.0, 0.0, 0.5}, {0.0, 0.0, 1.0},{1,1,1,1},{0.5,0.5}};static const SceneVertex vertexF ={{ 0.0, -0.5, 0}, {0.0, 0.0, 1.0},{1,1,1,1},{0.5,0}};static const SceneVertex vertexG ={{ 0.5, 0.5, 0}, {0.0, 0.0, 1.0},{1,1,1,1},{1,1}};static const SceneVertex vertexH ={{ 0.5, 0.0, 0}, {0.0, 0.0, 1.0},{1,1,1,1},{1,0.5}};static const SceneVertex vertexI ={{ 0.5, -0.5, 0}, {0.0, 0.0, 1.0},{1,1,1,1},{1,0}};SceneTriangle triangle[8];@interface ViewController ()@property(nonatomic,assign)GLuint program;@property(nonatomic,assign)int lightPositionP;@property(nonatomic,assign)int lightColor;@property(nonatomic,assign)int modelMatrix;@property(nonatomic,assign)int viewMatrix;@property(nonatomic,assign)GLint texCoords;@property(nonatomic,assign)GLuint texture;@end@implementation ViewController{ GLKBaseEffect *effect;}-(void)makeTriangles{ triangle[0] = [self makeTriangle:vertexA B:vertexB C:vertexD]; triangle[1] = [self makeTriangle:vertexG B:vertexD C:vertexH]; triangle[2] = [self makeTriangle:vertexH B:vertexF C:vertexI]; triangle[3] = [self makeTriangle:vertexB B:vertexC C:vertexF]; triangle[4] = [self makeTriangle:vertexD B:vertexB C:vertexE]; triangle[5] = [self makeTriangle:vertexD B:vertexE C:vertexH]; triangle[6] = [self makeTriangle:vertexH B:vertexE C:vertexF]; triangle[7] = [self makeTriangle:vertexF B:vertexE C:vertexB];}-(SceneTriangle)makeTriangle:(SceneVertex)A B:(SceneVertex)B C:(SceneVertex)C{ SceneTriangle triangle; triangle.vertices[0] = A; triangle.vertices[1] = B; triangle.vertices[2] = C; GLKVector3 AB = GLKVector3Make(B.position.x - A.position.x, B.position.y - A.position.y, B.position.z - B.position.z); GLKVector3 AC = GLKVector3Make(C.position.x - A.position.x, C.position.y - A.position.y, C.position.z - B.position.z); GLKVector3 normal = GLKVector3CrossProduct(AB, AC); normal = GLKVector3Normalize(normal); triangle.vertices[0].normal = normal; triangle.vertices[1].normal = normal; triangle.vertices[2].normal = normal; return triangle;}- (void)viewDidLoad { [super viewDidLoad]; GLKView *view = (GLKView *)self.view; view.context =[[EAGLContext alloc]initWithAPI:kEAGLRenderingAPIOpenGLES2]; [EAGLContext setCurrentContext:view.context]; effect = [[GLKBaseEffect alloc]init]; effect.useConstantColor = GL_TRUE; effect.constantColor = GLKVector4Make(0, 0, 0, 1); [self makeTriangles]; GLuint name; glGenBuffers(1, &name); glBindBuffer(GL_ARRAY_BUFFER, name); glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW); glEnable(GL_TEXTURE_2D); UIImage *image = [UIImage imageNamed:@"1.jpg"]; size_t width; size_t height; NSData *data = AGLKDataWithResizedCGImageBytes(image.CGImage, &width, &height); glGenTextures(1, &_texture); glActiveTexture(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, _texture); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.bytes); glClearColor(0, 0, 0, 1); glEnableVertexAttribArray(GLKVertexAttribPosition); glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL); glEnableVertexAttribArray(GLKVertexAttribNormal); glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL + offsetof(SceneVertex, normal)); glEnableVertexAttribArray(GLKVertexAttribColor); glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL+offsetof(SceneVertex, color)); glEnableVertexAttribArray(GLKVertexAttribTexCoord0); glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, sizeof(SceneVertex), NULL+offsetof(SceneVertex, texCoords)); glEnable(GL_DEPTH_TEST | GL_CULL_FACE); [self loadShaders]; glUniform1i(_texCoords, 0);}-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); static float i = 0.0; glUseProgram(_program); glUniform4f(_lightPositionP, 1, 0, 1, 1); glUniform4f(_lightColor, 0, 0.5, 0.5, 1); GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0, 0, 2); GLfloat ratio = (GLfloat)view.drawableWidth / view.drawableHeight; modelViewMatrix = GLKMatrix4Scale(modelViewMatrix, 3, 3*ratio, 3); modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(60), 1, 0, 0); i = i + 0.001; GLKMatrix4 projection = GLKMatrix4MakeFrustum(-1, 1, -1, 1, 1, 50); glUniformMatrix4fv(_modelMatrix, 1, 0, modelViewMatrix.m); glUniformMatrix4fv(_viewMatrix, 1, 0, projection.m); glDrawArrays(GL_TRIANGLES, 0, sizeof(triangle)/sizeof(SceneVertex));}#pragma mark - OpenGL ES 2 shader compilation- (BOOL)loadShaders{ GLuint vertShader, fragShader; NSString *vertShaderPathname, *fragShaderPathname; // Create shader program. _program = glCreateProgram(); 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); glBindAttribLocation(_program, GLKVertexAttribPosition, "position"); glBindAttribLocation(_program, GLKVertexAttribNormal, "normal"); glBindAttribLocation(_program, GLKVertexAttribTexCoord0, "TextureCoords"); 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; } if (vertShader) { glDetachShader(_program, vertShader); glDeleteShader(vertShader); } if (fragShader) { glDetachShader(_program, fragShader); glDeleteShader(fragShader); } char *position = "lightPosition"; char *lightColor = "lightColor"; _lightPositionP = glGetUniformLocation(_program, position); _lightColor = glGetUniformLocation(_program, lightColor); _modelMatrix = glGetUniformLocation(_program, "modelMatrix"); _viewMatrix = glGetUniformLocation(_program, "projectionMatrix"); _texCoords = glGetUniformLocation(_program, "tex"); 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;}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@endstatic AGLKPowerOf2 AGLKCalculatePowerOf2ForDimension( GLuint dimension){ AGLKPowerOf2 result = AGLK1; if(dimension > (GLuint)AGLK512) { result = AGLK1024; } else if(dimension > (GLuint)AGLK256) { result = AGLK512; } else if(dimension > (GLuint)AGLK128) { result = AGLK256; } else if(dimension > (GLuint)AGLK64) { result = AGLK128; } else if(dimension > (GLuint)AGLK32) { result = AGLK64; } else if(dimension > (GLuint)AGLK16) { result = AGLK32; } else if(dimension > (GLuint)AGLK8) { result = AGLK16; } else if(dimension > (GLuint)AGLK4) { result = AGLK8; } else if(dimension > (GLuint)AGLK2) { result = AGLK4; } else if(dimension > (GLuint)AGLK1) { result = AGLK2; } return result;}static NSData *AGLKDataWithResizedCGImageBytes( CGImageRef cgImage, size_t *widthPtr, size_t *heightPtr){ NSCParameterAssert(NULL != cgImage); NSCParameterAssert(NULL != widthPtr); NSCParameterAssert(NULL != heightPtr); GLuint originalWidth = (GLuint)CGImageGetWidth(cgImage); GLuint originalHeight = (GLuint)CGImageGetWidth(cgImage); NSCAssert(0 < originalWidth, @"Invalid image width"); NSCAssert(0 < originalHeight, @"Invalid image width"); // Calculate the width and height of the new texture buffer // The new texture buffer will have power of 2 dimensions. GLuint width = AGLKCalculatePowerOf2ForDimension( originalWidth); GLuint height = AGLKCalculatePowerOf2ForDimension( originalHeight); // Allocate sufficient storage for RGBA pixel color data with // the power of 2 sizes specified NSMutableData *imageData = [NSMutableData dataWithLength: height * width * 4]; // 4 bytes per RGBA pixel NSCAssert(nil != imageData, @"Unable to allocate image storage"); // Create a Core Graphics context that draws into the // allocated bytes CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef cgContext = CGBitmapContextCreate( [imageData mutableBytes], width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorSpace); // Flip the Core Graphics Y-axis for future drawing CGContextTranslateCTM (cgContext, 0, height); CGContextScaleCTM (cgContext, 1.0, -1.0); // Draw the loaded image into the Core Graphics context // resizing as necessary CGContextDrawImage(cgContext, CGRectMake(0, 0, width, height), cgImage); CGContextRelease(cgContext); *widthPtr = width; *heightPtr = height; return imageData;}
0 0
- iOS原生OPENGL之贴图
- Qt+OpenGL之纹理贴图
- OpenGL 核心技术之立方体贴图
- OpenGL核心技术之法线贴图
- opengl 贴图
- OpenGL之纹理贴图(1):Basic
- OpenGL之纹理贴图(2):Texture Objects
- OpenGL学习笔记之纹理贴图
- [OpenGL]图形学之旅:纹理贴图三部曲
- OpenGL之路(六)贴图
- openGL之纹理贴图---openGL学习笔记(十三)
- OpenGL ES教程VI之纹理贴图(原文对照)
- OpenGL ES教程VI之纹理贴图(原文对照)
- OpenGL ES教程VI之纹理贴图(原文对照)
- OpenGL ES教程VI之纹理贴图(原文对照)
- 《高效学习OpenGL》 之 纹理贴图的步骤
- OpenGL ES教程VI之纹理贴图(原文对照)
- 立方体环境贴图(Cube Mapping)之OpenGL原理
- 常见的动态规划问题分析与求解
- iframe的低边会留白的处理
- View的工作流程---Measure过程
- 3月23
- [code static]Go基础语法
- iOS原生OPENGL之贴图
- Android 自定义控件原理
- C语言中常用的几个内存申请函数
- 记录Android开发中使用HorizontalScrollView的坑
- 欢迎使用CSDN-markdown编辑器
- 3月24号
- 程序员的工作、学习与绩效
- Java入门篇——注解Annotation
- Office Web Apps Server作为Client,Java代码作为Host实现Office在线预览'