码迷,mamicode.com
首页 > 其他好文 > 详细

【计算机图形学】OpenGL+VS2015相关类库配置

时间:2016-06-12 02:29:59      阅读:692      评论:0      收藏:0      [点我收藏+]

标签:

1 WiKi

OpenGL一直是事实上的计算机图形学标准,截止2016年06月,OpenGL版本已经更新到4.5。不过DirectX发展迅速,大有OpenGL落后的态势,知乎上的该话题的讨论:https://www.zhihu.com/question/23241456。所以OpenGL为了追赶DirectX,推出 了glNext(Vulkan API),相关讨论https://www.zhihu.com/question/28039310

2 相关资料

图形学的经典书籍是《Computer Graphics with OpenGL》,即《计算机图形学》,以OpenGL描述,在介绍图形学基础理论的同时,也提供了OpengGL的相关API和实例程序。目前(2016年6月)本书已经更新到第4版。网上第3版的PDF文档比较多,尚未发现第4版的PDF文档,不过第3版和第4版差别很小,第4版重要的更新是提供了GLSL的一个章节。
《计算机图形学》的重要性在于全面的理论知识,不过它基本不涉及Shader编程,仍然沿用固定管程的教学内容,然而当前的OpengGL都是Shader编程,读完本书你会发现对Shader了解很少。
下面三本书都是Shader编程。
《OpenGL超级宝典》和《OpenGL编程指南》是两本实用的OpengGL学习书籍,区别在于前者有更多实例,更容易按步骤进行操作,而后者着重介绍API,最好先阅读前者。
《OpenGL 4.0 Shading Language Cookbook.pdf》主要介绍Shader编程。
《OpenGL 4.0 Shading Language Cookbook.pdf》下载地址:http://download.csdn.net/detail/brillianteagle/9541959

3 相关库文件

3.1 gl、glu和glut

《计算机图形学》详细介绍了3个类库,总结起来就是
glu库:函数glu开头,设置视景和投影矩阵、用线和多边形近似法来描述对象、用线性近似法描述quadric和B-spline,处理表面绘制操作。
glut库:跨平台套件,包括了窗口操作、输入管理。
注意,包括GLUT头文件就不必包括GL和GLU头文件。
配置好这三个库就可以运行《计算机图形学》中所有的实例,但是不能进行Shader编程。

3.2 glew和freeglut

GLU库获得是比较陈旧的OpenGL API版本,可以从glew获得最新的OpenGL API版本。freeglut则是用来取代glut库的。
所以,配置好glew和freeglut两个库,完全取代glu和glut库,同时可以获得最新版本的API,可以进行Shader编程。

3.3 GLTools

GLTools是《OpenGL超级宝典》作者提供的工具包,在运行本书的实例时要用到。

3.4 GLM

GLM (OpenGL Mathematics) 也是一个工具包,在运行《OpenGL 4.0 Shading Language Cookbook.pdf》的程序时会用到。

4 库文件配置

一般配置都有两种方式,要么相关文件放到VC目录下,这样不必每次都配置;要么相关文件放到工程目录下,并包含头文件目录和lib文件目录,这样程序在在其他电脑上也可以打开。各有好处。这里介绍第二种方式。

4.1 glew和freeglut配置

glew官网:http://glew.sourceforge.net/
glew官方GitHub主页:https://github.com/nigels-com/glew
freeglut官网:https://sourceforge.net/projects/freeglut/
下载glew的最新Binaries版本(截止2016年6月9日的)为glew-1.13.0-win32.zip,freeglut最新版本为3.0版本freeglut-MSVC-3.0.0-2.mp.zip。
在VS2015中新建VC控制台程序OpenGL-Demo,在【工程目录】下新建GL文件夹和lib文件夹,然后执行下面四个步骤:
(1) 将glew-1.13.0-win32\glew-1.13.0\include\GL目录下的头文件和freeglut-MSVC-3.0.0-2.mp\freeglut\include\GL目录下的头文件都放到【工程目录】下新建GL文件夹中;
(2) 将glew-1.13.0-win32\glew-1.13.0\lib\Release\Win32目录下的glew32.lib文件和freeglut-MSVC-3.0.0-2.mp\freeglut\lib目录下的freeglut.lib放到【工程目录】下新建lib文件夹中,这里要注意,我使用的是32位版本的lib包,即便我的电脑是64位的。因为我们建立的VC工程默认是32位的。
(3) 将glew-1.13.0-win32\glew-1.13.0\bin\Release\Win32目录下的glew32.dll和freeglut-MSVC-3.0.0-2.mp\freeglut\bin目录下的freeglut.dll放到工程目录下。
(4) 在项目上右键菜单中打开配置,设置附加头文件目录和附加lib文件目录,如图。注意,$(ProjectDir)就是当前目录的意思。
技术分享
技术分享
可以用以下代码测试一下,绘制一个白色背景的窗口:

// OpenGL-Demo.cpp : Defines the entry point for the console application.
//
#pragma comment(lib,"glew32.lib")
#include <glew.h>
#include <freeglut.h>
#include <iostream>
using namespace std;
/* GLUT callback Handlers */

static void resize(GLint width, GLint height) {
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0, (GLdouble)width, 0.0, (GLdouble)height);
    glClear(GL_COLOR_BUFFER_BIT);
}
/**绘制 函数,这里是空的*/
static void display() {
}
/**更换屏幕颜色设定矩阵模式
选择正摄投影的范围*/
static void init() {
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0, 200.0, 0.0, 150.0);//窗口的左下角是原点
}
/* Program entry point */

int main(int argc, char *argv[]) {
    glutInit(&argc, argv);
    glutInitWindowSize(640, 480);
    glutInitWindowPosition(100, 100);//相对屏幕的左上角
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);//正在使用单个帧缓存,颜色模式//为RGB,这是默认的颜色模式
    glutCreateWindow("Draw Curves");
    init();
    if (glewInit() == GLEW_OK) {
        cout << "glew初始化成功!" << endl;
    }
    glutDisplayFunc(display);
    glutReshapeFunc(resize);
    glutMainLoop();
}

4.2 GLTools生成

这个库由《OpenGL超级宝典》的作者提供,但是需要自己进行编译使用。这里我将本书源码进行了上传。
part1下载地址:http://download.csdn.net/detail/brillianteagle/9545333
part2下载地址:http://download.csdn.net/detail/brillianteagle/9545335
只有两个都下载后才能解压。解压后SB5\Src目录下就有GLTools文件夹。该文件夹的目录下有include和src两个文件夹。由于GLTools的编译依赖于glew,可以看到SB5\Src\GLTools\include\GL目录下就是某个版本的glew头文件,而SB5\Src\GLTools\src目录下有glew.c源文件。
由于我们已经采用了glew的1.13版本,所以这里要替换SB5\Src\GLTools\include\GL目录下的所有头文件,并采用1.13版本glew.c源文件。在glew的官网http://glew.sourceforge.net/下载Source版本,替换SB5\Src\GLTools\src目录下有glew.c源文件。
在VS2015中新建VC静态库程序GLTools,然后按下面步骤配置工程:
(1)将 SB5\Src\GLTools的include文件夹放到【工程目录】下,将SB5\Src\GLTools\src目录下的源文件放到【工程目录】下;
(2)将SB5\Src\GLTools\src目录下的所有源文件放到【工程目录】下;
(3)在工程上点击右键菜单中的属性,添加头文件。
技术分享
然后,就可以在relseas模式下编译该工程,结束后GLTools\Release目录下生成GLTools.lib。

4.3 GLTools配置

如何把GLTools集成到自己的工程呢?
在之前的OpenGL-Demo【项目目录】下新建GLTools文件夹。
(1) 将更新过glew最新版本的SB5\Src\GLTools的include文件夹下的所有文件拷贝到GLTools文件夹,并删除【项目目录】的GL文件夹,因为此时GL文件夹已经存在于GLTools目录下。
(2) 将GLTools.lib添加到lib文件夹。
(3) 更改附加头文件目录(ProjectDir)GL(ProjectDir) GLTools
值得注意的是,GLTools依赖于glew,所有,在添加GLTools到自己的工程时要注意依赖关系。这样,引入GLTools,也就引入了glew。
测试一下《OpengGL超级宝典(第5版)》的第一个例子,蓝色背景下绘制红色三角形。

// OpenGL-Demo.cpp : Defines the entry point for the console application.
// Created by 曹艳丰
//2016-06-09
//#pragma comment(lib,"glew32.lib")//不用

#pragma comment(lib,"GLTools.lib")

//#include <glew.h>//不用
#include <GLTools.h>
#include <GLShaderManager.h>
#include <GL\freeglut.h>
GLBatch triangleBatch;
GLShaderManager shaderManager;
///////////////////////////////////////////////////////////////////////////////  
// Window has changed size, or has just been created. In either case, we need  
// to use the window dimensions to set the viewport and the projection matrix.  
void ChangeSize(int w, int h)
{
    glViewport(0, 0, w, h);
}


///////////////////////////////////////////////////////////////////////////////  
// This function does any needed initialization on the rendering context.   
// This is the first opportunity to do any OpenGL related tasks.  
void SetupRC()
{
    // Blue background  
    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);

    shaderManager.InitializeStockShaders();

    // Load up a triangle  
    GLfloat vVerts[] = { -0.5f, 0.0f, 0.0f,
        0.5f, 0.0f, 0.0f,
        0.0f, 0.5f, 0.0f };

    triangleBatch.Begin(GL_TRIANGLES, 3);
    triangleBatch.CopyVertexData3f(vVerts);
    triangleBatch.End();
}



///////////////////////////////////////////////////////////////////////////////  
// Called to draw scene  
void RenderScene(void)
{
    // Clear the window with current clearing color  
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    GLfloat vRed[] = { 1.0f, 0.0f, 0.0f, 1.0f };
    shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vRed);
    triangleBatch.Draw();

    // Perform the buffer swap to display back buffer  
    glutSwapBuffers();
}


///////////////////////////////////////////////////////////////////////////////  
// Main entry point for GLUT based programs  
int main(int argc, char* argv[])
{
    gltSetWorkingDirectory(argv[0]);

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
    glutInitWindowSize(800, 600);
    glutCreateWindow("Triangle");
    glutReshapeFunc(ChangeSize);
    glutDisplayFunc(RenderScene);

    GLenum err = glewInit();
    if (GLEW_OK != err) {
        fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
        return 1;
    }

    SetupRC();

    glutMainLoop();
    return 0;
}

4.4 GLM配置

GLM只有头文件,只需要在官网下载后解压,glm-master\glm-master目录下的glm放到OpenGL-Demo【工程目录】下,并添加$(ProjectDir)glm即可。
glm官网:https://sourceforge.net/projects/ogl-math/
下面是《OpenGL 4.0 Shading Language Cookbook.pdf》中第一个例子,也是绘制三角形。

#pragma comment(lib,"glew32.lib")//这里要加载该静态包
#include <GL/glew.h>
#include <GL/glut.h>
#include <glm\glm.hpp>//斜杠和反斜杠都可以
#include <iostream>

/*
完整的shader过程。
初始化→编译→链接到程序
*/
using namespace std;

/*传入shader的引用,和GLSL字符串,对shader进行编译*/
void compileShader(GLint& shader, const GLchar* shaderCode) {
    const GLchar* codeArray[] = { shaderCode };
    glShaderSource(shader, 1, codeArray, NULL);
    glCompileShader(shader);//编译shader

                            /*判断编译后的结果*/
    GLint result;
    glGetShaderiv(shader, GL_COMPILE_STATUS, &result);

    if (result == GL_FALSE) {
        cout << "shader编译错误!" << endl;
        GLint logLen;
        glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLen);

        if (logLen>0) {
            char* log = (char*)malloc(logLen);
            GLsizei written;
            glGetShaderInfoLog(shader, logLen, &written, log);
            cout << log << endl;
            free(log);

        }
        exit(1);
    }
    else
    {
        cout << "shader编译成功!" << endl;
    }
}
void render(GLuint programHandle) {
    float positionData[] = {
        -0.8f, -0.8f, 0.0f,
        0.8f, -0.8f, 0.0f,
        0.0f, 0.8f, 0.0f
    };
    float colorData[] = {
        1.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 1.0f
    };

    GLuint vboHandle[2];
    glGenBuffers(2, vboHandle);
    GLuint positionbufferHandle = vboHandle[0];
    GLuint colorBufferHandle = vboHandle[1];
    glBindBuffer(GL_ARRAY_BUFFER, positionbufferHandle);
    glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), positionData, GL_STATIC_DRAW);//绑定顶点数据
    glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
    glBufferData(GL_ARRAY_BUFFER, 9 * sizeof(float), colorData, GL_STATIC_DRAW);//绑定颜色数据

    GLuint vaoHandle;
    glGenVertexArrays(1, &vaoHandle);
    glBindVertexArray(vaoHandle);
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glBindBuffer(GL_ARRAY_BUFFER, positionbufferHandle);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL);
    glBindBuffer(GL_ARRAY_BUFFER, colorBufferHandle);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (GLubyte*)NULL);
    glBindVertexArray(vaoHandle);
    //  绘制三角形
    glDrawArrays(GL_TRIANGLES, 0, 3);
    glFlush();


}
void link() {
    //判断glew是否能初始化
    if (glewInit() != GLEW_OK) {
        cout << "glewInit()失败!" << endl;
        exit(1);
    }
    /*编译vertexShader*/
    const GLchar* shaderCode = "#version 400 \n in vec3 VertexPosition;in vec3 VertexColor;out vec3 Color;void main() {Color = VertexColor;gl_Position = vec4(VertexPosition, 1.0);}";
    GLint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    if (vertexShader == 0) {
        cout << "vertexShader无法获取!" << endl;
        exit(1);
    }
    compileShader(vertexShader, shaderCode);

    /*编译fragmentShader*/
    const GLchar* fragmentCode = "#version 400 \n in vec3 Color;out vec4 FragColor;void main() {FragColor=vec4(Color,1.0);}";
    GLint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    if (fragmentShader == 0) {
        cout << "fragmentShader无法获取!" << endl;
        exit(1);
    }
    compileShader(fragmentShader, fragmentCode);

    /*获得程序programHandle*/
    GLuint programHandle = glCreateProgram();
    if (programHandle == 0)
    {
        cout << "Program无法获取!" << endl;
        exit(1);

    }
    /*将shader链接到programHandle*/
    glAttachShader(programHandle, vertexShader);
    glAttachShader(programHandle, fragmentShader);
    glBindAttribLocation(programHandle, 0, "VertexPosition");
    glBindAttribLocation(programHandle, 1, "VertexColor");
    glLinkProgram(programHandle);

    /*判断链接状态*/
    GLint status;
    glGetProgramiv(programHandle, GL_LINK_STATUS, &status);
    if (status == GL_FALSE)
    {
        cout << "link失败!" << endl;
        GLint logLen;
        glGetProgramiv(programHandle, GL_INFO_LOG_LENGTH, &logLen);

        if (logLen>0) {
            char* log = (char*)malloc(logLen);
            GLsizei written;
            glGetProgramInfoLog(programHandle, logLen, &written, log);
            cout << log << endl;
            free(log);

        }
        exit(1);
    }
    else {
        cout << "link成功!" << endl;
        glUseProgram(programHandle);//使用该程序
        render(programHandle);
    }
}

int main(int argc, char *argv[])
{
    glutInit(&argc, argv);;
    glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
    glutInitWindowPosition(0, 0);
    glutInitWindowSize(900, 600);
    glutCreateWindow("First GLUT Sample");
    /*link函数是GLSL编写的主体*/
    glutDisplayFunc(link);
    glutMainLoop();
    return 0;
}

【计算机图形学】OpenGL+VS2015相关类库配置

标签:

原文地址:http://blog.csdn.net/brillianteagle/article/details/51623208

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!