【问题标题】:First OpenGL program from the Red book inside a Mac OS Cocoa NSOpenGLViewMac OS Cocoa NSOpenGLView 中红皮书中的第一个 OpenGL 程序
【发布时间】:2015-08-22 14:20:06
【问题描述】:

我想要做的是在 NSOpenGLView 中简单地运行红皮书 (triangles.cpp) 中的第一个 OpenGL 程序,但我的应用程序只会将屏幕清除为黑色并且不会绘制所需的三角形(即使着色器编译成功)。

(附注:如果我使用 glBegin() 和 glEnd(),我可以在屏幕上绘制,但如果我使用 glDrawArrays(),则屏幕上什么也没有绘制)

这是我的代码:

#import "GLView.h"
#include <OpenGL/gl3.h>
#include <vector>
#include <iostream>

@implementation GLView

static GLuint shaderProgram; // The shader program

static GLuint vPosition; // vPosition is a vertex shader input variable

static GLuint vao1; // Vertex Array Object
static GLuint vbo1; // Vertex Buffer Object

const GLuint num_verts = 6; // The number of vertices to draw

// The vertex data that will be drawn
GLfloat vertices[num_verts][2] = {
    { -0.90, -0.90 },
    { 0.85, -0.90},
    {-0.90, 0.85},
    {0.90,-0.85},
    {0.90,0.90},
    {-0.85, 0.90}
};

- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];

    // 1. Make an OpenGL 4.1 context
    NSOpenGLPixelFormatAttribute attrs[] =
    {
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFADepthSize, 24,
        // Must specify the 4.1 Core Profile to use OpenGL 4.1
        NSOpenGLPFAOpenGLProfile,
        NSOpenGLProfileVersion4_1Core,
        0
    };

    NSOpenGLPixelFormat *pf = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];

    if (!pf)
    {
        NSLog(@"No OpenGL pixel format");
    }

    NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat:pf shareContext: nil] ;

    [context makeCurrentContext];

    // 2. Compiling the shaders
    GLuint  vs;
    GLuint  fs;

    // Vertex Shader Source
    const char    *vss=
        "#version 410\n"

        "in vec4 vPosition;"

        "void main(void) {"
            "gl_Position = vPosition;"
        "}";

    // Fragment Shader Source
    const char    *fss=
        "#version 410\n"

        "out vec4 fColor;"

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

    vs = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vs, 1, &vss, NULL);
    glCompileShader(vs);

    // Error handling if shader was not compiled successfully 
    GLint isCompiled;
    glGetShaderiv(vs, GL_COMPILE_STATUS, &isCompiled);
    if(isCompiled == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetShaderiv(vs, GL_INFO_LOG_LENGTH, &maxLength);

        std::vector<GLchar> infoLog(maxLength);
        glGetShaderInfoLog(vs, maxLength, &maxLength, &infoLog[0]);

        //We don't need the shader anymore.
        glDeleteShader(vs);

        // Printing the error to console
        for (int i = 0; i < infoLog.size(); i++)
            putchar(infoLog[i]);
        putchar('\n');
    }

    fs = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fs, 1, &fss, NULL);
    glCompileShader(fs);

    // Error handling if shader was not compiled successfully 
    glGetShaderiv(fs, GL_COMPILE_STATUS, &isCompiled);
    if(isCompiled == GL_FALSE)
    {
        GLint maxLength = 0;
        glGetShaderiv(fs, GL_INFO_LOG_LENGTH, &maxLength);

        std::vector<GLchar> infoLog(maxLength);
        glGetShaderInfoLog(fs, maxLength, &maxLength, &infoLog[0]);

        //We don't need the shader anymore.
        glDeleteShader(fs);

        // Printing the error to console
        for (int i = 0; i < infoLog.size(); i++)
            putchar(infoLog[i]);
        putchar('\n');
    }

    // 3. Attach the shaders
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vs);
    glAttachShader(shaderProgram, fs);
    glLinkProgram(shaderProgram);

    // Error handling if program wasn't linked successfully 
    GLint isLinked;
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, (int *)&isLinked);
    if(isLinked == GL_FALSE)
    {
        GLint maxLength = 0;

        glGetProgramiv(shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
        std::vector<GLchar> infoLog(maxLength);

        glGetProgramInfoLog(shaderProgram, maxLength, &maxLength, &infoLog[0]);

        // Printing the error to console
        for (int i = 0; i < infoLog.size(); i++)
            putchar(infoLog[i]);
        putchar('\n');
    }

    vPosition = glGetAttribLocation(shaderProgram, "vPosition");
    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE,
                    0, 0);

    glEnableVertexAttribArray(vPosition);

    glUseProgram(shaderProgram);

    // 4. Creating the vertex data
    glGenVertexArrays(1, &vao1);
    glBindVertexArray(vao1);

    glGenBuffers(1, &vbo1);
    glBindBuffer(GL_ARRAY_BUFFER, vbo1);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    return self;
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glBindVertexArray(vao1);
    glDrawArrays(GL_TRIANGLES, 0, num_verts);

    glFlush();
}

@end

你能告诉我吗:

我是否正确创建了 OpenGL 4.1 上下文(即 NSOpenGLContext 对象)?

我是否正确编译/加载着色器?

我是否正确创建了顶点数组对象和顶点缓冲区对象?

【问题讨论】:

  • 您是否尝试过将 glGetError 放在 OpenGL 调用旁边以跟踪任何返回错误的函数?

标签: c++ objective-c macos cocoa opengl


【解决方案1】:

我已经设法通过使用 Apple 的 GLEssentials 示例中的代码使其工作:

https://developer.apple.com/library/mac/samplecode/GLEssentials/Introduction/Intro.html

在编写了一些设置 NSOpenGLView 的代码(包括将 NSOpenGLView 将运行的 OpenGL 版本设置为 4.1)后,红皮书中的 triangles.cpp 示例在 NSOpenGLView 内完美运行。

【讨论】:

    猜你喜欢
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-05
    • 1970-01-01
    相关资源
    最近更新 更多