Windows7+VS2010下OpenGL的環境配置

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。ide

        因爲OpenGL自己只包含涉及渲染的核心函數,而不包括平臺相關的UI、文件輸入輸出、鍵盤鼠標交互等功能,在不一樣平臺上通常採用不一樣的擴展庫來輔助開發。在UNIX、Linux和Mac OS X平臺上通常採用GLUT庫實現圖形界面,但已經好久沒有更新了;在Windows平臺上,freeglut會更實用一些。由於調用OpenGL的函數時須要頻繁地調用和管理函數指針,可使用GLEW代替這些繁瑣的操做,並且GLEW還會根據你的平臺決定使用哪些擴展。函數


檢查兼容性oop

        OpenGL版本衆多,並且各顯卡廠商也有本身開發的擴展庫。要想使用某個版本進行開發,既須要顯卡自己支持所需的功能,又須要驅動程序能兼容這個版本。決定使用哪個版本以前,先要用GPU Caps Viewer檢查一下支持的OpenGL和GLSL的最高版本和具體支持哪些擴展。個人筆記本比較老,僅能支持OpenGL 3.0和GLSL 1.3。性能

gpu-caps-viewer
image-448

 

準備文件ui

        在http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip下載GLUT;spa

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

        能夠在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個文件是必需的)

include-gl
image-449

 

        把解壓獲得的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個文件是必需的)

lib
image-450

 

        把解壓獲得的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個文件是必需的)

bin
image-451

 

        若是發現這樣運行下面的樣例代碼時提示缺乏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。

linker-input
image-452

 

        若是還使用了freeglut庫,還須要在Configuration Properties -> VC++ Directories -> Include Directories中增長 C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Include\freeglut。

include-directories
image-453

 


樣例代碼

        把下面的代碼粘貼到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;
}

運行結果以下:

triangle-ibo
相關文章
相關標籤/搜索