- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试将一些 openGL 处理转移到 C++ 类中,该类包装在 Objective-C 类中以用于 iOS。它的大部分似乎都有效,但我没有将渲染结果放入帧缓冲区。当我用 glGetError() 括起每个 openGL 调用时——在 Objective-C 包装器和 C++ 类中——我在调用 glUseProgram 时收到错误 1281 (GL_INVALID_VALUE)(从 C++ 方法 renderTextures 中)。
(FWIW,然后在随后的两次调用中调用 GL_INVALID_OPERATION (1282):glUniform1i 和 glUniformMatrix4fv,如果它们与着色器程序相关联,我认为这是有意义的。附注:我在 glGetError 上使用了一个自定义包装函数,它循环直到返回值为零——这是我得到的仅有的三个错误。)
我可以从帧缓冲区设置和检索任意值(使用 glClearColor 和 glClear 设置它们,并使用 glReadPixels 检索它们),因此帧缓冲区似乎设置正常。但是渲染(通过 glDrawElements)似乎失败了,我想这与我在 glUseProgram 上遇到的错误有关。请注意,glUseProgram 的参数 _program 是通过调用 MyClass::renderTextures 从 Objective-C 包装器传入的。值是相同的(它只是一个句柄,对吗?)但是在 C++ 类中调用失败。
所以...知道为什么 glUseProgram 会失败吗?这是我设置参数_program 的方式吗?我将它从 Objective-C 传递到 C++? (关于从 C++ 内部失去对上下文的访问权的事情?)任何人都可以看到的其他事情?
代码如下(很大程度上基于 Xcode 的样板文件)
Objective-C 包装器:
#import “MyClass.h”
// OBJECTIVE-C WRAPPER CLASS
@interface ObjCWrapperClass () {
MyClass *_myObject;
GLuint _program;
GLint _mvpUniform;
GLint _textureUniform;
GLKMatrix4 _modelViewProjectionMatrix;
}
@property EAGLContext *myContext;
@end
@implementation ObjCWrapperClass
-(id)init {
if (self = [super init]) {
self.myContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
_myObject = new MyClass();
BOOL result = [self loadShaders];
}
return self;
}
-(void)doRender {
// Has to be in Objective-C
[EAGLContext setCurrentContext:self.queryContext];
// ---- Use C++ ------------------------------
// 1. Create frame buffer
_myObject->createFrameBuffer();
// 2. Get Texture List
_myObject->createTextureList();
// 3. Create the Texture Geometry
_myObject->createTextureGeometry();
// 4. Load textures
_myObject->loadTextures();
if ([NSThread isMainThread]) {
[self doRenderInCPP];
}
else {
dispatch_sync(dispatch_get_main_queue(), ^{
[self doRenderInCPP];
} );
}
_myObject->deleteTextures();
// ---- END C++ ------------------------------
}
-(void)doRenderInCPP
{
// Render textures into framebuffer
_myObject->renderTextures(_program, _mvpUniform, _textureUniform);
}
#pragma mark - OpenGL ES 2 shader compilation
- (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 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);
// Bind attribute locations.
// This needs to be done prior to linking.
glBindAttribLocation(_program, GLKVertexAttribPosition, "position");
glBindAttribLocation(_program, GLKVertexAttribTexCoord0, "texCoord");
// Link program.
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;
}
// Get uniform locations.
_mvpUniform = glGetUniformLocation(_program, "modelViewProjectionMatrix");
_textureUniform = glGetUniformLocation(_program, "tileTexture");
// Release vertex and fragment shaders.
if (vertShader) {
glDetachShader(_program, vertShader);
glDeleteShader(vertShader);
}
if (fragShader) {
glDetachShader(_program, fragShader);
glDeleteShader(fragShader);
}
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;
}
@end
C++(相关位):
//
// MyClass.cpp
//
#include “MyClass.h”
void MyClass::createFrameBuffer()
{
glGenFramebuffers(1, &_frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, _frameBuffer);
// Create the texture:
glGenTextures(1, &_frameBufferTexture);
glBindTexture(GL_TEXTURE_2D, _frameBufferTexture);
glTexImage2D(GL_TEXTURE_2D, 0, _drawFormatEnum, _destinationSizeWidth, _destinationSizeHeight, 0, _drawFormatEnum, GL_UNSIGNED_BYTE, NULL);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _frameBufferTexture, 0);
GLenum error = glGetError();
if (error != 0) {
printf("Error Creating Depth Buffer: %i (backing size: %i %i)\n", error, _destinationSizeWidth, _destinationSizeHeight);
}
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
printf("Failed to make complete framebuffer object %x\n", glCheckFramebufferStatus(GL_FRAMEBUFFER));
}
glClearColor(0.015625, 0.03125, 0.0, 1.0); // For testing - put distinctive values in to see if we find these in Framebuffer
glClear(GL_COLOR_BUFFER_BIT);
}
void MyClass::renderTextures(GLint program, GLint mvpUniform, GLint textureUniform)
{
// Clear the draw buffer
glClearColor(0.0, 0.0, 0.0625, 1.0); // TEST: clear to distinctive values
glClear(GL_COLOR_BUFFER_BIT);
// Draw each segment in a different area of frame buffer
for (int segment_index = 0; segment_index < _numSegments; segment_index++) {
// Set draw region
glScissor(segment_index*(_segmentWidthPixels), 0, _segmentWidthPixels, _segmentHeightPixels);
glEnable(GL_SCISSOR_TEST);
int segment_horz_offset = getSegmentHorzOffset(segment_index);
int segment_vert_offset = getSegmentVertOffset(segment_index);
FFGLKMatrix4 modelViewProjectionMatrix = createMVPmatrix(segment_horz_offset, segment_vert_offset);
// Render the object ES2
glUseProgram(program); // Error after glUseProgram:, GL_INVALID_VALUE (1281)
glUniform1i(textureUniform, 0); //GL_INVALID_OPERATION (1282)
glUniformMatrix4fv(mvpUniform, 1, 0, modelViewProjectionMatrix.m); //GL_INVALID_OPERATION (1282)
glEnableVertexAttribArray(FFGLKVertexAttribPosition);
glEnableVertexAttribArray(FFGLKVertexAttribTexCoord0);
glActiveTexture(GL_TEXTURE0);
for (auto &texture: _textures) {
uint8_t *data = (uint8_t *)texture.geometryData;
glVertexAttribPointer(FFGLKVertexAttribPosition, 2, GL_FLOAT, 0, sizeof(float)*4, data);
glVertexAttribPointer(FFGLKVertexAttribTexCoord0, 2, GL_FLOAT, 0, sizeof(float)*4, data+8);
glBindTexture(GL_TEXTURE_2D, texture.getTextureID());
glDrawElements(GL_TRIANGLE_STRIP, _textureVertexIndicesCount, GL_UNSIGNED_SHORT, _textureVertexIndices);
}
glDisable((GL_SCISSOR_TEST));
// Test - are correct values rendered into the frame buffer?
uint8_t *outdata = new uint8_t[100*4];
glReadPixels(0, 0, (GLsizei)2, (GLsizei)4, GL_RGBA, GL_UNSIGNED_BYTE, outdata);
for (int i=0; i < 8; i++) {
printf("render: Value: %i\n", outdata[i]); // Prints values as specified in glClearColor above (0,0,16,255)
}
printf("glGetError: %d\n", glGetError() );
delete [] outdata;
}
最佳答案
错误 1281 已解决(openGL 新手错误)- 需要设置上下文:
(仍未渲染到帧缓冲区中,但另一个障碍已清除。)
-(id)init {
if (self = [super init]) {
self.myContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
[EAGLContext setCurrentContext:self.myContext]; // <-- ADDED
_myObject = new MyClass();
BOOL result = [self loadShaders];
}
return self;
}
关于c++ - 从 C++ : error 1281 on glUseProgram 使用 openGL ES,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30017507/
reqwest v0.9 将 serde v1.0 作为依赖项,因此实现 converting serde_json errors into reqwest error . 在我的代码中,我使用 se
我有这个代码: let file = FileStorage { // ... }; file.write("Test", bytes.as_ref()) .map_err(|e| Mu
我只是尝试用angular-cli创建一个新项目,然后运行服务器,但是它停止并显示一条有趣的消息:Error: No errors。 我以这种方式更新了(希望有帮助):npm uninstall -g
我从我的 javascript 发送交易 Metamask 打开传输对话框 我确定 i get an error message in metamask (inpage.js:1 MetaMask -
这个问题在这里已经有了答案: How do you define custom `Error` types in Rust? (3 个答案) How to get a reference to a
我想知道两者之间有什么大的区别 if let error = error{} vs if error != nil?或者只是人们的不同之处,比如他们如何用代码表达自己? 例如,如果我使用这段代码: u
当我尝试发送超过 50KB 的图像时,我在 Blazor 服务器应用程序上收到以下错误消息 Error: Connection disconnected with error 'Error: Serv
我有一个error-page指令,它将所有异常重定向到错误显示页面 我的web.xml: [...] java.lang.Exception /vi
我有这样的对象: address: { "phone" : 888, "value" : 12 } 在 WHERE 中我需要通过 address.value 查找对象,但是在 SQL 中有函数
每次我尝试编译我的代码时,我都会遇到大量错误。这不是我的代码的问题,因为它在另一台计算机上工作得很好。我尝试重新安装和修复,但这没有帮助。这是整个错误消息: 1>------ Build starte
在我的代码的类部分,如果我写一个错误,则在不应该的情况下,将有几行报告为错误。我将'| error'放在可以从错误中恢复的良好/安全位置,但是我认为它没有使用它。也许它试图在某个地方恢复中间表情? 有
我遇到了 csv 输入文件整体读取故障的问题,我可以通过在 read_csv 函数中添加 "error_bad_lines=False" 来删除这些问题来解决这个问题。 但是我需要报告这些造成问题的文
在 Spring 中,验证后我们在 controller 中得到一个 BindingResult 对象。 很简单,如果我收到验证错误,我想重新显示我的表单,并在每个受影响的字段上方显示错误消息。 因此
我不知道出了什么问题,因为我用 Java 编程了大约一年,从来没有遇到过这个错误。在一分钟前在 Eclipse 中编译和运行工作,现在我得到这个错误: #A fatal error has been
SELECT to_char(messages. TIME, 'YYYY/MM/DD') AS FullDate, to_char(messages. TIME, 'MM/DD
我收到这些错误: AnonymousPath\Anonymized.vb : error BC30037: Character is not valid. AnonymousPath\Anonymiz
我刚刚安装了 gridengine 并在执行 qstat 时出现错误: error: commlib error: got select error (Connection refused) erro
嗨,我正在学习 PHP,我从 CRUD 系统开始,我在 Windows 上安装了 WAMP 服务器,当我运行它时,我收到以下错误消息。 SCREAM: Error suppression ignore
我刚刚开始一个新项目,我正在学习核心数据教程,可以找到:https://www.youtube.com/watch?v=zZJpsszfTHM 我似乎无法弄清楚为什么会抛出此错误。我有一个名为“Exp
当我使用 Jenkins 运行新构建时,出现以下错误: "FilePathY\XXX.cpp : fatal error C1853: 'FilePathZ\XXX.pch' precompiled
我是一名优秀的程序员,十分优秀!