vps做网站,如何做网站国际化,客户做外贸用那些网站,会考网页制作视频教程全集本文为转载内容#xff0c;原地址
有时#xff0c;我们想通过GPU做一些视频、图像处理#xff0c;而处理的结果不需要显示在显示器上#xff0c;而是直接交给主存#xff0c;这时候我们可以通过OpenGL的离屏渲染来实现。
由于我们不需要将渲染好的像素显示到屏幕上…本文为转载内容原地址
有时我们想通过GPU做一些视频、图像处理而处理的结果不需要显示在显示器上而是直接交给主存这时候我们可以通过OpenGL的离屏渲染来实现。
由于我们不需要将渲染好的像素显示到屏幕上因此我们可以使用framebuffer object将像素放到fbo上然后通过glReadPixels来最终获取渲染好的像素。
在Mac OS X Lion中做离屏渲染非常简单基本步骤如下
1、创建OpenGL绘制上下文可使用离屏渲染属性然后可以设置上其它属性。
2、创建framebuffer object
3、绑定创建好的fbo
4、编译、连接、加载着色器并初始化一些基本的OpenGL的上下文
5、生成纹理并将它绑定到framebuffer中
6、取消framebuffer的绑定然后就可以做渲染了。
在使用glDrawArrays等绘制接口之后可以调用glFlush来确保像素都已经到了指定的framebuffer然后通过调用glReadPixels将像素读取出来。
下面将给出具体的代码 // // MyGLView.h // OpenGLShaderBasic // // Created by Zenny Chen on 10/4/10. // Copyright 2010 GreenGames Studio. All rights reserved. // #import Cocoa/Cocoa.h class NSOpenGLContext; interface MyGLView : NSObject { GLuint program; GLuint framebufferID; GLuint texName; NSOpenGLContext *glContext; } - (void)prepareOpenGL; - (void)compute; end
这里尽管给出的Objective-C类叫MyGLView但它其实不是一个UIView的子类。由于我们不需要将结果显示到屏幕上因此这里也就不需要用UIView作为父类。 // // MyGLView.m // OpenGLShaderBasic // // Created by Zenny Chen on 10/4/10. // Copyright 2010 GreenGames Studio. All rights reserved. // #import MyGLView.h #include OpenGL/gl.h #include OpenGL/OpenGL.h #include OpenGL/CGLRenderers.h #define MY_PIXEL_WIDTH 128 #define MY_PIXEL_HEIGHT 128 implementation MyGLView // uniform index enum { UNIFORM_SAMPLER, NUM_UNIFORMS }; static GLint uniforms[NUM_UNIFORMS]; // attribute index enum { ATTRIB_VERTEX, ATTRIB_TEXCOORD, NUM_ATTRIBUTES }; - (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 FALSE; } *shader glCreateShader(type); glShaderSource(*shader, 1, source, NULL); glCompileShader(*shader); 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); } glGetShaderiv(*shader, GL_COMPILE_STATUS, status); if (status 0) { glDeleteShader(*shader); return FALSE; } return TRUE; } - (BOOL)linkProgram:(GLuint)prog { GLint status; glLinkProgram(prog); 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); } glGetProgramiv(prog, GL_LINK_STATUS, status); if (status 0) return FALSE; return TRUE; } - (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 FALSE; return TRUE; } - (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 FALSE; } // 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 FALSE; } // 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, ATTRIB_VERTEX, position); glBindAttribLocation(program, ATTRIB_TEXCOORD, texCoords); //glBindFragDataLocationEXT(program, 0, myFragColor); // link program if (![self linkProgram:program]) { NSLog(Failed to link program: %d, program); return FALSE; } // get uniform locations uniforms[UNIFORM_SAMPLER] glGetUniformLocation(program, sampler); // release vertex and fragment shaders if (vertShader) glDeleteShader(vertShader); if (fragShader) glDeleteShader(fragShader); return TRUE; } - (void)dealloc { if(texName ! 0) glDeleteTextures(1, texName); if(framebufferID ! 0) glDeleteFramebuffers(1, framebufferID); if(glContext ! nil) { [glContext release]; glContext nil; } [super dealloc]; } static GLfloat __attribute__((aligned(16))) my_buffer[MY_PIXEL_WIDTH * MY_PIXEL_HEIGHT * 4]; static GLfloat __attribute__((aligned(16))) checkImage[MY_PIXEL_WIDTH * MY_PIXEL_HEIGHT * 4]; static void initCheckImage(void) { for(int row 0; row MY_PIXEL_HEIGHT; row) { for(int col 0; col MY_PIXEL_WIDTH; col) { checkImage[row * MY_PIXEL_WIDTH * 4 col * 4 0] 0.1f; checkImage[row * MY_PIXEL_WIDTH * 4 col * 4 1] 0.2f; checkImage[row * MY_PIXEL_WIDTH * 4 col * 4 2] 0.3f; checkImage[row * MY_PIXEL_WIDTH * 4 col * 4 3] 0.4f; } } } - (void)prepareOpenGL { if(glContext ! nil) return; #if 0 CGLPixelFormatObj pixObj NULL; GLint nPix 0; CGLChoosePixelFormat((const CGLPixelFormatAttribute[]){kCGLPFAOpenGLProfile, kCGLOGLPVersion_3_2_Core, 0}, pixObj, nPix); NSOpenGLPixelFormat *pixelFormat [[NSOpenGLPixelFormat alloc] initWithCGLPixelFormatObj:pixObj]; CGLReleasePixelFormat(pixObj); #else // 创建pixel format设置离屏渲染 NSOpenGLPixelFormat *pixelFormat [[NSOpenGLPixelFormat alloc] initWithAttributes:(const NSOpenGLPixelFormatAttribute[]){NSOpenGLPFAAllRenderers, NSOpenGLPFAOffScreen, NSOpenGLPFAAllowOfflineRenderers, 0}]; #endif // 创建OpenGL上下文 glContext [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; [pixelFormat release];br // 将此上下文作为当前上下文 [glContext makeCurrentContext]; if(![self loadShaders]) return; glGenFramebuffers(1, framebufferID); glBindFramebuffer(GL_FRAMEBUFFER, framebufferID); glViewport(0, 0, MY_PIXEL_WIDTH, MY_PIXEL_HEIGHT); glClearColor(0.4f, 0.4f, 0.4f, 1.0f); // Use shader program glUseProgram(program); // Drawing code here. static const GLfloat squareVertices[] { -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f }; static const GLfloat texCoords[] { 0.0f, 0.0f, // left lower 1.0f, 0.0f, // right lower 0.0f, 1.0f, // left upper 1.0f, 1.0f // right upper }; glEnable(GL_CULL_FACE); // 初始化纹理数据 initCheckImage(); glClampColorARB(GL_RGBA_FLOAT_MODE_ARB, GL_TRUE); glClampColorARB(GL_CLAMP_FRAGMENT_COLOR_ARB, GL_FALSE); glClampColorARB(GL_CLAMP_READ_COLOR_ARB, GL_FALSE); // 初始化纹理 glPixelStorei(GL_UNPACK_ALIGNMENT, 8); glActiveTexture(GL_TEXTURE0); glGenTextures(1, texName); glBindTexture(GL_TEXTURE_2D, texName); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, MY_PIXEL_WIDTH, MY_PIXEL_HEIGHT, 0, GL_RGBA, GL_FLOAT, checkImage); // 将纹理绑定到帧缓存 glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, texName, 0); glUniform1i(uniforms[UNIFORM_SAMPLER], 0); // Set the sampler value // Update attribute values glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, squareVertices); glEnableVertexAttribArray(ATTRIB_VERTEX); glVertexAttribPointer(ATTRIB_TEXCOORD, 2, GL_FLOAT, 0, 0, texCoords); glEnableVertexAttribArray(ATTRIB_TEXCOORD); } - (void)compute { glClear(GL_COLOR_BUFFER_BIT); // Draw glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glFlush(); glReadPixels(0, 0, MY_PIXEL_WIDTH, MY_PIXEL_HEIGHT, GL_RGBA, GL_FLOAT, my_buffer); NSLog(R:%f, G:%f, B:%f, A:%f, my_buffer[0], my_buffer[1], my_buffer[2], my_buffer[3]); } end 下面给出Vertex shader和Fragment shader这两个Shader的代码很简单 // // Shader.vsh // GLSLTest // // Created by Zenny Chen on 4/11/10. // Copyright GreenGames Studio 2010. All rights reserved. // #version 120 #extension GL_EXT_gpu_shader4 : enable attribute vec4 position; attribute vec4 texCoords; uniform mat4 translate; uniform mat4 projection; void main() { gl_Position position; gl_TexCoord[0] texCoords; } // // Shader.fsh // GLSLTest // // Created by Zenny Chen on 4/11/10. // Copyright GreenGames Studio 2010. All rights reserved. // #version 120 uniform sampler2D sampler; void main() { // gl_FragColor gl_FragColor texture2D(sampler, gl_TexCoord[0].st) vec4(0.4, 0.3, 0.2, 1.1); } 最后给出OS X的AppDelegate中的实现。各位可以拿这代码自己尝试一下看看输出结果 // // AppDelegate.h // OpenGL4Compute // // Created by zenny_chen on 12-12-9. // Copyright (c) 2012年 zenny_chen. All rights reserved. // #import Cocoa/Cocoa.h class MyGLView; interface AppDelegate : NSObject NSApplicationDelegate { MyGLView *glComputeObj; } property (assign) IBOutlet NSWindow *window; end // // AppDelegate.m // OpenGL4Compute // // Created by zenny_chen on 12-12-9. // Copyright (c) 2012年 zenny_chen. All rights reserved. // #import AppDelegate.h #import MyGLView.h implementation AppDelegate - (void)dealloc { [super dealloc]; } - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Insert code here to initialize your application NSView *baseView self.window.contentView; CGSize viewSize baseView.frame.size; NSButton *button [[NSButton alloc] initWithFrame:CGRectMake(20.0f, viewSize.height - 60.0f, 100.0f, 30.0f)]; [button setButtonType:NSMomentaryPushInButton]; [button setBezelStyle:NSRoundedBezelStyle]; [button setTitle:Compute]; [button setTarget:self]; [button setAction:selector(computeButtonTouched:)]; [baseView addSubview:button]; [button release]; } - (void)computeButtonTouched:(id)sender { if(glComputeObj nil) { glComputeObj [[MyGLView alloc] init]; [glComputeObj prepareOpenGL]; } [glComputeObj compute]; } end