سؤال

أحاول إضافة بعض قدرات ما بعد المعالجة إلى برنامج. يتم التقديم باستخدام OpenGL. أريد فقط أن اسمح للبرنامج بتحميل بعض الصفحة المنزلية شادت شظية واستخدامها على دفق الفيديو.

كتبت قطعة صغيرة من التظليل باستخدام "OpenGL Shader Builder" الذي يقوم فقط بتحويل الملمس في Grayscale. يعمل التظليل بشكل جيد في منشئ Shader لكنني لا أستطيع أن أجعله يعمل في البرنامج الرئيسي. الشاشات تبقى كلها سوداء.

هنا هو الإعداد:

@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;
}

وهنا وظيفة "الشاشة RENDR" Wich بشكل أساسي ... تقدم الشاشة.

- (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);
}

إذا كان Shader يحتوي على خطأ في بناء الجملة، أحصل على رسالة خطأ من وظيفة Loadshader وما إلى ذلك. إذا قمت بإزالة استخدام Shader، فإن كل شيء يعمل بشكل طبيعي.

أعتقد أن المشكلة تأتي من "تمرير الملمس كمعلمة موحدة". لكن هذه هي خطواتي الأولى مع OpenGL وأنا غير متأكد من أي شيء.

لا تتردد في طلب المزيد من المعلومات.

شكرا لك Stack O.

هل كانت مفيدة؟

المحلول

يجب ضبط عينات الملمس على عدد وحدة الملمس النشطة. لذلك على سبيل المثال مع glactivetexture (gl_texture3) يجب ضبط العينات على 3 كذلك. في حالتك يجب أن يكون الرقم 0.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top