OpenGL学习记录(1)

博主分享了作为机械专业毕业生进入IT行业的经历,特别是在一家手机游戏公司工作后开始接触OpenGL的学习。文章提到,虽然公司可能不需要深入学习OpenGL,但个人还是决定自学,并对比了“红皮书”和“蓝宝书”,以及glut和glfw的区别。在Mac上使用Xcode进行开发,博主发现GLTools库对初学者非常有帮助,但也决定不依赖它,而是尝试自己编写基于glfw和OpenGL的简单着色器程序。遇到的问题包括着色器编译错误,可能与OpenGL版本和Mac平台有关,期待得到解答。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    本科毕业了,比较顺利地找到了IT行业的工作,作为一个机械专业的本科生实属不易啊!回想各种面试,还是觉得技术很重要,毕竟IT行业是一个日新月异的行业,需要你持续学习。应届生应该是进入BAT等大公司的最容易的时候了,毕竟才毕业,没有什么工作经验,对你的要求也相应的低得多。通过与公司的交流,因为是一家手机游戏公司,所以需要懂OpenGL(其实我觉得没必要深入学习,毕竟可以再cocos2d基础上进行再封装的嘛!这不是重复造轮子么?),所以就学习了一下。

    当然,首先必须要看的就是“红皮书”和“蓝宝书”了,但是我们学校图书馆的蓝宝书只有第五版,不过貌似现在中文的版本也就只有第五版的吧,不过觉得还是听老的了,用的是glut框架,我用的Mac,从OS X 10.9之后glut就被加入到过时行列了,所以网上查了下,现在都用的glfw代替之,不过就目前来说,感觉这两个之间没什么差别,而且我觉得glut通过函数指针调用自定义渲染函数等的方式比glfw还更好一点,其他的不知。可能是某些技术过于落后了吧。在Mac平台,当然首选的开发工具就是Xcode了,在一番环境配置之后,终于搞定了环境的配置,这里顺便提一下,超级宝典提供的那个GLTools工具库确实方便了很多初学者,可以快速看到实际效果,大大增强信心,相反,红宝书更加注重理论,一开始就开始讲理论,什么缓存之类的,让初学者云里雾里。不过GLTool在mac平台需要自己编译成库,我是编译成的静态库,在terminal用g++编译的。

    超级宝典快速浏览了一下,刚看完着色器,感觉是时候终结一下了,基本上的opengl基础知识都看完了,该上手编写代码了,但是强迫症,不想用超级宝典提供的库,想完全用glfw和opengl来实现,自己编写简单的着色器程序。所以首要的任务当然就是学习glfw,在官网看了glfw的入门教程,大概知道了glfw的使用,就那么几个函数。然后当然就是着色器编写了,我发现直接将超级宝典的着色器来用回编译不过,可能是opengl版本什么的吧,也可能是因为在mac平台,具体位置,貌似超级宝典中的in/out变量限制符不能用。希望知道的人求教一下。所以就用了glfw示例程序的着色器编写形式,然后自己简化了一下。目标就是画一个静态的三角形就好啦,屏蔽掉所有复杂的部分。直接上源码,里面注释也有几个我的疑问,希望大神解答!

    

#include <iostream>
#include <glfw3.h>
using namespace std;
static const char* vertex_shader_text =
"uniform vec4 vCol;\n"
"attribute vec4 vPos;\n"
"varying vec4 color;\n"
"void main()\n"
"{\n"
"    gl_Position = vPos;\n"
"    color = vCol;\n"
"}\n";
static const char* fragment_shader_text =
"varying vec4 color;\n"
"void main()\n"
"{\n"
"    gl_FragColor = vec4(1.0,0,0,1.0);\n"
"}\n";

void errorCallBack(int error,const char* description)
{
    cout<<"Error:"<<error<<" " <<description<<endl;
}
void windowShouldClosedCallBack(GLFWwindow * window)
{
    cout<<"window is going to be closed;\n";
}
 void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GLFW_TRUE);
}
void glfwMain()
{
    if (!glfwInit()) {
        cout<<"glfwInit failed!\n";
    }
    glfwSetErrorCallback(errorCallBack);
    //创建窗口
    GLFWwindow * window = glfwCreateWindow(640,480, "First GLFW", nullptr, nullptr);
    if (!window) {
        cout<<"Create Window Failed \ n";
    }
    glfwMakeContextCurrent(window);
    glfwSetKeyCallback(window, key_callback);
    glfwSetWindowCloseCallback(window, windowShouldClosedCallBack);
    
    int width, height;
    glfwGetFramebufferSize(window, &width, &height);
    glViewport(0, 0, width, height);
    glfwSwapInterval(1000/60.0);
    GLfloat vects[] ={-0.5f,0.5f,0.f,1.0f,
                            0.5f,0.5f,0.f,1.0f,
                            0.f,-0.5f,0.f,1.0f};
    GLuint bufferId = 0;
    //分配bufferID
    glGenBuffers(1, &bufferId);
    //我的理解就是制定这个已经分配的ID是什么类型的buffer,然后就是分配内存
    glBindBuffer(GL_ARRAY_BUFFER, bufferId);
    //将数据传递到这个buffer
    glBufferData(GL_ARRAY_BUFFER, sizeof(vects), vects, GL_STATIC_DRAW);
    //下面的都是着色器的编译和链接
    GLuint vShaderID = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vShaderID, 1, &vertex_shader_text, NULL);
    glCompileShader(vShaderID);
    GLint r = 1;
    glGetShaderiv(vShaderID, GL_COMPILE_STATUS, &r);
    if (r==GL_FALSE) {
        cout<<"Fail to compile vertex shader\n";
    }
        
    GLuint fShaderID = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fShaderID, 1, &fragment_shader_text, NULL);
    glCompileShader(fShaderID);
    glGetShaderiv(fShaderID, GL_COMPILE_STATUS, &r);
    if (r==GL_FALSE) {
        cout<<"Fail to compile fragment shader\n";
    }
    GLuint program = glCreateProgram();
    glAttachShader(program, vShaderID);
    glAttachShader(program, fShaderID);
    glLinkProgram(program);
    //glValidateProgram(program);
    glGetProgramiv(program, GL_LINK_STATUS, &r);
    if (r==GL_FALSE) {
        cout<<"Fail to link program\n";
    }
    
    
    //因为vPos是一个attribute,所以获取attribute的index,传递数据给着色器
    GLuint vPosLoc = glGetAttribLocation(program, "vPos");
    //将着色器变量Index与缓存中的,其实我觉得很奇怪,他怎么知道是哪个buffer,也没有bufferID相关的参数
    glVertexAttribPointer(vPosLoc, 4, GL_FLOAT, GL_FALSE, 0, NULL);
    glEnableVertexAttribArray(vPosLoc);
    
    glClearColor(0.0, 1.0f, 1.0f, 1.0f);
    while (!glfwWindowShouldClose(window)) {
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(program);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    
    glfwDestroyWindow(window);
    glfwTerminate();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值