http://johnhany.net/2014/01/environment-for-opengl-with-vs2010/

OpenGL(Open Graphics Library)是一个开放的、跨编程语言、跨平台的API库,提供了大量的针对图形硬件的软件接口,主要用于绘制高性能的二维和三维图形。它的一个子集OpenGL ES主要针对嵌入式系统,比如手机、平板等,目前也开始流行起来。

GLSL(OpenGL Shading Language)是OpenGL 2.0版本开始引入的编程语言,用来编写运行在GPU上的着色程序,以代替之前所采用的固定功能管线(fixed-function pipeline)。直到3.x版本起,固定功能管线被彻底弃用,而完全被基于着色器(shader)的新功能所代替。OpenGL 3.0是最后一个同时存在新老两种功能的版本。

目前OpenGL最新版本是4.4,GLSL的最新版本是4.4。

由于OpenGL本身只包含涉及渲染的核心函数,而不包括平台相关的UI、文件输入输出、键盘鼠标交互等功能,在不同平台上一般采用不同的扩展库来辅助开发。在UNIX、Linux和Mac OS X平台上一般采用GLUT库实现图形界面,但已经很久没有更新了;在Windows平台上,freeglut会更实用一些。因为调用OpenGL的函数时需要频繁地调用和管理函数指针,可以使用GLEW代替这些繁琐的操作,而且GLEW还会根据你的平台决定使用哪些扩展。


检查兼容性

OpenGL版本众多,而且各显卡厂商也有自己开发的扩展库。要想使用某个版本进行开发,既需要显卡本身支持所需的功能,又需要驱动程序能兼容这个版本。决定使用哪一个版本之前,先要用GPU Caps Viewer检查一下支持的OpenGL和GLSL的最高版本和具体支持哪些扩展。我的笔记本比较老,仅能支持OpenGL 3.0和GLSL 1.3。

准备文件

http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip下载GLUT;

https://sourceforge.net/projects/glew/files/glew/1.10.0/glew-1.10.0-win32.zip/download下载GLEW。

可以在http://www.transmissionzero.co.uk/software/freeglut-devel/下载freeglut。为了尽可能减少干扰因素,下文的样例程序没有用freeglut,而仅使用GLUT库。

把解压得到的glutdlls37beta文件夹中的glut.h,和glew-1.10.0-win32\glew-1.10.0\include\GL文件夹中的glew.h、glxew.h、wglew.h共4个文件拷贝到C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\gl目录下。(粗体的2个文件是必需的)

把解压得到的glutdlls37beta文件夹中的glut.libglut32.lib,和glew-1.10.0-win32\glew-1.10.0\lib\Release\Win32文件夹中的glew32.lib、glew32s.lib,还有glew-1.10.0-win32\glew-1.10.0\lib\Release MX\Win32文件夹中的glew32mx.lib、glew32mxs.lib共6个文件拷贝到C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Lib目录下。(粗体的3个文件是必需的)

把解压得到的glutdlls37beta文件夹中的glut.dll、glut32.dll,和glew-1.10.0-win32\glew-1.10.0\bin\Release\Win32文件夹中的glew32.dll拷贝到C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin目录下。(粗体的2个文件是必需的)

如果发现这样运行下面的样例代码时提示缺少lib或dll文件,可以参考这篇文档修改添加文件的位置。

所需的文件也可以在这里下载。

如果想使用freeglut,其.h、.lib和.dll文件的位置与GLUT和GLEW是相同的。


配置工程

打开Visual Studio 2010,新建一个Visual C++的Win32 Console Application,选项使用默认的,即Application Type为Console Application,Additional Options选Precompiled Header,其他选项都不勾选。

打开项目Properties窗口,找到Configuration Properties -> Linker -> Input ->Additional Dependencies,添加glew32.lib。如果使用了freeglut,还要添加freeglut.lib。

如果还使用了freeglut库,还需要在Configuration Properties -> VC++ Directories -> Include Directories中增加 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\freeglut。


样例代码

把下面的代码粘贴到main.cpp文件:

如果使用了freeglut,需要把第8行的“gl/glut.h”改为“freeglut.h”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
#include <stdafx.h>
#include <stdio.h>
#include <stdlib.h>
#include <gl/glew.h>
#ifdef __APPLE__
#  include <gl/glut.h>
#else
#  include <gl/glut.h>
#endif
 
static struct {
    GLuint vertex_buffer, element_buffer, color_buffer;
    GLuint vertex_shader, fragment_shader, program;
    //用于保存CPU端的object名称
 
    struct {
        GLint position;
        GLint inColor;
    } attributes;
    //用于保存GPU端attribute变量的地址
} names;
 
static const GLfloat position_data[] = {
    0.0, 0.6,
    -0.6, -0.4,
    0.6, -0.4
};
static const GLfloat color_data[] = {
    1.0, 0.0, 0.0, 1.0,
    0.0, 1.0, 0.0, 1.0,
    0.0, 0.0, 1.0, 1.0
};
static const GLushort element_data[] = { 0, 1, 2 };
 
static void infoLog(GLuint object, PFNGLGETSHADERIVPROC glGet__iv, PFNGLGETSHADERINFOLOGPROC glGet__InfoLog)
{
    GLint log_length;
    char *log;
 
    glGet__iv(object, GL_INFO_LOG_LENGTH, &log_length);
    log = (char *)malloc(log_length);
    glGet__InfoLog(object, log_length, NULL, log);
    fprintf(stderr, "%s", log);
    free(log);
}
 
void *readShader(const char *filename, GLint *length)
{
    FILE *f = fopen(filename, "r");
    void *buffer;
 
    if (!f) {
        fprintf(stderr, "Unable to open %s for reading\n", filename);
        return NULL;
    }
 
    fseek(f, 0, SEEK_END);
    *length = ftell(f);
    fseek(f, 0, SEEK_SET);
 
    buffer = malloc(*length+1);
    *length = fread(buffer, 1, *length, f);
    fclose(f);
    ((char*)buffer)[*length] = '\0';
 
    return buffer;
}
 
static GLuint initShader(GLenum type, const char *filename)
{
    GLint length;
    GLchar *source = (GLchar *)readShader(filename, &length);
    GLuint shader;
    GLint shader_ok;
 
    if (!source)
        return 0;
 
    shader = glCreateShader(type);
    //创建shader object
    glShaderSource(shader, 1, (const GLchar**)&source, &length);
    //导入shader的代码
    //count - string的行数
    //length - 指向包含string每行字数的数组
    free(source);
    glCompileShader(shader);
    //编译shader代码
 
    glGetShaderiv(shader, GL_COMPILE_STATUS, &shader_ok);
    //查询shader的状态,导出可能的编译错误
    if (!shader_ok) {
        fprintf(stderr, "Failed to compile %s:\n", filename);
        infoLog(shader, glGetShaderiv, glGetShaderInfoLog);
        glDeleteShader(shader);
        getchar();
    }
    return shader;
}
 
static void installShaders(void)
{
    names.vertex_shader = initShader(GL_VERTEX_SHADER, "HelloWorld-vs.glsl");
    names.fragment_shader = initShader(GL_FRAGMENT_SHADER, "HelloWorld-fs.glsl");
 
    GLint program_ok;
    names.program = glCreateProgram();
    glAttachShader(names.program, names.vertex_shader);
    glAttachShader(names.program, names.fragment_shader);
    //把shader依附在同一个program上,以连接两个shader
    glLinkProgram(names.program);
    //链接program,在GPU端创建相应可执行文件,并初始化uniform变量及其地址
    glGetProgramiv(names.program, GL_LINK_STATUS, &program_ok);
    //查询program的状态,并导出可能的错误
    if (!program_ok) {
        fprintf(stderr, "Failed to link shader program:\n");
        infoLog(names.program, glGetProgramiv, glGetProgramInfoLog);
        glDeleteProgram(names.program);
        getchar();
    }
    glUseProgram(names.program);
    //激活program后才能为shader指定uniform变量的值
}
 
static void initBuffers(void)
{
    names.attributes.position = glGetAttribLocation(names.program, "position");
    names.attributes.inColor = glGetAttribLocation(names.program, "inColor");
    //获取GPU端attribute变量的地址保存在本地变量中,用于值的传递
 
    glGenBuffers(1, &names.vertex_buffer);
    //产生1个buffer object的名称,并分配显存空间
    glBindBuffer(GL_ARRAY_BUFFER, names.vertex_buffer);
    //把产生的buffer object与相应target绑定,以改变其值
    glBufferData(GL_ARRAY_BUFFER, sizeof(position_data), position_data, GL_STATIC_DRAW);
    //GL_STATIC_DRAW其他可用参数:
    //STATIC - 长时间不更改的值     DYNAMIC - 需要频繁改变的值      STREAM - 需要偶尔重写整个buffer的值
    //DRAW - 保存于GPU用于绘制的值       READ - 保存于CPU用于读取的值     COPY - 折衷
    glVertexAttribPointer(names.attributes.position, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, (void*)0);
    glEnableVertexAttribArray(names.attributes.position);
 
    glGenBuffers(1, &names.color_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, names.color_buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(color_data), color_data, GL_STATIC_DRAW);
    glVertexAttribPointer(names.attributes.inColor, 4, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*4, (void*)0);
    glEnableVertexAttribArray(names.attributes.inColor);
 
    glGenBuffers(1, &names.element_buffer);
    glBindBuffer(GL_ARRAY_BUFFER, names.element_buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(element_data), element_data, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, names.element_buffer);
}
 
static void idleFunc(void)
{
}
 
static void displayFunc(void)
{
    glClearColor(1.0, 1.0, 1.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);
 
    glDrawElements(GL_TRIANGLE_STRIP, 3, GL_UNSIGNED_SHORT, (void*)0);
 
    glutSwapBuffers();
}
 
int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutInitWindowSize(400, 400);
    glutCreateWindow("Hello World");
    glutIdleFunc(&idleFunc);
    glutDisplayFunc(&displayFunc);
 
    glewInit();
    if (!GLEW_VERSION_2_0) {
        fprintf(stderr, "OpenGL 2.0 not available\n");
        getchar();
    }
    //与glew扩展库相关的函数要在glewInit()后执行
    installShaders();
    initBuffers();
 
    glutMainLoop();
    return 0;
}

在工程内新建一个名为HelloWorld-vs.glsl的文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
#version 130
 
attribute vec2 position;
attribute vec4 inColor;
 
varying vec4 outColor;
void main()
{
    gl_Position = vec4(position, 0.0, 1.0);
    outColor = inColor;
}

再新建一个名为HelloWorld-fs.glsl的文件,内容如下:

1
2
3
4
5
6
7
8
#version 130
 
varying vec4 outColor;
 
void main()
{
    gl_FragColor = outColor;
}

运行结果如下:

Windows7+VS2010下OpenGL的环境配置的更多相关文章

  1. Fedora和Ubuntu下安装OpenGL开发环境配置

    Fedora下OpenGl开发环境配置 开发OpenGL工程需要3个库文件和对应的头文件: libglut.so,libGLU.so,libGL.so, gl.h ,glu.h, glut.h 这些库 ...

  2. Windows7+VS2012下OpenGL 4的环境配置

    系统环境 Windows 7 Ultimate x64,Visual Studio Ultimate 2012 Update 4,和一块支持OpenGL 4.x的显卡. 准备工作 首先用GPU Cap ...

  3. windows7+eclipse+hadoop2.5.2环境配置

    windows7+eclipse+hadoop2.5.2环境配置    一.hadoop集群环境配置 参考我的前一篇文章(ubuntu + hadoop2.5.2分布式环境配置 http://www. ...

  4. 【Objective-C】Windows下Objective-C开发环境配置

    [Objective-C]Windows下Objective-C开发环境配置 ftp://ftpmain.gnustep.org/pub/gnustep/binaries/windows/   最近打 ...

  5. windows下spark开发环境配置

    http://www.cnblogs.com/davidwang456/p/5032766.html windows下spark开发环境配置 --本篇随笔由同事葛同学提供. windows下spark ...

  6. windows下apache+https环境配置

    windows下apache+https环境配置 转 https://www.cnblogs.com/sandaizi/p/7519370.html 1.修改配置文件conf/httpd.conf,去 ...

  7. Linux—CentOS7下python开发环境配置

    CentOS7下python开发环境配置 上一篇博客讲了如何在Centos7下安装python3(https://www.cnblogs.com/zivli/p/9937608.html),这一次配置 ...

  8. Metabase在Windows下的开发环境配置

    Metabase在Windows下的开发环境配置 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} Metabase在Wind ...

  9. deepin linux 下C开发环境配置

    # deepin linux 下C开发环境配置 ## 前言-----------------------------deepin操作系统商店默认提供了 eclipse for c\c++但是系统没有提 ...

随机推荐

  1. 如何在VISIO 2010/2013 中关闭Shape protection(图形保护)

    最近在画UML图,用到MS visio 2010, 在使用一些网络查找到的图形的时候发现无法编辑,在网上找了找,翻译了下. Visio 2013 的图形保护功能,可以锁定图形的某些特定属性,使其无法被 ...

  2. 为 iTween 指定特定的回调 : onupdate, oncomplete

    问题地址:Specifying a delegate for the value of onupdate in iTween 1.找到 void CallBack 2.修改以下代码: void Cal ...

  3. volatile关键字及编译器指令乱序总结

    本文简单介绍volatile关键字的使用,进而引出编译期间内存乱序的问题,并介绍了有效防止编译器内存乱序所带来的问题的解决方法,文中简单提了下CPU指令乱序的现象,但并没有深入讨论. 以下是我搭建的博 ...

  4. Python【2】-列表和元组

    一.序列 python包含六种内建的序列:列表.元组.字符串.unicode字符串.buffer对象.xrange对象. 列表可以修改,元组是不能修改的. 二.列表 列表list是变长序列,其中的内容 ...

  5. java substring

    str=str.substring(int beginIndex,int endIndex);中最终得到的值: beginIndex =< str的值 < endIndex

  6. guava学习--monitor

    转载:https://my.oschina.net/realfighter/blog/349924   https://my.oschina.net/realfighter/blog/349926 M ...

  7. HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树

    HDU 3966 Aragorn's Story 先把树剖成链,然后用树状数组维护: 讲真,研究了好久,还是没明白 树状数组这样实现"区间更新+单点查询"的原理... 神奇... ...

  8. Phonegap中自定义插件的使用

    在phonegap中需要实现特定相关的功能,可能需要自定义扩展一下功能,那么扩展phonegap组件就成为了可能. 源代码结构图: 本文目的在于讲述怎么扩展一个phonegap组件以及实现. 针对ph ...

  9. Matrix(单点移动,多点缩放)

    package cn.iris.matrixapi; import android.app.Activity; import android.graphics.Matrix; import andro ...

  10. 写程序该选Mac 还是PC ?(转)

    原文链接:http://gogojimmy.net/2012/04/07/why-programmer-should-use-mac/ 序 一个竞争的市场,就会有对立的产生,这世界存在着很多不同的领域 ...