텍스처의 조각 셰이더
-
19-09-2019 - |
문제
프로그램에 후 처리 기능을 추가하려고합니다. 렌더링은 OpenGL을 사용하여 수행됩니다. 나는 단지 프로그램이 홈 만든 조각 셰이더를로드하여 비디오 스트림에서 사용하도록 허용하고 싶습니다.
나는 "OpenGL Shad 셰이더는 셰이더 빌더에서 잘 작동하지만 메인 프로그램에서는 작동하지 않습니다. 화면은 모든 검은 색을 유지합니다.
설정은 다음과 같습니다.
@implementation PluginGLView
- (id) initWithCoder: (NSCoder *) coder
{
const GLubyte * strExt;
if ((self = [super initWithCoder:coder]) == nil)
return nil;
glLock = [[NSLock alloc] init];
if (nil == glLock) {
[self release];
return nil;
}
// Init pixel format attribs
NSOpenGLPixelFormatAttribute attrs[] =
{
NSOpenGLPFAAccelerated,
NSOpenGLPFANoRecovery,
NSOpenGLPFADoubleBuffer,
0
};
// Get pixel format from OpenGL
NSOpenGLPixelFormat* pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
if (!pixFmt)
{
NSLog(@"No Accelerated OpenGL pixel format found\n");
NSOpenGLPixelFormatAttribute attrs2[] =
{
NSOpenGLPFANoRecovery,
0
};
// Get pixel format from OpenGL
pixFmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs2];
if (!pixFmt) {
NSLog(@"No OpenGL pixel format found!\n");
[self release];
return nil;
}
}
[self setPixelFormat:[pixFmt autorelease]];
/*
long swapInterval = 1 ;
[[self openGLContext]
setValues:&swapInterval
forParameter:NSOpenGLCPSwapInterval];
*/
[glLock lock];
[[self openGLContext] makeCurrentContext];
// Init object members
strExt = glGetString (GL_EXTENSIONS);
texture_range = gluCheckExtension ((const unsigned char *)"GL_APPLE_texture_range", strExt) ? GL_TRUE : GL_FALSE;
texture_hint = GL_STORAGE_SHARED_APPLE ;
client_storage = gluCheckExtension ((const unsigned char *)"GL_APPLE_client_storage", strExt) ? GL_TRUE : GL_FALSE;
rect_texture = gluCheckExtension((const unsigned char *)"GL_EXT_texture_rectangle", strExt) ? GL_TRUE : GL_FALSE;
// Setup some basic OpenGL stuff
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Loads the shaders
shader=LoadShader(GL_FRAGMENT_SHADER,"/Users/alexandremathieu/fragment.fs");
program=glCreateProgram();
glAttachShader(program, shader);
glLinkProgram(program);
glUseProgram(program);
[NSOpenGLContext clearCurrentContext];
[glLock unlock];
image_width = 1024;
image_height = 512;
image_depth = 16;
image_type = GL_UNSIGNED_SHORT_1_5_5_5_REV;
image_base = (GLubyte *) calloc(((IMAGE_COUNT * image_width * image_height) / 3) * 4, image_depth >> 3);
if (image_base == nil) {
[self release];
return nil;
}
// Create and load textures for the first time
[self loadTextures:GL_TRUE];
// Init fps timer
//gettimeofday(&cycle_time, NULL);
drawBG = YES;
// Call for a redisplay
noDisplay = YES;
PSXDisplay.Disabled = 1;
[self setNeedsDisplay:true];
return self;
}
그리고 다음은 "렌더 화면"기능이 기본적으로 ... 화면을 렌더링합니다.
- (void)renderScreen
{
int bufferIndex = whichImage;
glBindTexture(GL_TEXTURE_RECTANGLE_EXT, bufferIndex+1);
glUseProgram(program);
int loc=glGetUniformLocation(program, "texture");
glUniform1i(loc,bufferIndex+1);
glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, image_width, image_height, GL_BGRA, image_type, image[bufferIndex]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2f(-1.0f, 1.0f);
glTexCoord2f(0.0f, image_height);
glVertex2f(-1.0f, -1.0f);
glTexCoord2f(image_width, image_height);
glVertex2f(1.0f, -1.0f);
glTexCoord2f(image_width, 0.0f);
glVertex2f(1.0f, 1.0f);
glEnd();
[[self openGLContext] flushBuffer];
[NSOpenGLContext clearCurrentContext];
//[glLock unlock];
}
그리고 마지막으로 여기에 셰이더가 있습니다.
uniform sampler2DRect texture;
void main() {
vec4 color, texel;
color = gl_Color;
texel = texture2DRect(texture, gl_TexCoord[0].xy);
color *= texel;
// Begin Shader
float gray=0.0;
gray+=(color.r + color.g + color.b)/3.0;
color=vec4(gray,gray,gray,color.a);
// End Shader
gl_FragColor = color;
}
이 셰이더로 화면을 모두 빨간색으로 돌릴 수 있기 때문에 셰이더의 로딩 및 사용이 작동합니다.
void main(){
gl_FragColor=vec4(1.0,0.0,0.0,1.0);
}
셰이더에 구문 오류가 포함 된 경우 LoadShader 함수 등에서 오류 메시지가 나타납니다. 셰이더 사용을 제거하면 모든 것이 정상적으로 작동합니다.
문제는 "텍스처를 균일 한 매개 변수로 전달하는"것에서 발생한다고 생각합니다. 그러나 이것들은 OpenGL과의 첫 단계이며 아무것도 확신 할 수 없습니다.
주저하지 말고 더 많은 정보를 요청하십시오.
감사합니다 O.
해결책
텍스처 샘플러는 활성 텍스처 유닛의 수로 설정해야합니다. 예를 들어 GlactiveTexture (GL_TEXTURE3)의 경우 샘플러도 3으로 설정해야합니다. 귀하의 경우 숫자는 0이어야합니다.
제휴하지 않습니다 StackOverflow