- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一些在 Android 上运行良好的 OpenGL ES C 代码。代码质量很差(随机错误代码,使用全局变量等),因为我只是想在重构和清理之前启动并运行。但是,它适用于 Android 并正确显示红色三角形。
但相同的代码在 iOS 上不起作用。我在调用 glAttachShader
时得到 GL_INVALID_VALUE
(我在下面评论了相关行),即使之前的每个调用都成功了。
代码如下:
#include "gl_render.h"
#include "gl_wrapper.h"
#include <math.h>
GLuint globalProgramObject;
int surfaceWidth;
int surfaceHeight;
GLuint LoadShader ( GLenum type, const char *shaderSrc )
{
GLuint shader;
GLint compiled;
GLenum error;
shader = glCreateShader ( type );
error = glGetError();
if (error != GL_NO_ERROR) {
return -50;
}
glShaderSource ( shader, 1, &shaderSrc, NULL );
error = glGetError();
if (error != GL_NO_ERROR) {
return -51;
}
glCompileShader ( shader );
error = glGetError();
if (error != GL_NO_ERROR) {
return -52;
}
glGetShaderiv ( shader, GL_COMPILE_STATUS, &compiled );
error = glGetError();
if (error != GL_NO_ERROR) {
return -53;
}
if ( !compiled )
{
GLint infoLen = 0;
glGetShaderiv ( shader, GL_INFO_LOG_LENGTH, &infoLen );
error = glGetError();
if (error != GL_NO_ERROR) {
return -54;
}
if ( infoLen > 1 )
{
char *infoLog = malloc ( sizeof ( char ) * infoLen );
glGetShaderInfoLog ( shader, infoLen, NULL, infoLog );
error = glGetError();
if (error != GL_NO_ERROR) {
return -55;
}
free ( infoLog );
}
glDeleteShader ( shader );
error = glGetError();
if (error != GL_NO_ERROR) {
return -56;
}
return -2;
}
return shader;
}
int on_surface_created(int width, int height) {
surfaceWidth = width;
surfaceHeight = height;
char vShaderStr[] =
"#version 300 es \n"
"layout(location = 0) in vec4 vPosition; \n"
"void main() \n"
"{ \n"
" gl_Position = vPosition; \n"
"} \n";
char fShaderStr[] =
"#version 300 es \n"
"precision mediump float; \n"
"out vec4 fragColor; \n"
"void main() \n"
"{ \n"
" fragColor = vec4 ( 1.0, 0.0, 0.0, 1.0 ); \n"
"} \n";
GLuint vertexShader;
GLuint fragmentShader;
GLuint programObject;
GLint linked;
GLenum error;
vertexShader = LoadShader ( GL_VERTEX_SHADER, vShaderStr );
if (vertexShader <= 0) {
return -155;
}
fragmentShader = LoadShader ( GL_FRAGMENT_SHADER, fShaderStr );
if (fragmentShader <= 0) {
return -156;
}
programObject = glCreateProgram ( );
if (programObject == 0) {
return -157;
}
error = glGetError();
if (error != GL_NO_ERROR) {
return -57;
}
// this is failing with GL_INVALID_VALUE
glAttachShader ( programObject, vertexShader );
error = glGetError();
if (error != GL_NO_ERROR) {
return -58;
}
glAttachShader ( programObject, fragmentShader );
error = glGetError();
if (error != GL_NO_ERROR) {
return -59;
}
glLinkProgram ( programObject );
error = glGetError();
if (error != GL_NO_ERROR) {
return -60;
}
glGetProgramiv ( programObject, GL_LINK_STATUS, &linked );
error = glGetError();
if (error != GL_NO_ERROR) {
return -61;
}
if ( !linked )
{
GLint infoLen = 0;
glGetProgramiv ( programObject, GL_INFO_LOG_LENGTH, &infoLen );
error = glGetError();
if (error != GL_NO_ERROR) {
return -62;
}
if ( infoLen > 1 )
{
char *infoLog = malloc ( sizeof ( char ) * infoLen );
glGetProgramInfoLog ( programObject, infoLen, NULL, infoLog );
error = glGetError();
if (error != GL_NO_ERROR) {
return -63;
}
free ( infoLog );
}
glDeleteProgram ( programObject );
error = glGetError();
if (error != GL_NO_ERROR) {
return -64;
}
return -2;
}
glClearColor ( 1.0f, 1.0f, 1.0f, 0.0f );
error = glGetError();
if (error != GL_NO_ERROR) {
return -65;
}
globalProgramObject = programObject;
return 0;
}
int on_draw_frame() {
GLenum error;
GLfloat vVertices[] = { 0.0f, 0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f
};
glViewport ( 0, 0, surfaceWidth, surfaceHeight );
error = glGetError();
if (error != GL_NO_ERROR) {
return -66;
}
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
error = glGetError();
if (error != GL_NO_ERROR) {
return -67;
}
glUseProgram ( globalProgramObject );
error = glGetError();
if (error != GL_NO_ERROR) {
return -68;
}
glVertexAttribPointer ( 0, 3, GL_FLOAT, GL_FALSE, 0, vVertices );
error = glGetError();
if (error != GL_NO_ERROR) {
return -69;
}
glEnableVertexAttribArray ( 0 );
error = glGetError();
if (error != GL_NO_ERROR) {
return -70;
}
glDrawArrays ( GL_TRIANGLES, 0, 3 );
error = glGetError();
if (error != GL_NO_ERROR) {
return -71;
}
glDisableVertexAttribArray ( 0 );
error = glGetError();
if (error != GL_NO_ERROR) {
return -72;
}
return 0;
}
对于额外的上下文,这里是我用来托管 OpenGL worker 的 Objective C 代码:
#import "OpenGLRender.h"
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES2/gl.h>
#import <OpenGLES/ES2/glext.h>
@interface OpenGLRender()
@property (strong, nonatomic) EAGLContext *context;
@property (strong, nonatomic) id<OpenGLRenderWorker> worker;
@property (copy, nonatomic) void(^onNewFrame)(void);
@property (nonatomic) GLuint frameBuffer;
@property (nonatomic) GLuint depthBuffer;
@property (nonatomic) CVPixelBufferRef target;
@property (nonatomic) CVOpenGLESTextureCacheRef textureCache;
@property (nonatomic) CVOpenGLESTextureRef texture;
@property (nonatomic) CGSize renderSize;
@property (nonatomic) BOOL running;
@end
@implementation OpenGLRender
- (instancetype)initWithSize:(CGSize)renderSize
worker:(id<OpenGLRenderWorker>)worker
onNewFrame:(void(^)(void))onNewFrame {
self = [super init];
if (self){
self.renderSize = renderSize;
self.running = YES;
self.onNewFrame = onNewFrame;
self.worker = worker;
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
thread.name = @"OpenGLRender";
[thread start];
}
return self;
}
- (void)run {
[self initGL];
int result = [_worker onCreateWithWidth: self.renderSize.width andHeight: self.renderSize.height];
if (result != 0) {
NSLog(@"Failed to call onCreateWithWidth %f AndHeight %f: %d", self.renderSize.width, self.renderSize.height, result);
}
while (_running) {
CFTimeInterval loopStart = CACurrentMediaTime();
result = [_worker onDraw];
if (result != 0) {
NSLog(@"Failed to call onDraw: %d", result);
} else {
glFlush();
dispatch_async(dispatch_get_main_queue(), self.onNewFrame);
}
CFTimeInterval waitDelta = 0.016 - (CACurrentMediaTime() - loopStart);
if (waitDelta > 0) {
[NSThread sleepForTimeInterval:waitDelta];
}
}
[self deinitGL];
}
#pragma mark - Public
- (void)dispose {
_running = NO;
}
#pragma mark - FlutterTexture
- (CVPixelBufferRef _Nullable)copyPixelBuffer {
CVBufferRetain(_target);
return _target;
}
#pragma mark - Private
- (void)initGL {
_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:_context];
[self createCVBufferWithSize:_renderSize withRenderTarget:&_target withTextureOut:&_texture];
glBindTexture(CVOpenGLESTextureGetTarget(_texture), CVOpenGLESTextureGetName(_texture));
glTexImage2D(GL_TEXTURE_2D,
0, GL_RGBA,
_renderSize.width, _renderSize.height,
0, GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
glGenRenderbuffers(1, &_depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, _depthBuffer);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, _renderSize.width, _renderSize.height);
glGenFramebuffers(1, &_frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, CVOpenGLESTextureGetName(_texture), 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depthBuffer);
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
} else {
NSLog(@"Successfully initialized GL");
}
}
- (void)createCVBufferWithSize:(CGSize)size
withRenderTarget:(CVPixelBufferRef *)target
withTextureOut:(CVOpenGLESTextureRef *)texture {
CVReturn err = CVOpenGLESTextureCacheCreate(kCFAllocatorDefault, NULL, _context, NULL, &_textureCache);
if (err) return;
CFDictionaryRef empty;
CFMutableDictionaryRef attrs;
empty = CFDictionaryCreate(kCFAllocatorDefault,
NULL,
NULL,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
attrs = CFDictionaryCreateMutable(kCFAllocatorDefault, 1,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(attrs, kCVPixelBufferIOSurfacePropertiesKey, empty);
CVPixelBufferCreate(kCFAllocatorDefault, size.width, size.height,
kCVPixelFormatType_32BGRA, attrs, target);
CVOpenGLESTextureCacheCreateTextureFromImage(kCFAllocatorDefault,
_textureCache,
*target,
NULL, // texture attributes
GL_TEXTURE_2D,
GL_RGBA, // opengl format
size.width,
size.height,
GL_BGRA, // native iOS format
GL_UNSIGNED_BYTE,
0,
texture);
CFRelease(empty);
CFRelease(attrs);
}
- (void)deinitGL {
glDeleteFramebuffers(1, &_frameBuffer);
glDeleteFramebuffers(1, &_depthBuffer);
CFRelease(_target);
CFRelease(_textureCache);
CFRelease(_texture);
}
@end
谁能告诉我为什么这在 iOS 上不起作用,尽管它在 Android 上运行良好?
最佳答案
您已经创建了 GLES2 上下文 (kEAGLRenderingAPIOpenGLES2
),但您正在使用 GLES3 着色器 (#version 300 es
)。
我有点惊讶 glCompileShader
没有捕获到错误,但我猜 iOS 驱动程序正在推迟实际编译,直到 glAttachShader
被调用。
关于ios - OpenGL ES 代码在 Android 中工作,但 glAttachShader 不适用于 iOS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57015669/
我尝试理解[c代码 -> 汇编]代码 void node::Check( data & _data1, vector& _data2) { -> push ebp -> mov ebp,esp ->
我需要在当前表单(代码)的上下文中运行文本文件中的代码。其中一项要求是让代码创建新控件并将其添加到当前窗体。 例如,在Form1.cs中: using System.Windows.Forms; ..
我有此 C++ 代码并将其转换为 C# (.net Framework 4) 代码。有没有人给我一些关于 malloc、free 和 sprintf 方法的提示? int monate = ee; d
我的网络服务器代码有问题 #include #include #include #include #include #include #include int
给定以下 html 代码,将列表中的第三个元素(即“美丽”一词)以斜体显示的 CSS 代码是什么?当然,我可以给这个元素一个 id 或一个 class,但 html 代码必须保持不变。谢谢
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我试图制作一个宏来避免重复代码和注释。 我试过这个: #define GrowOnPage(any Page, any Component) Component.Width := Page.Surfa
我正在尝试将我的旧 C++ 代码“翻译”成头条新闻所暗示的 C# 代码。问题是我是 C# 中的新手,并不是所有的东西都像 C++ 中那样。在 C++ 中这些解决方案运行良好,但在 C# 中只是不能。我
在 Windows 10 上工作,R 语言的格式化程序似乎没有在 Visual Studio Code 中完成它的工作。我试过R support for Visual Studio Code和 R-T
我正在处理一些报告(计数),我必须获取不同参数的计数。非常简单但乏味。 一个参数的示例查询: qCountsEmployee = ( "select count(*) from %s wher
最近几天我尝试从 d00m 调试网络错误。我开始用尽想法/线索,我希望其他 SO 用户拥有可能有用的宝贵经验。我希望能够提供所有相关信息,但我个人无法控制服务器环境。 整个事情始于用户注意到我们应用程
我有一个 app.js 文件,其中包含如下 dojo amd 模式代码: require(["dojo/dom", ..], function(dom){ dom.byId('someId').i
我对“-gencode”语句中的“code=sm_X”选项有点困惑。 一个例子:NVCC 编译器选项有什么作用 -gencode arch=compute_13,code=sm_13 嵌入库中? 只有
我为我的表格使用 X-editable 框架。 但是我有一些问题。 $(document).ready(function() { $('.access').editable({
我一直在通过本教程学习 flask/python http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-wo
我想将 Vim 和 EMACS 用于 CNC、G 代码和 M 代码。 Vim 或 EMACS 是否有任何语法或模式来处理这种类型的代码? 最佳答案 一些快速搜索使我找到了 this vim 和 thi
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve this
这个问题在这里已经有了答案: Enabling markdown highlighting in Vim (5 个回答) 6年前关闭。 当我在 Vim 中编辑包含 Markdown 代码的 READM
我正在 Swift3 iOS 中开发视频应用程序。基本上我必须将视频 Assets 和音频与淡入淡出效果合并为一个并将其保存到 iPhone 画廊。为此,我使用以下方法: private func d
pipeline { agent any stages { stage('Build') { steps { e
我是一名优秀的程序员,十分优秀!