日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OS X下使用OpenGL做离屏渲染

發(fā)布時間:2023/12/3 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OS X下使用OpenGL做离屏渲染 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文為轉(zhuǎn)載內(nèi)容,原地址

有時,我們想通過GPU做一些視頻、圖像處理,而處理的結(jié)果不需要顯示在顯示器上,而是直接交給主存,這時候我們可以通過OpenGL的離屏渲染來實(shí)現(xiàn)。

由于我們不需要將渲染好的像素顯示到屏幕上,因此我們可以使用framebuffer object,將像素放到fbo上,然后通過glReadPixels來最終獲取渲染好的像素。

在Mac OS X Lion中做離屏渲染非常簡單,基本步驟如下:

1、創(chuàng)建OpenGL繪制上下文,可使用離屏渲染屬性,然后可以設(shè)置上其它屬性。

2、創(chuàng)建framebuffer object

3、綁定創(chuàng)建好的fbo

4、編譯、連接、加載著色器并初始化一些基本的OpenGL的上下文

5、生成紋理,并將它綁定到framebuffer中

6、取消framebuffer的綁定,然后就可以做渲染了。

在使用glDrawArrays等繪制接口之后,可以調(diào)用glFlush來確保像素都已經(jīng)到了指定的framebuffer,然后通過調(diào)用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,但它其實(shí)不是一個UIView的子類。由于我們不需要將結(jié)果顯示到屏幕上,因此這里也就不需要用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

?????

????// 創(chuàng)建pixel format,設(shè)置離屏渲染

????NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:(const?NSOpenGLPixelFormatAttribute[]){NSOpenGLPFAAllRenderers, NSOpenGLPFAOffScreen, NSOpenGLPFAAllowOfflineRenderers, 0}];

#endif

?????

????// 創(chuàng)建OpenGL上下文

????glContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];

????[pixelFormat release];<br>

????// 將此上下文作為當(dāng)前上下文

????[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);

?????

????// 初始化紋理數(shù)據(jù)

????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中的實(shí)現(xiàn)。各位可以拿這代碼自己嘗試一下,看看輸出結(jié)果~

//

//? 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

總結(jié)

以上是生活随笔為你收集整理的OS X下使用OpenGL做离屏渲染的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 激情总合网 | 亚洲精品国产精品国自产观看 | 亚洲少妇中文字幕 | jizz日本在线播放 | 亚洲精品一区二区三区蜜桃 | 国产在线一区二区视频 | 靠逼视频免费网站 | 黑人玩弄人妻一区二区三区影院 | 天美视频在线观看 | www.日韩精品 | 四虎av影视 | 国产高清中文字幕 | www.九色.com | 18被视频免费观看视频 | 久久九九视频 | 亚色视频在线观看 | 日韩欧美三级在线 | 中文字幕在线观看播放 | 精品处破女学生 | 中文字幕在线精品 | 日韩高清精品免费观看 | 国产剧情一区在线 | 欧洲精品在线播放 | 日本免费看 | av网址网站 | 五月婷婷色丁香 | 一级大黄毛片 | 一级黄色大片免费观看 | 爱情岛成人 | 国产精品无码一区二区三区在线看 | 永久免费av无码网站性色av | 五月天综合婷婷 | 综合狠狠 | 97超碰人人澡 | 国产区第一页 | 9191国产精品 | 国产女主播在线一区二区 | 国产a三级 | 超碰在线91 | 在线观看日本 | 一个色在线视频 | 欧美日韩综合网 | 亚洲免费视频网 | 超碰免费在线观看 | 中国一级特黄毛片 | 黄色片链接| 国产吞精囗交久久久 | 日韩欧美国产网站 | 在线观看亚洲欧美 | 人人舔人人干 | 日本黄色片免费看 | 免费午夜网站 | av激情小说 | av不卡中文字幕 | 一区二区日韩视频 | 免费黄色国产 | 婷婷午夜精品久久久久久性色av | 亚洲高清免费 | 天天射夜夜撸 | 午夜视频福利在线 | 一本大道一区二区 | 中文 欧美 日韩 | 巨茎大战刘亦菲 | 97精品一区二区视频在线观看 | 成人午夜影院在线观看 | 偷拍视频久久 | 国产成人在线一区二区 | 成人黄网免费观看视频 | 欧美日韩一二三区 | 日批网址| 99爱爱| 亚洲欧美一区二区三区 | 久久精品在这里 | 欧美射射射 | 三级国产在线 | 日韩欧美中字 | 精品美女一区 | www毛片| 亚洲熟妇一区二区三区 | av在线资源播放 | 国产91精品高潮白浆喷水 | 亚洲av综合色区无码另类小说 | 亚洲精品一线二线三线 | 美女被啪羞羞粉色视频 | 久久九九爱 | 欧洲做受高潮欧美裸体艺术 | 丁香婷婷综合激情 | 天堂а在线中文在线新版 | 国产成人精品免费看视频 | 中文字幕人成乱码熟女香港 | 欧美脚交| 日本中文字幕视频 | 欧美手机看片 | 波多野吉衣一区二区三区 | 久草视频免费在线播放 | 9色av| 日本高清不卡视频 | 91免费在线观看网站 | 一起草视频在线播放 |