OpenGL和Cocoa不工作

时间:2013-07-17 03:36:42

标签: macos cocoa opengl nsopenglview

我正在尝试使用Mountain Lion上的NSOpenGL在OpenGL中绘制一个带有红色背景的非常简单的蓝色方块。代码很简单,应该可以工作,我假设我在设置上下文时遇到了问题。

这是我的GLView界面:

#import <Cocoa/Cocoa.h>
#import <OpenGL/gl.h>
#import <GLKit/GLKit.h>

typedef struct {
    char *Name;
    GLint Location;
} Uniform;

@interface MyOpenGLView : NSOpenGLView {
    Uniform *_uniformArray;
    int _uniformArraySize;
    GLKMatrix4 _projectionMatrix;
    GLKMatrix4 _modelViewMatrix;
    IBOutlet NSWindow *window;
    int height, width;
}

-(void)drawRect:(NSRect)bounds;

@end

实施:

GLfloat square[] = {
    -0.5, -0.5,
    0.5, -0.5,
    -0.5, 0.5,
    0.5, 0.5
};

- (id)initWithFrame:(NSRect)frame {
    self = [super initWithFrame:frame];
    if (self) {

    }
    return self;
}

-(void)awakeFromNib {
    NSString *vertexShaderSource = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"VertexShader" ofType:@"vsh"] encoding:NSUTF8StringEncoding error:nil];

    const char *vertexShaderSourceCString = [vertexShaderSource cStringUsingEncoding:NSUTF8StringEncoding];
    NSLog(@"%s",vertexShaderSourceCString);

    NSString *fragmentShaderSource = [NSString stringWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"FragmentShader" ofType:@"fsh"] encoding:NSUTF8StringEncoding error:nil];
    const char *fragmentShaderSourceCString = [fragmentShaderSource cStringUsingEncoding:NSUTF8StringEncoding];

    NSLog(@"%s",fragmentShaderSourceCString);

    NSOpenGLContext *glContext = [self openGLContext];
    [glContext makeCurrentContext];

    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSourceCString, NULL);
    glCompileShader(fragmentShader);

    GLint compileSuccess;
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compileSuccess);
    if (compileSuccess == GL_FALSE) {
        GLint logLength;
        glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &logLength);
        if(logLength > 0) {
            GLchar *log = (GLchar *)malloc(logLength);
            glGetShaderInfoLog(fragmentShader, logLength, &logLength, log);
            NSLog(@"Shader compile log:\n%s", log);
            free(log);
        }
        exit(1);
    }

    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSourceCString, NULL);
    glCompileShader(vertexShader);

    GLuint program = glCreateProgram();
    glAttachShader(program, fragmentShader);
    glAttachShader(program, vertexShader);
    glLinkProgram(program);

    glUseProgram(program);

    const char *aPositionCString = [@"a_position" cStringUsingEncoding:NSUTF8StringEncoding];
    GLuint aPosition = glGetAttribLocation(program, aPositionCString);

    glVertexAttribPointer(aPosition, 2, GL_FLOAT, GL_FALSE, 0, square);
    glEnable(aPosition);

    GLint maxUniformLength;
    GLint numberOfUniforms;
    char *uniformName;

    glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &numberOfUniforms);
    glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformLength);

    _uniformArray = malloc(numberOfUniforms * sizeof(Uniform));
    _uniformArraySize = numberOfUniforms;

    for (int i =0; i <numberOfUniforms; i++) {
        GLint size;
        GLenum type;
        GLint location;

        uniformName = malloc(sizeof(char*)*maxUniformLength);
        glGetActiveUniform(program, i, maxUniformLength, NULL, &size, &type, uniformName);
        _uniformArray[i].Name = uniformName;
        location = glGetUniformLocation(program, uniformName);
        _uniformArray[i].Location = location;
    }

    _modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 0.0f);
    _projectionMatrix = GLKMatrix4MakeOrtho(-1, 1, -1.5, 1.5, -1, 1);
}

- (void)drawRect:(NSRect)bounds {
    glClearColor(1.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    glViewport(0, 0, 480, 360);

    for (int i = 0; i <_uniformArraySize; i++) {
        if (strcmp(_uniformArray[i].Name, "ModelViewProjectionMatrix")==0) {
            // Multiply the transformation matrices together
            GLKMatrix4 modelViewProjectionMatrix = GLKMatrix4Multiply(_projectionMatrix,        _modelViewMatrix);
            glUniformMatrix4fv(_uniformArray[i].Location, 1, GL_FALSE,           modelViewProjectionMatrix.m);
        }
    }
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glFlush();
}

我非常简单的片段着色器:

void main() {
    gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}

简单顶点着色器:

attribute vec4 a_position;

uniform mat4 ModelViewProjectionMatrix;

void main() {
    gl_Position = a_position * ModelViewProjectionMatrix;
}

我没有编译错误,只是一个红色的屏幕,没有蓝色方块。请有人帮我弄清楚什么是错的。我确实收到警告,说明Gl.h和gl3.h都包括在内。我想使用OpenGL 2

1 个答案:

答案 0 :(得分:0)

您的视图矩阵在哪里(AKA是您的观察矩阵)?对于我的NSOpenGLView,我至少有三个矩阵,模型视图(由旋转和平移矩阵的乘法结果组成),投影矩阵(考虑到你的平截头体尺度,纵横比,近平面和远平面) )和视图矩阵(其考虑了观众在“世界”中的眼睛位置,焦点和向上矢量的方向)。我会说将代码放在awakeFromNib中,并告诉我一些事情......