第一个OpenGL程序从红皮书里面一个Mac OS Cocoa NSOpenGLView [英] First OpenGL program from the Red book inside a Mac OS Cocoa NSOpenGLView

查看:1523
本文介绍了第一个OpenGL程序从红皮书里面一个Mac OS Cocoa NSOpenGLView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



(一边注意:如果我使用glBegin()和glEnd(),我可以在屏幕上绘制,但如果我使用glDrawArrays

 


importGLView.h
#include< OpenGL / gl3.h>
#include< vector>
#include< iostream>

@implementation GLView

static GLuint shaderProgram; //着色器程序

static GLuint vPosition; // vPosition是顶点着色器输入变量

static GLuint vao1; //顶点数组对象
static GLuint vbo1; //顶点缓冲区对象

const GLuint num_verts = 6; //要绘制的顶点数量

//将要绘制的顶点数据
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.创建OpenGL 4.1上下文
NSOpenGLPixelFormatAttribute attrs [] =
{
NSOpenGLPFADoubleBuffer,
NSOpenGLPFADepthSize,24,
/ /必须指定4.1核心配置文件使用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.编译着色器
GLuint vs;
GLuint fs;

//顶点着色器源
const char * vss =
#version 410 \\\


in vec4 vPosition;

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

// Fragment Shader源
const char * fss =
#version 410 \\\


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

//如果着色器未成功编译,则错误处理
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]);

//我们不再需要着色器了。
glDeleteShader(vs);

//将错误打印到控制台
for(int i = 0; i< infoLog.size(); i ++)
putchar(infoLog [i]);
putchar('\\\
');
}

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

//如果着色器未成功编译,则错误处理
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]);

//我们不再需要着色器了。
glDeleteShader(fs);

//将错误打印到控制台
for(int i = 0; i< infoLog.size(); i ++)
putchar(infoLog [i]);
putchar('\\\
');
}

// 3.附加着色器
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram,vs);
glAttachShader(shaderProgram,fs);
glLinkProgram(shaderProgram);

//程序未成功链接时出错处理
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]);

//将错误打印到控制台
for(int i = 0; i< infoLog.size(); i ++)
putchar(infoLog [i]);
putchar('\\\
');
}

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

glEnableVertexAttribArray(vPosition);

glUseProgram(shaderProgram);

// 4.创建顶点数据
glGenVertexArrays(1,& vao1);
glBindVertextArray(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对象)?



解决方案是什么?



$ b

正确地创建顶点数组对象和顶点缓冲区对象?

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



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



编写一个小代码以设置NSOpenGLView(包括设置OpenGL版本,NSOpenGLView将运行到4.1),红皮书中的triangles.cpp示例正在运行完全在NSOpenGLView内部。


What I want to do is to simply run the first OpenGL program from the Red Book (triangles.cpp) inside a NSOpenGLView, but my app only clears the screen to black and does not draws the required triangles (even though the shaders were compiled successfully).

(One side note: If I use glBegin() and glEnd() I can draw on the screen, but if I use glDrawArrays() nothing got drawn on the screen)

Here's my code:

#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

Can you tell me wether:

Am I creating the OpenGL 4.1 Context correctly (I.e. The NSOpenGLContext object)?

Am I compile/load the shaders correctly?

Am I creating the vertex array object and vertex buffer object correctly?

解决方案

I have managed to get it working by using code from Apple's GLEssentials sample:

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

After writing a little code to set up the NSOpenGLView (including setting the OpenGL version that the NSOpenGLView will run to 4.1), The triangles.cpp example from the Red Book were running perfectly inside the NSOpenGLView.

这篇关于第一个OpenGL程序从红皮书里面一个Mac OS Cocoa NSOpenGLView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆