gpt4 book ai didi

c++ - 从 C++ : error 1281 on glUseProgram 使用 openGL ES

转载 作者:太空宇宙 更新时间:2023-11-04 13:34:43 27 4
gpt4 key购买 nike

我正在尝试将一些 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com