|||
演示如果通过glew使用opengl的新特性
1 安装msys:下载地址;在windows下提供类似linux的命令环境.
2 下载glew代码、解压到d:glew-xxx.
3 编译
1)启动msys.
2)进入d:glew-xxx. 使用命令:cd /d/glew-xxx
3)编译:(要求已预先安装了mingw或tdw-mingw64)
make
4)得到编译后的.a文件和.dll文件.
4 将include下GL拷贝到(tdw-mingw64)include
将lib文件拷贝到(tdw-mingw64)lib
5 建立工作文件夹,如:d:workdir
6 拷贝4步中得到的dll到d:workdir
7 下载freeglut for mingw(freeglut-MinGW-3.0.0-1.mp)并安装include和lib文件,拷贝其目录下的freeglut.dll到d:workdir(注意不是freeglut32.dll).
8 编写测试程序,如vf_demo.cpp
9 编译c程序,命令:
g++ -o vf_demo vf_demo.cpp -lglew32.dll -lopengl32 -lfreeglut -lglu32
10 运行程序:
vf_demo
效果为:
附上三个程序文件:
vf_demo.cpp
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gl/glew.h>
#include <gl/glut.h>
float window_width = 600;
float window_height = 600;
GLfloat xRot = 0.0f;
GLfloat yRot = 0.0f;
GLfloat xTrans = 0;
GLfloat yTrans = 0;
GLfloat zTrans = -32.0;
int ox;
int oy;
int buttonState;
GLfloat xRotLength = 0.0f;
GLfloat yRotLength = 0.0f;
GLfloat LightAmbient[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat LightPosition[] = { 20.0f, 20.0f, 20.0f, 1.0f };
GLuint f;
GLuint v;
GLuint p;
void draw_box(float ox, float oy, float oz, float width, float height, float length)
{
glLineWidth(1.0f);
glBegin(GL_LINES);
glColor3f(1.0f, 0.0f, 0.0f);
//1
glVertex3f(ox, oy, oz);
glVertex3f(ox+width, oy, oz);
//2
glVertex3f(ox, oy, oz);
glVertex3f(ox, oy+height, oz);
//3
glVertex3f(ox, oy, oz);
glVertex3f(ox, oy, oz+length);
//4
glVertex3f(ox+width, oy, oz);
glVertex3f(ox+width, oy+height, oz);
//5
glVertex3f(ox+width, oy+height, oz);
glVertex3f(ox, oy+height, oz);
//6
glVertex3f(ox, oy+height, oz+length);
glVertex3f(ox, oy, oz+length);
//7
glVertex3f(ox, oy+height, oz+length);
glVertex3f(ox, oy+height, oz);
//8
glVertex3f(ox+width, oy, oz);
glVertex3f(ox+width, oy, oz+length);
//9
glVertex3f(ox, oy, oz+length);
glVertex3f(ox+width, oy, oz+length);
//10
glVertex3f(ox+width, oy+height, oz);
glVertex3f(ox+width, oy+height, oz+length);
//11
glVertex3f(ox+width, oy+height, oz+length);
glVertex3f(ox+width, oy, oz+length);
//12
glVertex3f(ox, oy+height, oz+length);
glVertex3f(ox+width, oy+height, oz+length);
glEnd();
}
void set_shaders()
{
char *vs = NULL;
char *fs = NULL;
vs = (char *)malloc(sizeof(char)*10000);
fs = (char *)malloc(sizeof(char)*10000);
memset(vs, 0, sizeof(char)*10000);
memset(fs, 0, sizeof(char)*10000);
FILE *fp;
char c;
int count;
fp = fopen("checkerboard.vs", "r");
count = 0;
while((c = fgetc(fp)) != EOF)
{
vs[count] = c;
count++;
}
fclose(fp);
fp = fopen("checkerboard.fs", "r");
count = 0;
while((c = fgetc(fp)) != EOF)
{
fs[count] = c;
count++;
}
fclose(fp);
printf("Shaders loaded...n");
v = glCreateShader(GL_VERTEX_SHADER);
f = glCreateShader(GL_FRAGMENT_SHADER);
const char *vv;
const char *ff;
vv = vs;
ff = fs;
glShaderSource(v, 1, &vv, NULL);
glShaderSource(f, 1, &ff, NULL);
int success;
glCompileShader(v);
glGetShaderiv(v, GL_COMPILE_STATUS, &success);
if(!success)
{
char info_log[5000];
glGetShaderInfoLog(v, 5000, NULL, info_log);
printf("Error in vertex shader compilation!n");
//printf("Info Log: %sn", info_log);
}
glCompileShader(f);
glGetShaderiv(f, GL_COMPILE_STATUS, &success);
if(!success)
{
char info_log[5000];
glGetShaderInfoLog(f, 5000, NULL, info_log);
printf("Error in fragment shader compilation!n");
//printf("Info Log: %sn", info_log);
}
p = glCreateProgram();
glAttachShader(p, v);
glAttachShader(p, f);
glLinkProgram(p);
glUseProgram(p);
free(vs);
free(fs);
}
void init()
{
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glewInit(); //glew init
set_shaders();
}
void display_func()
{
glEnable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 0.25); //0.75f, 0.75f, 0.75f, 0.25f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
if(buttonState == 1)
{
xRot+= (xRotLength-xRot)*0.1f;
yRot+= (yRotLength-yRot)*0.1f;
}
glTranslatef(xTrans, yTrans, zTrans);
glRotatef(xRot, 1.0f, 0.0f, 0.0f);
glRotatef(yRot, 0.0f, 1.0f, 0.0f);
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);
glEnable(GL_LIGHT1);
draw_box(-10.0f, -10.0f, -10.0f, 20.0f, 20.0f, 20.0f);
glColor3f(1.0f, 0.0f, 0.0f);
GLint uniformLoc = glGetUniformLocation(p, "lightPos");
if (uniformLoc != -1)
{
glUniform3fv(uniformLoc, 1, LightPosition);
}
glutSolidSphere(8.0, 300, 300);
glPopMatrix();
glutSwapBuffers();
}
void idle_func()
{
glutPostRedisplay();
}
void reshape_func(GLint width, GLint height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float)width/height, 0.001, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.0f);
}
void keyboard_func(unsigned char key, int x, int y)
{
switch(key) {
case 'w': zTrans += 2.0f; break;
case 's': zTrans -= 2.0f; break;
case 'a': xTrans += 2.0f; break;
case 'd': xTrans -= 2.0f; break;
case 'q': yTrans += 2.0f; break;
case 'e': yTrans -= 2.0f; break;
default:
break;
}
glutPostRedisplay();
}
void specialkey_func(int key, int x, int y)
{
if(key == GLUT_KEY_UP)
{
zTrans += 2.0f;
}
if(key == GLUT_KEY_DOWN)
{
zTrans -= 2.0f;
}
if(key == GLUT_KEY_LEFT)
{
xTrans -= 2.0f;
}
if(key == GLUT_KEY_RIGHT)
{
xTrans += 2.0f;
}
glutPostRedisplay();
}
void mouse_func(int button, int state, int x, int y)
{
if (state == GLUT_DOWN)
{
buttonState = 1;
}
else if (state == GLUT_UP)
{
buttonState = 0;
}
ox = x; oy = y;
glutPostRedisplay();
}
void motion_func(int x, int y)
{
float dx, dy;
dx = (float)(x - ox);
dy = (float)(y - oy);
if (buttonState == 1)
{
xRotLength += dy / 5.0f;
yRotLength += dx / 5.0f;
}
ox = x; oy = y;
glutPostRedisplay();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(0, 0);
glutInitWindowSize(window_width, window_height);
glutCreateWindow("Sphere demo");
init();
glutDisplayFunc(display_func);
glutReshapeFunc(reshape_func);
glutSpecialFunc(specialkey_func);
glutKeyboardFunc(keyboard_func);
glutMouseFunc(mouse_func);
glutMotionFunc(motion_func);
glutIdleFunc(idle_func);
glEnable(GL_DEPTH_TEST);
glutMainLoop();
return 0;
}
顶点着色文件checkerboard.vs(保存在workdir下)
uniform vec3 lightPos;
varying vec3 N, L, V;
void main(void)
{
// normal MVP transform
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// map object-space position onto unit sphere
V = gl_Vertex.xyz;
// eye-space normal
N = gl_NormalMatrix * gl_Normal;
// eye-space light vector
vec4 Veye = gl_ModelViewMatrix * gl_Vertex;
L = lightPos - Veye.xyz;
}
面源着色文件checkerboard.fs
// 3D solid checker grid
varying vec3 V; // object-space position
varying vec3 N; // eye-space normal
varying vec3 L; // eye-space light vector
const vec3 onColor = vec3(1.0, 1.0, 1.0);
const vec3 offColor = vec3(0.0, 0.0, 0.0);
const float ambientLighting = 0.2;
const float specularExp = 60.0;
const float specularIntensity = 0.75;
const int numSquaresPerSide = 8;
void main (void)
{
// Normalize vectors
vec3 NN = normalize(N);
vec3 NL = normalize(L);
vec3 NV = normalize(V);
vec3 NH = normalize(NL + vec3(0.0, 0.0, 1.0));
// Map -1,1 to 0,numSquaresPerSide
vec3 onOrOff = ((NV + 1.0) * float(numSquaresPerSide)) / 2.0;
// mod 2 >= 1
onOrOff = step(1.0, mod(onOrOff, 2.0));
// 3-way xor
onOrOff.x = step(0.5,
mod(onOrOff.x + onOrOff.y + onOrOff.z, 2.0));
// checkerboard grid
vec3 surfColor = mix(offColor, onColor, onOrOff.x);
// calculate diffuse lighting + 20% ambient
surfColor *= (ambientLighting + vec3(max(0.0, dot(NN, NL))));
// calculate specular lighting w/ 75% intensity
surfColor += (specularIntensity *
vec3(pow(max(0.0, dot(NN, NH)), specularExp)));
gl_FragColor = vec4(surfColor, 1.0);
}
编译后,程序正常工作。
只是奇怪的是,freeglut.dll是64位的,glew32.dll是32位的,编译运行没有问题;但如果freeglut32.dll被使用的话,程序运行就出错。
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-9-26 05:56
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社