我正在尝试渲染纹理,然后使用iPhone上的OpenGL ES将该纹理绘制到屏幕上.我正在使用这个问题作为起点,并在Apple的演示EAGLView的子类中进行绘图.
实例变量:
GLuint textureFrameBuffer;
Texture2D * texture;
Run Code Online (Sandbox Code Playgroud)
要初始化帧缓冲区和纹理,我这样做:
GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO);
// initWithData results in a white image on the device (works fine in the simulator)
texture = [[Texture2D alloc] initWithImage:[UIImage imageNamed:@"blank320.png"]];
// create framebuffer
glGenFramebuffersOES(1, &textureFrameBuffer);
glBindFramebufferOES(GL_FRAMEBUFFER_OES, textureFrameBuffer);
// attach renderbuffer
glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, texture.name, 0);
if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
NSLog(@"incomplete");
glBindFramebufferOES(GL_FRAMEBUFFER_OES, oldFBO);
Run Code Online (Sandbox Code Playgroud)
现在,如果我像往常一样将我的场景画到屏幕上,它可以正常工作:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// draw some triangles, complete with vertex normals
[contentDelegate draw];
[self swapBuffers];
Run Code Online (Sandbox Code Playgroud)
但是,如果我渲染到'textureFrameBuffer',然后在屏幕上绘制'纹理',则生成的图像会颠倒并"向内".也就是说,看起来三维物体的法线指向内部而不是外部 - 每个物体的最前面是透明的,我可以看到背面的内部.这是代码:
GLint oldFBO;
glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &oldFBO); …Run Code Online (Sandbox Code Playgroud) 离屏渲染到纹理绑定的屏幕外帧缓冲对象应该是如此微不足道,但我遇到了一个问题,我无法绕过头脑.
我的完整示例程序(目前只有2D!)在这里:
请参阅下面的一些说明.
我正在创建一个rgba纹理对象512x512,将其绑定到FBO.此时不需要深度或其他渲染缓冲区,严格来说是2D.
以下非常简单的着色器渲染到此纹理:
顶点着色器:
varying vec2 vPos; attribute vec2 aPos;
void main (void) {
vPos = (aPos + 1) / 2;
gl_Position = vec4(aPos, 0.0, 1.0);
}
Run Code Online (Sandbox Code Playgroud)
在aPos中,这只是一个包含4 xy坐标的VBO,用于四边形(-1,-1 :: 1,-1 :: 1,1:-1,1)
因此,虽然帧缓冲分辨率理论上应该是512x512,但着色器将其"纹理"渲染到"全(关)屏幕四边形"上,遵循GLs -1..1 coords范例.
片段着色器:
varying vec2 vPos;
void main (void) {
gl_FragColor = vec4(0.25, vPos, 1);
}
Run Code Online (Sandbox Code Playgroud)
所以它设置了一个完全不透明的颜色,红色固定为0.25,绿色/蓝色取决于x/y,介于0和1之间.
在这一点上,我的假设是渲染512x512纹理,仅显示-1..1全(关)屏幕四边形,片段阴影显示绿色/蓝色从0..1.
所以这是我的屏幕外设置.在屏幕上,我有另一个真正可见的全屏四边形与4 xyz坐标{-1,-1,1 ::: 1,-1,1 ::: 1,1,1 ::: -1,1, 1}.同样,现在这是2D所以没有矩阵,所以z总是1.
此四边形由不同的着色器绘制,只需渲染给定的纹理,即教科书GL-101样式.在我上面链接的示例程序中,我有一个简单的布尔切换doRtt,当这是假(默认)时,根本不执行渲染到纹理,这个着色器只显示使用当前目录中的texture.jpg.
这个doRtt = false模式显示第二个屏幕四重渲染器对于我当前的要求是"正确的"并按照我的要求执行纹理化:垂直重复两次和水平重复两次(稍后将被钳制,重复仅用于测试这里),否则使用NO纹理过滤或mipmapping进行缩放.
因此,无论窗口(以及视图端口)如何调整大小,我们总是会看到一个全屏四边形,其中单个纹理水平重复两次,垂直重复两次.
现在,使用doRtt = true,第二个着色器仍然可以完成它的工作,但纹理永远不会完全正确缩放 - 或绘制,我不确定,因为不幸的是我们不能只说"嘿gl将此FBO保存到磁盘调试目的".
RTT着色器执行一些部分渲染(或者可能是一个完整的渲染,再次无法确定屏幕外发生了什么......)特别是当您调整视口大小比默认大小小很多时,您会看到纹理之间的间隔重复,并非确实显示了我们非常简单的RTT片段着色器所期望的所有颜色.
(A)要么:512x512纹理是正确创建的,但我的代码没有正确映射(但是为什么doRtt = false任何给定的texture.jpg文件使用完全相同的简单纹理四边形着色器显示得很好?)
(B)或:512x512纹理没有正确渲染,不知何故rtt frag着色器根据窗口分辨率改变其输出 …
我正在尝试使用C++ directx 11 SDK一次渲染到两个纹理.我希望一个纹理包含结果图像的每个像素的颜色(我在渲染3D场景时通常在屏幕上看到的颜色),另一个纹理包含每个像素和深度的法线(3个浮点数用于法线和1个浮点数)深度).现在,我能想到的是创建两个渲染目标并将第一遍渲染为颜色,第二遍分别传递法线和深度到每个渲染目标.然而,这似乎是浪费时间,因为我可以在第一遍中获得每个像素的颜色,法线和深度的信息.那么有没有办法用像素着色器以某种方式输出两个纹理?
任何帮助,将不胜感激.
PS我在想象像素着色器中的RWTexture2D或RWStructuredBuffer.一点背景:我需要两个图像在计算着色器中进一步处理.这引出了同步的一个侧面问题:由于像素着色器(与计算着色器不同)一次一个地写入每个像素,我如何知道像素着色器何时完成并告诉计算着色器开始图像后处理?
尝试通过 WebRtc 流式传输位图。我的 Capturer 类大致如下所示:
public class BitmapCapturer implements VideoCapturer, VideoSink {
private Capturer capturer;
private int width;
private int height;
private SurfaceTextureHelper textureHelper;
private Context appContext;
@Nullable
private CapturerObserver capturerObserver;
@Override
public void initialize(SurfaceTextureHelper surfaceTextureHelper,
Context context, CapturerObserver capturerObserver) {
if (capturerObserver == null) {
throw new RuntimeException("capturerObserver not set.");
} else {
this.appContext = context;
this.textureHelper = surfaceTextureHelper;
this.capturerObserver = capturerObserver;
this.capturer = new Capturer();
this.textureHelper.startListening(this);
}
}
@Override
public void startCapture(int width, int height, int fps) { …Run Code Online (Sandbox Code Playgroud) android surfaceview render-to-texture opengl-es-2.0 webrtc-android
我为iPhone编写图形应用程序,我希望将我最新的应用程序"Layers"移植到Android平台.图层是绘画应用程序,允许用户在屏幕上绘图,并创建具有不同画笔,颜色等的多层绘画......并导出到PSD.它有桌面同步,涂抹工具,很多好东西...... http://www.layersforiphone.com/
周一我开始关注Android平台,我遇到了一个重大问题.我使用OpenGL来完成所有绘图,因为它提供了最佳性能.但是,有几个地方我需要渲染到纹理然后使用纹理.例如:
在iPhone上,当用户的手指移动时,我会不断地这样做,并且我能够在第一代iPod Touch上实现12-15fps.这是必要的,因为将颜色和alpha应用于构成画笔笔划的各个精灵不会产生正确的结果(因为精灵重叠并使笔画太暗).
android平台支持OpenGL ES 1.0,但似乎省略了处理framebuffers的关键函数.我找不到一种方法将纹理绑定到帧缓冲区并使用OpenGL绘制到它.
以下是我通常在iPhone上进行的操作:
// generate a secondary framebuffer and bind it to OpenGL so we don't mess with existing output.
glGenFramebuffers(1, &compositingFramebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, compositingFramebuffer);
// attach a texture to the framebuffer.
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
// subsequent drawing operations are rendered into the texture
// restore the primary framebuffer and (possibly) draw the rendered texture
glBindFramebuffer(GL_FRAMEBUFFER, originalActiveFramebuffer);
Run Code Online (Sandbox Code Playgroud)
Android平台上有这样的东西吗?在iPhone上,OpenGL比基于软件的绘图快得多,并且是唯一可行的解决方案(相信我 - 我也写了一个CoreGraphics绘画应用程序......).也许我可以在Android上使用另一条路线?我愿意跳过任何必要的箍,但我不会发布应用程序,除非性能良好(10fps +,因为你在屏幕上绘图).
我知道使用glGet获取各种参数.我需要知道如何获取当前的GL_FRAMEBUFFER_OES并获取GLuint类型的帧缓冲区ID.
我需要使用renderToTexture.当切换回普通帧缓冲时,这将使其中一个类代码更容易.
我非常肯定,经过几个小时的抨击,这是无法做到的.
到目前为止,这是我的代码(下图),用于渲染纹理; 它完成了这项工作,但非常浪费.我只想要一个8位通道,可能是16位灰度.我不想要一个无用的RG和B频道.
但是,如果我尝试切换GL_RGBA/**GL_ALPHA /在glTexImage2D,glCheckFramebufferStatus接球"帧缓冲不完整的"错误:36054 0x8CD6 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT
IRC上的人建议使用GL_R,但是Xcode不提供自动完成功能,所以看起来它可能是GL为GLES修剪过的东西之一
但这似乎很奇怪!这是一个移动设备.当然,将执行操作所需的位数减少了四倍......这肯定是最后要采取的事情之一.
?!?
任何人都可以明确地埋葬这个吗?是否可以在GLES2.0中渲染到单个通道纹理?
+ (void) blurTexture: (GLuint) in_texId
POTWidth: (GLuint) in_W
POTHeight: (GLuint) in_H
returningTexId: (GLuint*) out_pTexId
{
// search HELP: 'Using a Framebuffer Object as a Texture'
// http://stackoverflow.com/questions/3613889/gl-framebuffer-incomplete-attachment-when-trying-to-attach-texture
// Create the destination texture, and attach it to the framebuffer’s color attachment point.
// create the texture
GLuint id_texDest;
{
// fragshader will use 0
glActiveTexture( GL_TEXTURE0 );
// Ask GL to give us a texture-ID for us to use
glGenTextures( …Run Code Online (Sandbox Code Playgroud) 我正在使用opengl es 2.0编写Android 2d游戏.在我将精灵绘制到后备缓冲区后,我将灯光绘制到FBO并尝试将其再次混合到后台缓冲区.当我将FBO绘制到帧缓冲区时,即使没有任何颜色也没有任何颜色,帧率在三星Galaxy w上从60降到30(它有一个adreno 205作为gpu).我到处搜索并尝试了一切,即使我在场景中绘制了一个精灵并将一个透明的FBO纹理混合到帧速率下降的屏幕上.我在手机上尝试了其他带有灯光效果的游戏,它们运行良好,几乎所有游戏都可以在手机上运行,我相信它们也使用了帧缓冲.在Galaxy SII(mali 400 gpu)运行正常,我对opengl很新,所以我相信我在某个地方犯了错误,我分享了我的代码.
// Create a framebuffer and renderbuffer
GLES20.glGenFramebuffers(1, fb, offset);
GLES20.glGenRenderbuffers(1, depthRb, offset);
// Create a texture to hold the frame buffer
GLES20.glGenTextures(1, renderTex, offset);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, renderTex[offset]);
GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA,
screenWidth, screenHeight, 0,
GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE,
null);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
GLES20.GL_LINEAR);
//bind renderbuffer
GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, depthRb[offset]);
GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16,
screenWidth, screenHeight);
// bind the framebuffer
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[offset]);
// specify texture as color attachment
GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0,
GLES20.GL_TEXTURE_2D, renderTex[offset], …Run Code Online (Sandbox Code Playgroud) glMemoryBarrier在GL 4.2及更高版本中可用,而glTextureBarrier在GL 4.5中可用
glTextureBarrier允许在片段着色器从中获取时同时渲染到相同的纹理,IFF纹理的每个纹素都被纹理拾取恰好一次.
我想知道glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT)是否允许这样做?如果没有,是否有一个等同于glTextureBarrier的OpenGL ES?
当我将 MTKView 的内容捕获到 UIImage 中时,生成的图像看起来有质的不同,如下所示:
我用来生成 UIImage 的代码如下:
let kciOptions = [kCIContextWorkingColorSpace: CGColorSpace(name: CGColorSpace.sRGB)!,
kCIContextOutputPremultiplied: true,
kCIContextUseSoftwareRenderer: false] as [String : Any]
let lastDrawableDisplayed = self.currentDrawable! // needed to hold the last drawable presented to screen
drawingUIView.image = UIImage(ciImage: CIImage(mtlTexture: lastDrawableDisplayed.texture, options: kciOptions)!)
Run Code Online (Sandbox Code Playgroud)
由于我没有修改 ciImage 方向 (.orientation(CGImagePropertyOrientation.downMirrored)),因此生成的图像是颠倒的,如上图所示。我保持镜像方向不变,以便我可以指出两个图像捕获之间的颜色差异。
无论我如何更改 kciOptions 参数(例如,甚至将色彩空间更改为灰度),我都没有看到生成的 UIImage 有任何变化,它看起来比原始图像更暗/不饱和。有人对我如何准确地将我在 MTKView 上绘制的内容捕获到 UIImage 有任何建议吗?任何建议将不胜感激。
以下是我可能证明相关的 MTKView 设置:
let renderPipelineDescriptor = MTLRenderPipelineDescriptor()
renderPipelineDescriptor.vertexFunction = vertexProgram
renderPipelineDescriptor.sampleCount = self.sampleCount
renderPipelineDescriptor.colorAttachments[0].pixelFormat = MTLPixelFormat.bgra8Unorm
renderPipelineDescriptor.colorAttachments[0].isBlendingEnabled = true
renderPipelineDescriptor.colorAttachments[0].rgbBlendOperation = .add
renderPipelineDescriptor.colorAttachments[0].alphaBlendOperation = …Run Code Online (Sandbox Code Playgroud) opengl-es ×4
android ×3
framebuffer ×2
iphone ×2
opengl ×2
2d ×1
alpha ×1
directx-11 ×1
go ×1
ios ×1
memory ×1
metal ×1
metalkit ×1
off-screen ×1
pixel-shader ×1
surfaceview ×1
swift ×1
uiimageview ×1