第一个OpenGL程序从红皮书里面一个Mac OS Cocoa NSOpenGLView [英] First OpenGL program from the Red book inside a 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屋!