10月13号下午3:00队长给我开了一个会,10.14号开始学习opengl
今天10月21号,期间,虽然有时候课程很满,但每天都至少写一个程序。
当然,这些只是我7天来业余时间的学习,我觉得这个网址不错,大家如果也想学习opengl,并且具有一定的C语言C++基础,入门课程推荐大家去学习这个网址http://www.cnblogs.com/crazyxiaom/articles/2073586.html
我的这些代码等都是从这个网址学习的,推荐你还是去这个网址学习,那更全更准确。
PS:“今天”(发表文章的今天)把我入门学习的资料送给一块儿学习的同学了,看着那厚厚的一叠折折状状的资料,我穿越了,我很清晰的看到了我接下来的学习生活--将会更加投入,将会有更厚更厚的资料进入我的大脑!
10.14
今天写了15个程序。这些是画二维图形的基础。
开始的时候犯了一个错误,以为坐标范围是像素点呢,后来才知道坐标范围是-1~1;(0,0)在中心。
第三个程序到第15个程序都是在练习glBegin()的使用,最后可以画一个近似圆的多边形。
GL_POINTS,GL_LINES,GL_LINE_STRIP,GL_LINE_LOOP,GL_TRIANGLES,GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN
GL_POLYGON
1.
#include<GL/GLUT.H>
void myDisplay(void){
glClear(GL_COLOR_BUFFER_BIT);
glRectf(-0.5f, -0.4f, 0.5f, 0.5f);
glFlush();
}
int main(int argc, char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB|GLUT_SINGLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(400, 400);
glutCreateWindow("openglѧϰ1");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}

2.
#include <GL/glut.h>
void myDisplay(){
glClearColor(1.0, 1.0, 1.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glRectf(-0.5f,-0.5f,0.5f,0.5f);
glFlush();
}
int main(int argc, char* argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400, 400);
glutInitWindowSize(200, 200);
glutCreateWindow("独立");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

3.
#include<GL/glut.h>
void myDisplay(){
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_POINTS);
glVertex2i(100, 100);
glVertex2i(50, 50);
glVertex2i(70, 70);
glVertex2f(0.3f, 0.3f);
glVertex2f(-0.3f, -0.3f);
glVertex2f(0.5f, 0.5f);
glVertex2d(0.2,0.5);
glVertex2d(-0.4, -0.6);
glVertex2d(0.3,0.6);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study02");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}

4.
#include<GL/glut.h>
void myDisplay(){
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINES);
//glVertex2i(100, 100);
//glVertex2i(50, 50);
//glVertex2i(70, 70);
glVertex2f(0.3f, 0.3f);
glVertex2f(-0.3f, -0.3f);
glVertex2f(0.5f, 0.5f);
glVertex2d(0.2,0.5);
glVertex2d(-0.4, -0.6);
glVertex2d(0.3,0.6);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study03");
glutDisplayFunc(&myDisplay);
glutMainLoop();
return 0;
}

5.
#include <GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINE_STRIP);
glVertex2f(0.1f, 0.8f);
glVertex2f(-0.1f, -0.8f);
glVertex2f(0.1f, -0.8f);
glVertex2f(-0.1f, 0.8f);
glVertex2f(0.1f, 0.9f);
glVertex2f(0.4f, 0.8f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

6.1
#include <GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINE_LOOP);
glVertex2f(0.2f, 0.2f);
glVertex2f(-0.2f, 0.2f);
glVertex2f(-0.2f, -0.2f);
glVertex2f(0.2f, -0.2f);
//glVertex2f(0.1f, 0.9f);
//glVertex2f(0.4f, 0.8f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

7
#include <GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLES);
//glVertex2f(0.2f, 0.2f);
//glVertex2f(-0.2f, 0.2f);
//glVertex2f(-0.2f, -0.2f);
glVertex2f(0.8f, 0.4f);
glVertex2f(0.4f, 0.8f);
glVertex2f(0.0f, 0.0f);
//glVertex2f(0.1f, 0.9f);
//glVertex2f(0.4f, 0.8f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

7.1
#include <GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLES);
glVertex2f(0.2f, 0.2f);
glVertex2f(-0.2f, 0.2f);
glVertex2f(-0.2f, -0.2f);
glEnd();
glBegin(GL_TRIANGLES);
glVertex2f(0.8f, 0.4f);
glVertex2f(0.4f, 0.8f);
glVertex2f(0.0f, 0.0f);
//glVertex2f(0.1f, 0.9f);
//glVertex2f(0.4f, 0.8f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
#include <GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLES);
glVertex2f(0.2f, 0.2f);
glVertex2f(-0.2f, 0.2f);
glVertex2f(-0.2f, -0.2f);
glVertex2f(0.8f, 0.4f);
glVertex2f(0.4f, 0.8f);
glVertex2f(0.0f, 0.0f);
//glVertex2f(0.1f, 0.9f);
//glVertex2f(0.4f, 0.8f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

7.3
#include <GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLES);
glVertex2f(0.2f, 0.2f);
glVertex2f(-0.2f, 0.2f);
glVertex2f(-0.2f, -0.2f);
glVertex2f(0.8f, 0.4f);
glVertex2f(0.4f, 0.8f);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.1f, 0.9f);
glVertex2f(0.4f, 0.8f);
glVertex2f(0.9f,0.3f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
#include <GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLE_STRIP);
glVertex2f(0.0f,0.0f);
glVertex2f(0.4f,0.8f);
glVertex2f(0.8f,0.4f);
glVertex2f(0.8f,0.5f);
glVertex2f(-0.1f,0.9f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

9.
#include <GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_TRIANGLE_FAN);
glVertex2f(0.0f,0.0f);
glVertex2f(0.4f,0.8f);
glVertex2f(0.8f,0.4f);
glVertex2f(0.8f,-0.5f);
glVertex2f(0.1f,-0.9f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

10.
#include <GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
glVertex2f(0.0f,0.0f);
glVertex2f(0.8f,0.4f);
glVertex2f(0.4f,0.8f);
glVertex2f(0.8f,-0.5f);
glVertex2f(0.1f,-0.9f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

11.
#include <GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_QUADS);
glVertex2f(0.2f, 0.2f);
glVertex2f(0.2f, -0.2f);
glVertex2f(-0.2f,-0.2f);
glVertex2f(-0.2f,0.2f);
glVertex2f(0.3f, 0.3f);
glVertex2f(0.3f, 0.7f);
glVertex2f(0.7f,1.0f);
glVertex2f(0.7f,0.3f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

12
#include <GL/glut.h>
#include<math.h>
const int n = 20;
const GLfloat R = 0.5f;
const GLfloat Pi = 3.14159265358979f;
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
for(int i=0;i<n;++i)
{
glVertex2f(R*cos(2*Pi/n*i), R*sin(2*Pi/n*i));
}
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

12.1
#include <GL/glut.h>
#include<math.h>
const int n = 30;
const GLfloat R = 0.5f;
const GLfloat Pi = 3.14159265358979f;
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
for(int i=0;i<n;++i)
{
glVertex2f(R*cos(2*Pi/n*i), R*sin(2*Pi/n*i));
}
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

12.2
#include <GL/glut.h>
#include<math.h>
const int n = 50;
const GLfloat R = 0.5f;
const GLfloat Pi = 3.14159265358979f;
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_POLYGON);
for(int i=0;i<n;++i)
{
glVertex2f(R*cos(2*Pi/n*i), R*sin(2*Pi/n*i));
}
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

13
#include <GL/glut.h>
#include<math.h>
const GLfloat R = 0.5f;
const GLfloat Pi = 3.14159265358979f;
void myDisplay()
{
GLfloat PointA[2] = {0,R};
GLfloat PointB[2] = {R*cos(162*Pi/180),R*sin(162*Pi/180)};
GLfloat PointC[2] = {R*cos(234*Pi/180),R*sin(234*Pi/180)};
GLfloat PointD[2] = {R*cos(306*Pi/180),R*sin(306*Pi/180)};
GLfloat PointE[2] = {R*cos(18*Pi/180),R*sin(18*Pi/180)};
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,0.0,0.0);
glBegin(GL_LINE_LOOP);
glVertex2fv(PointA);
glVertex2fv(PointC);
glVertex2fv(PointE);
glVertex2fv(PointB);
glVertex2fv(PointD);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

10.15
以下程序诸个描述
14.用很多线段的连线去模拟一个正玄函数线。用多条短的线段去模拟复杂的曲线或弧线似乎是一个很好的思维,在这思维下可以画出很多复杂的函数曲线
#include <GL/glut.h>
#include<math.h>
const GLfloat factor = 0.1f;
void myDisplay()
{
GLfloat x;
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glBegin(GL_LINES);
glVertex2f(-1.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(0.0f, -1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glBegin(GL_LINE_STRIP);
for(x=-1.0f/factor;x<1.0f/factor;x+=0.01)
{
glVertex2f(x*factor, sin(x)*factor);
}
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

15.上周上机实验时设置点的大小总是不通过,今天发现设置点的大小不是那么难。
#include <GL/glut.h>
#include<math.h>
const GLfloat factor = 0.1f;
void myDisplay()
{
GLfloat x;
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glPointSize(5.0f);
glBegin(GL_POINTS);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.4f, 0.4f);
glVertex2f(-0.2f,0.3f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
#include <GL/glut.h>
#include<math.h>
const GLfloat factor = 0.1f;
void myDisplay()
{
GLfloat x;
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glPointSize(50.0f);
glBegin(GL_POINTS);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.4f, 0.4f);
glVertex2f(-0.2f,0.3f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
#include <GL/glut.h>
#include<math.h>
const GLfloat factor = 0.1f;
void myDisplay()
{
GLfloat x;
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glLineWidth(5.0f);
glBegin(GL_LINE_STRIP);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.4f, 0.4f);
glVertex2f(-0.2f,0.3f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

16.1 设置了夸张的线宽
#include <GL/glut.h>
#include<math.h>
const GLfloat factor = 0.1f;
void myDisplay()
{
GLfloat x;
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glLineWidth(50.0f);
glBegin(GL_LINE_STRIP);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.4f, 0.4f);
glVertex2f(-0.2f,0.3f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

17. 画圆。圆心和周长上的点的连线,线加粗。
#include <GL/glut.h>
#include<math.h>
const GLfloat factor = 0.1f;
class screenPt
{
private :
GLint x,y;
public:
screenPt()
{
x=y=0;
}
void setCoords(GLint xCoordValue,GLint yCoordValue)
{
x=xCoordValue;
y=yCoordValue;
}
GLint getx() const
{
return x;
}
GLint gety() const
{
return y;
}
void incrementx()
{
x++;
}
void decrementy()
{
y--;
}
};
void line(GLint x1, GLint y1, GLint x2, GLint y2){
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glLineWidth(5.0f);
glBegin(GL_LINES);
glVertex2f(x1/200.0f, y1/200.0f);
glVertex2f(x2/200.0f, y2/200.0f);
//glEnd();
glFlush();
}
void circleMidpoint(GLint xc,GLint yc,GLint radius)
{
screenPt circPt;
GLint p=1-radius;
circPt.setCoords(0,radius);
void circlePlotPoints (GLint,GLint,screenPt);
circlePlotPoints(xc, yc, circPt);
while(circPt.getx()<circPt.gety())
{
circPt.incrementx();
if(p<0)
p+=2*circPt.getx() +1;
else
{
circPt.decrementy();
p+=2*(circPt.getx()-circPt.gety())+1;
}
circlePlotPoints(xc,yc,circPt);
}
}
void circlePlotPoints(GLint xc,GLint yc,screenPt circPt)
{
line(xc, yc, xc+circPt.getx(),yc+circPt.gety());
line(xc, yc, xc-circPt.getx(),yc+circPt.gety());
line(xc, yc, xc+circPt.getx(),yc-circPt.gety());
line(xc, yc, xc-circPt.getx(),yc-circPt.gety());
line(xc, yc, xc+circPt.gety(),yc+circPt.getx());
line(xc, yc, xc-circPt.gety(),yc+circPt.getx());
line(xc, yc, xc+circPt.gety(),yc-circPt.getx());
line(xc, yc, xc-circPt.gety(),yc-circPt.getx());
}
void Mycircle(void)
{
circleMidpoint(100,80,50);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(&Mycircle);
glutMainLoop();
return 0;
}

17.1 画圆。圆心和周长上的点的连线,线稍细。
#include <GL/glut.h>
#include<math.h>
const GLfloat factor = 0.1f;
class screenPt
{
private :
GLint x,y;
public:
screenPt()
{
x=y=0;
}
void setCoords(GLint xCoordValue,GLint yCoordValue)
{
x=xCoordValue;
y=yCoordValue;
}
GLint getx() const
{
return x;
}
GLint gety() const
{
return y;
}
void incrementx()
{
x++;
}
void decrementy()
{
y--;
}
};
void line(GLint x1, GLint y1, GLint x2, GLint y2){
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
glLineWidth(1.0f);
glBegin(GL_LINES);
glVertex2f(x1/200.0f, y1/200.0f);
glVertex2f(x2/200.0f, y2/200.0f);
//glEnd();
glFlush();
}
void circleMidpoint(GLint xc,GLint yc,GLint radius)
{
screenPt circPt;
GLint p=1-radius;
circPt.setCoords(0,radius);
void circlePlotPoints (GLint,GLint,screenPt);
circlePlotPoints(xc, yc, circPt);
while(circPt.getx()<circPt.gety())
{
circPt.incrementx();
if(p<0)
p+=2*circPt.getx() +1;
else
{
circPt.decrementy();
p+=2*(circPt.getx()-circPt.gety())+1;
}
circlePlotPoints(xc,yc,circPt);
}
}
void circlePlotPoints(GLint xc,GLint yc,screenPt circPt)
{
line(xc, yc, xc+circPt.getx(),yc+circPt.gety());
line(xc, yc, xc-circPt.getx(),yc+circPt.gety());
line(xc, yc, xc+circPt.getx(),yc-circPt.gety());
line(xc, yc, xc-circPt.getx(),yc-circPt.gety());
line(xc, yc, xc+circPt.gety(),yc+circPt.getx());
line(xc, yc, xc-circPt.gety(),yc+circPt.getx());
line(xc, yc, xc+circPt.gety(),yc-circPt.getx());
line(xc, yc, xc-circPt.gety(),yc-circPt.getx());
}
void Mycircle(void)
{
circleMidpoint(100,80,50);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(&Mycircle);
glutMainLoop();
return 0;
}

18. 设置线的模式
glEnable(GL_LINE_STIPPLE);//激活模式选择
glLineStipple(2,0x3333);//单位线,虚实匹配
#include <GL/glut.h>
#include<math.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glEnable(GL_LINE_STIPPLE);
glLineStipple(2,0x3333);
glLineWidth(3.0f);
glBegin(GL_LINES);
glVertex2f(-1.0f, 0.0f);
glVertex2f(1.0f, 0.0f);
glVertex2f(0.0f, -1.0f);
glVertex2f(0.0f, 1.0f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("Study04");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

19.练习一下程序的基本流程。不能看书,自己敲完。
#include<GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glLineWidth(5.0f);
glBegin(GL_LINES);
glVertex2f(0.0f, 0.0f);
glVertex2f(0.6f,0.8f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
#include<GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glPolygonMode(GL_FRONT,GL_FILL); //设置正面为填充模式
glPolygonMode(GL_BACK,GL_LINE); //设置反面为线性模式
glFrontFace(GL_CCW);
glBegin(GL_POLYGON);
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.0f,-0.5f);
glVertex2f(0.0f,0.0f);
glVertex2f(-0.5f,0.0f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

20.
//glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
#include<GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glPolygonMode(GL_FRONT,GL_FILL); //设置正面为填充模式
glPolygonMode(GL_BACK,GL_LINE); //设置反面为线性模式
glFrontFace(GL_CW);
glBegin(GL_POLYGON);
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.0f,-0.5f);
glVertex2f(0.0f,0.0f);
glVertex2f(-0.5f,0.0f);
glEnd();
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

21 面具有两个面,可以剔除一个面,当面被挡着时可以剔除一个面。
glEnable(GL_CULL_FACE);//opengl是一个状态机,需要激活才能使用一些功能
glCullFace(GL_FRONT);//剔除正面
//glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
#include<GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glPolygonMode(GL_FRONT,GL_FILL); //设置正面为填充模式
glPolygonMode(GL_BACK,GL_LINE); //设置反面为线性模式
glFrontFace(GL_CCW);
glBegin(GL_POLYGON);
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.0f,-0.5f);
glVertex2f(0.0f,0.0f);
glVertex2f(-0.5f,0.0f);
glEnd();
glColor3f(1.0,0.0,0.0);
//glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glBegin(GL_POLYGON);
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.0f,-0.5f);
glVertex2f(0.0f,0.0f);
glVertex2f(-0.5f,0.0f);
glEnd();
glDisable(GL_CULL_FACE);
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
21.1剔除了一个面后,被挡的面出现
#include<GL/glut.h>
void myDisplay()
{
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glPolygonMode(GL_FRONT,GL_FILL); //设置正面为填充模式
glPolygonMode(GL_BACK,GL_LINE); //设置反面为线性模式
glFrontFace(GL_CCW);
glBegin(GL_POLYGON);
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.0f,-0.5f);
glVertex2f(0.0f,0.0f);
glVertex2f(-0.5f,0.0f);
glEnd();
glColor3f(1.0,0.0,0.0);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
glBegin(GL_POLYGON);
glVertex2f(-0.5f, -0.5f);
glVertex2f(0.0f,-0.5f);
glVertex2f(0.0f,0.0f);
glVertex2f(-0.5f,0.0f);
glEnd();
glDisable(GL_CULL_FACE);
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}
22 画板,镂空的实现
glEnable(GL_POLYGON_STIPPLE);激活多面体镂空模式
glPolygonStipple(Mask); 镂空数组
#include<GL/glut.h>
#include<stdio.h>
#include<STDLIB.H>
void myDisplay()
{
static GLubyte Mask[128];
FILE *fp;
fp = fopen("mmmm.bmp", "rb");
if(!fp)
exit(0);
if(fseek(fp, -(int)sizeof(Mask),SEEK_END))
exit(0);
if(!fread(Mask,sizeof(Mask),1,fp))
exit(0);
fclose(fp);
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0,0.0,1.0);
glEnable(GL_POLYGON_STIPPLE);
glPolygonStipple(Mask);
glRectf(-0.5f,-0.5f,0.0f,0.0f);
glDisable(GL_POLYGON_STIPPLE);
glRectf(0.0f,0.0f,0.5f,0.5f);
glFlush();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(myDisplay);
glutMainLoop();
return 0;
}

23 默认光滑模式
#include<GL/glut.h>
#include<math.h>
const GLdouble Pi = 3.1415926536;
void myDisplay()
{
int i;
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLE_FAN);
glColor3f(0.0,0.0,1.0);
glVertex2f(0.0f,0.0f);
for(i=0;i<=8;++i)
{
glColor3f(i&0x04, i&0x02, i&0x01);
glVertex2f((float)cos(i*Pi/4), (float)sin(i*Pi/4));
}
glEnd();
glFlush();
}
int main(int argv, char* argc[])
{
glutInit(&argv, argc);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(myDisplay);
//Sleep(10*1000);
glutMainLoop();
return 0;
}

23.1 设置了清除色
#include<GL/glut.h>
#include<math.h>
const GLdouble Pi = 3.1415926536;
void myDisplay()
{
int i;
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLE_FAN);
//glColor3f(0.0,0.0,1.0);
glVertex2f(0.0f,0.0f);
for(i=0;i<=8;++i)
{
glColor3f(i&0x04, i&0x02, i&0x01);
glVertex2f((float)cos(i*Pi/4), (float)sin(i*Pi/4));
}
glEnd();
glFlush();
}
int main(int argv, char* argc[])
{
glutInit(&argv, argc);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(myDisplay);
//Sleep(10*1000);
glutMainLoop();
return 0;
}

23.2
glShadeModel(GL_FLAT);采用平板展现模式---其对应光滑渐变模式
#include<GL/glut.h>
#include<math.h>
const GLdouble Pi = 3.1415926536;
void myDisplay()
{
int i;
glShadeModel(GL_FLAT);
glClearColor(1.0,1.0,1.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_TRIANGLE_FAN);
//glColor3f(0.0,0.0,1.0);
glVertex2f(0.0f,0.0f);
for(i=0;i<=8;++i)
{
glColor3f(i&0x04, i&0x02, i&0x01);
glVertex2f((float)cos(i*Pi/4), (float)sin(i*Pi/4));
}
glEnd();
glFlush();
}
int main(int argv, char* argc[])
{
glutInit(&argv, argc);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(myDisplay);
//Sleep(10*1000);
glutMainLoop();
return 0;
}

24 今天是周一,明天周二,计算机图形学上机实验,不能太给老是丢人,就勉强自己写了个三维的,借用隔壁同学的方法使它旋转起来了,发现这方法竟然是下一天的课程,呵呵
#include<GL/glut.h>
#include<windows.h>
#include<math.h>
static int day = 200;
void myDisplay()
{
glEnable(GL_DEPTH_TEST); //启动深度测试
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //清空深度缓冲和颜色缓冲
glMatrixMode(GL_PROJECTION); //操作投影矩阵
glLoadIdentity(); //进行变换前通常把当前矩阵设置为单位矩阵
gluPerspective(75,1,1,400000000); //设置可视空间,得到透视效果(可视角,高宽比,最近可视距离,最远可视距离)
glMatrixMode(GL_MODELVIEW); //设置当前操作的矩阵为“模型视图矩阵”
glLoadIdentity(); //把当前矩阵设置为单位矩阵
gluLookAt(0,-200000000,200000000,0,0,0,0,0,1); //设定观察点位置(观察点位置,目标位置,观察者上方向)
glColor3f(1.0f,0.0f,0.0f);
//glRotatef(day/360.0*360.0, 0.0f,0.0f,-1.0f);
glutSolidSphere(69600000,50,50);
glColor3f(0.0f,0.0f,1.0f);
glRotatef(day, 0.0f,0.0f,-1.0f);
glTranslatef(150000000,0.0f,0.0f);
glutSolidSphere(15945000,50,50);
glColor3f(1.0f,1.0f,0.0f);
glRotatef(day/30.0*360.0-day,0.0f,0.0f,-1.0f);
glTranslatef(38000000,0.0f,0.0f);
glutSolidSphere(4345000,50,50);
glutSwapBuffers();
}
void play()
{
day++;
if(day >= 360)
day = 0;
myDisplay();
Sleep(100);
glutPostRedisplay();
}
int main(int argv, char* argc[])
{
glutInit(&argv, argc);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
glutInitWindowPosition(400,400);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(play);
glutMainLoop();
return 0;
}

10.16
今天只有晚上有时间了,白天都满课
25 光照,材质等,不是很懂,光照必须要会用!
#include<GL/glut.h>
#define WIDTH 400
#define HEIGHT 400
static GLfloat angle = 0.0f;
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//创建透视效果视图
glMatrixMode(GL_PROJECTION); //操作投影矩阵
glLoadIdentity(); //当前矩阵设置为单位矩阵
gluPerspective(90.0f, 1.0f,1.0f,20.0f); //得到透视效果
glMatrixMode(GL_MODELVIEW); //操作“模型视图”矩阵
glLoadIdentity();
gluLookAt(0.0,0.0,-10.0,0.0,0.0,0.0,0.0,1.0,0.0);
//定义太阳光源,它是一种白色光源
{
GLfloat sun_light_position[] = {0.0f,0.0f,0.0f,1.0f};
GLfloat sun_light_ambient[] = {0.0f,0.0f,0.0f,1.0f};
GLfloat sun_light_diffuse[] = {1.0f,1.0f,1.0f,1.0f};
GLfloat sun_light_specular[] = {1.0f,1.0f,1.0f,1.0f};
glLightfv(GL_LIGHT0, GL_POSITION, sun_light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, sun_light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, sun_light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, sun_light_specular);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}
//定义太阳的材质并绘制太阳
{
GLfloat sun_mat_ambient[] = {0.0f,0.0f,0.0f,1.0f};
GLfloat sun_mat_diffuse[] = {0.0f,0.0f,0.0f,1.0f};
GLfloat sun_mat_specular[] = {0.0f,0.0f,0.0f,1.0f};
GLfloat sun_mat_emission[] = {0.5f,0.0f,0.0f,1.0f};
GLfloat sun_mat_shininess = 0.0f;
glMaterialfv(GL_FRONT, GL_AMBIENT, sun_mat_ambient); //环境变量
glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_mat_diffuse); //散射模式
glMaterialfv(GL_FRONT, GL_SPECULAR, sun_mat_specular); //镜面反射
glMaterialfv(GL_FRONT, GL_EMISSION, sun_mat_emission); //发射,散发喷射
glMaterialf(GL_FRONT, GL_SHININESS, sun_mat_shininess);
glutSolidSphere(2.0,40,32);
}
//定义地球材质并绘制地球
{
GLfloat earth_mat_ambient[] = {0.0f,0.0f,0.5f,1.0f};
GLfloat earth_mat_diffuse[] = {0.0f,0.0f,0.5f,1.0f};
GLfloat earth_mat_specular[] = {0.0f,0.0f,1.0f,1.0f};
GLfloat earth_mat_emission[] = {0.0f,0.0f,0.0f,1.0f};
GLfloat earth_mat_shininess = 30.0f;
glMaterialfv(GL_FRONT, GL_AMBIENT, earth_mat_ambient); //环境变量
glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse); //散射模式
glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular); //镜面反射
glMaterialfv(GL_FRONT, GL_EMISSION, earth_mat_emission); //发射,散发喷射
glMaterialf(GL_FRONT, GL_SHININESS, earth_mat_shininess);
glRotatef(angle,0.0f,-1.0f,0.0f);
glTranslatef(5.0f,0.0f,0.0f);
glutSolidSphere(1.5,40,32);
}
glutSwapBuffers();
}
void myIdle()
{
angle += 1.0f;
if(angle >= 360.0f)
angle = 0.0f;
myDisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200,200);
glutInitWindowSize(WIDTH, HEIGHT);
glutCreateWindow("opengl光照演示");
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle); //回调
glutMainLoop();
return 0;
}


10.17
今天周三,满课,且晚上还有数据库上机实验,自己电脑不能用,中午看过这课后借同学的手机敲了代码练习
26 列表的使用(一次编译,多次使用,节省效率)、glutIdleFunc(&myIdle)调用cpu空闲资源且控制旋转角度,注意矩阵的push和pop
#include<GL/glut.h>
#include<math.h>
#include<windows.h>
#define WIDTH 400
#define HEIGHT 400
#define ColoredVertex(c,v) do{glColor3fv(c);glVertex3fv(v);}while(0)
GLfloat angle=0.0f;
void myDisplay()
{
static int list = 0;
if(list == 0)
{
GLfloat
PointA[] = {0.5f,-sqrt(6.0f)/12,-sqrt(3.0f)/6},
PointB[] = {-0.5f,-sqrt(6.0f)/12,-sqrt(3.0f)/6},
PointC[] = {0.0f,-sqrt(6.0f)/12,sqrt(3.0f)/3},
PointD[] = {0.0f,sqrt(6.0f)/4,0};
GLfloat
ColorR[] = {1,0,0},
ColorG[] = {0,1,0},
ColorB[] = {0,0,1},
ColorY[] = {1,1,0};
list = glGenLists(1);
glNewList(list,GL_COMPILE);
glBegin(GL_TRIANGLES);
ColoredVertex(ColorR,PointA);
ColoredVertex(ColorG,PointB);
ColoredVertex(ColorB,PointC);
ColoredVertex(ColorR,PointA);
ColoredVertex(ColorB,PointC);
ColoredVertex(ColorY,PointD);
ColoredVertex(ColorB,PointC);
ColoredVertex(ColorG,PointB);
ColoredVertex(ColorY,PointD);
ColoredVertex(ColorG,PointB);
ColoredVertex(ColorR,PointA);
ColoredVertex(ColorY,PointD);
glEnd();
glEndList();
glEnable(GL_DEPTH_TEST);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle,1,0.5,0);
glCallList(list);
glPopMatrix();
glutSwapBuffers();
}
void myIdle()
{
++angle;
if(angle >= 360.0f)
angle = 0.0f;
Sleep(1000/10);
myDisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200,200);
glutInitWindowSize(400,400);
glutCreateWindow("study");
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutMainLoop();
return 0;
}



10.18
今天学颜色的混合,会有半透明的效果
27. glBlendFunc(GL_ONE,GL_ZERO);完全使用源色
#include<GL/glut.h>
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ZERO);
glColor4f(1,0,0,0.5);
glRectf(-1,-1,0.5,0.5);
glColor4f(0,1,0,0.5);
glRectf(-0.5,-0.5,1,1);
glutSwapBuffers();
}
void myIdle()
{
myDisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200,200);
glutInitWindowSize(400,400);
glutCreateWindow("study");
myDisplay();
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutMainLoop();
return 0;
}

27.1两种颜色混合
glBlendFunc(GL_ONE, GL_ONE);,则表示完全使用源颜色和目标颜色,最终的颜色实际上就是两种颜色的简单相加。例如红色(1, 0, 0)和绿色(0, 1, 0)相加得到(1, 1, 0),结果为黄色
#include<GL/glut.h>
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ONE); //改动
glColor4f(1,0,0,0.5);
glRectf(-1,-1,0.5,0.5);
glColor4f(0,1,0,0.5);
glRectf(-0.5,-0.5,1,1);
glutSwapBuffers();
}
void myIdle()
{
myDisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200,200);
glutInitWindowSize(400,400);
glutCreateWindow("study");
myDisplay();
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutMainLoop();
return 0;
}
27.2
GL_ONE_MINUS_SRC_ALPHA:表示用1.0减去源颜色的alpha值来作为因子。
GL_ONE_MINUS_DST_ALPHA:表示用1.0减去目标颜色的alpha值来作为因子。
#include<GL/glut.h>
void myDisplay()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); //改动
glColor4f(1,0,0,0.5);
glRectf(-1,-1,0.5,0.5);
glColor4f(0,1,0,0.5);
glRectf(-0.5,-0.5,1,1);
glutSwapBuffers();
}
void myIdle()
{
myDisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200,200);
glutInitWindowSize(400,400);
glutCreateWindow("study");
myDisplay();
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle);
glutMainLoop();
return 0;
}

28 光源,绘制半透明物体,注意深度测试的控制
在进行三维混合时,不仅要考虑源因子和目标因子,还应该考虑深度缓冲区。必须先绘制所有不透明的物体,再绘制半透明的物体。在绘制半透明物体时前,还需要将深度缓冲区设置为只读形式,否则可能出现画面错误。
#include<GL/glut.h>
//在1,1,-1处设置白色的光源
void setLight()
{
static const GLfloat light_position[] = {1.0f,1.0f,-1.0f,1.0f};
static const GLfloat light_ambient[] = {0.2f,0.2f,0.2f,1.0f};
static const GLfloat light_diffuse[] = {1.0f,1.0f,1.0f,1.0f};
static const GLfloat light_specular[] = {1.0f,1.0f,1.0f,1.0f};
glLightfv(GL_LIGHT0,GL_POSITION, light_position);
glLightfv(GL_LIGHT0,GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0,GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0,GL_SPECULAR, light_specular);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
}
//设置材质
void setMatirial(const GLfloat mat_diffuse[4], GLfloat mat_shininess)
{
static const GLfloat mat_specular[] = {0.0f,0.0f,0.0f,1.0f};
static const GLfloat mat_emission[] = {0.0f,0.0f,0.0f,1.0f};
glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,mat_diffuse);
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);
glMaterialfv(GL_FRONT,GL_EMISSION,mat_emission);
glMaterialf(GL_FRONT,GL_SHININESS,mat_shininess);
}
void myDisplay()
{
//定义一些材质颜色
const static GLfloat red_color[] = {1.0f,0.0f,0.0f,1.0f};
const static GLfloat green_color[] = {0.0f,1.0f,0.0f,0.3333f};
const static GLfloat blue_color[] = {0.0f,0.0f,1.0f,0.5f};
//清除屏幕
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//设置光源
setLight();
//启动混合并设置混合因子
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
//以(0,0,0.5)为中心,绘制一个半径为0.3的不透明红色球体(离观察者最远)
setMatirial(red_color, 30.0);
glPushMatrix();
glTranslatef(0.0f,0.0f,0.5f);
glutSolidSphere(0.3,30,30);
glPopMatrix();
//绘制半透明物体
glDepthMask(GL_FALSE);
//以(0.2,0,-0.5)为中心,绘制一个半径为0.2的半透明蓝色球体(离观察者最近)
setMatirial(blue_color, 30.0);
glPushMatrix();
glTranslatef(0.2f,0.0f,-0.5f);
glutSolidSphere(0.2,30,30);
glPopMatrix();
//以(0.1,0,0)为中心,绘制一个半径为0.15的半透明绿色球体(在两球体之间)
setMatirial(green_color, 30.0);
glPushMatrix();
glTranslatef(0.1,0,0);
glutSolidSphere(0.15,30,30);
glPopMatrix();
//深度缓冲区恢复为可读可写模式
glDepthMask(GL_TRUE);
glutSwapBuffers();
}
void myIdle()
{
myDisplay();
}
int main(int argc, char* argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(200,200);
glutInitWindowSize(400,400);
glutCreateWindow("study");
myDisplay();
glutDisplayFunc(&myDisplay);
//glutIdleFunc(&myIdle);
glutMainLoop();
return 0;
}

10.19
29 读取bmp图片的宽度和高度值,代码跟下一个程序开头类似
主代码:
static GLint ImageWidth; static GLint ImageHeight;
//打开文件 FILE* pFile = fopen("1234.bmp", "rb"); if(pFile == 0) exit(0); //读取图象的大小信息 fseek(pFile, 0x0012, SEEK_SET); fread(&ImageWidth,sizeof(ImageWidth),1,pFile); fread(&ImageHeight,sizeof(ImageHeight),1,pFile);
30 读取bmp图片文件--存像素数值,画出来
#include<GL/glut.h> #include<stdio.h> #include<stdlib.h> #define FileName "1234.bmp" static GLint ImageWidth; static GLint ImageHeight; static GLint PixelLength; static GLubyte* PixelData; void display() { /*清除屏幕并不必要 * 每次绘制时,画面都覆盖整个屏幕 * 因此无论是否清除屏幕,结果都一样 */ //glClear(GL_COLOR_BUFFER_BIT); //绘制像素 glDrawPixels(ImageWidth,ImageHeight, GL_BGR_EXT,GL_UNSIGNED_BYTE,PixelData); //完成绘制 glutSwapBuffers(); } int main(int argc, char* argv[]) { //打开文件 FILE* pFile = fopen("1234.bmp", "rb"); if(pFile == 0) exit(0); //读取图象的大小信息 fseek(pFile, 0x0012, SEEK_SET); fread(&ImageWidth,sizeof(ImageWidth),1,pFile); fread(&ImageHeight,sizeof(ImageHeight),1,pFile); //计算像素数据长度 PixelLength = ImageWidth*3; while(PixelLength%4 != 0) ++PixelLength; PixelLength *= ImageHeight; //读取像素数据 PixelData = (GLubyte*)malloc(PixelLength); if(PixelData == 0) exit(0); fseek(pFile,54,SEEK_SET); fread(PixelData,PixelLength,1,pFile); //关闭文件 fclose(pFile); //初始化GLUT并运行 glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(200,200); glutInitWindowSize(ImageWidth,ImageHeight); glutCreateWindow(FileName); glutDisplayFunc(&display); glutMainLoop(); free(PixelData); return 0; }
31 像素的拷贝glCopyPixels()--坐标点坐标,宽度值、高度值、GL_COLOR
#include<GL/glut.h> #include<iostream> using namespace std; #define WindowWidth 400 #define WindowHeight 400 /*函数grab * 抓取窗口中的像素 * 假设窗口宽度为WindowWidth,高度为WindowHeight */ #define BMP_Header_Length 54 void grap() { FILE* pDummyFile; FILE* pWritingFile; GLubyte* pPixelData; GLubyte BMP_Header[BMP_Header_Length]; GLint i, j; GLint PixelDataLength; //计算像素数据的实际长度 i = WindowWidth * 3; //得到每一行的像素数据长度 while(i%4 != 0) //补充数据知道i是4的倍数 ++i; //本来还有更快的算法,但这里追求直观,对速度没有太高要求 PixelDataLength = i*WindowHeight; //内存字节大小 //分配内存和打开文件 pPixelData = (GLubyte*)malloc(PixelDataLength); if(pPixelData == 0) exit(0); pDummyFile = fopen("dummy.bmp", "rb"); if(pDummyFile == 0) exit(0); pWritingFile = fopen("grab.bmp", "wb"); if(pWritingFile == 0) exit(0); //读取像素 glPixelStorei(GL_UNPACK_ALIGNMENT, 4); glReadPixels(0,0,WindowWidth, WindowHeight, GL_BGR_EXT,GL_UNSIGNED_BYTE,pPixelData); //把dummy.bmp的头文件复制为新文件的文件头 fread(BMP_Header,sizeof(BMP_Header),1,pDummyFile); fwrite(BMP_Header,sizeof(BMP_Header),1,pWritingFile); fseek(pWritingFile,0x0012,SEEK_SET); i = WindowWidth; j = WindowHeight; fwrite(&i,sizeof(i),1,pWritingFile); fwrite(&j,sizeof(j),1,pWritingFile); //写入像素数据 fseek(pWritingFile,0,SEEK_END); fwrite(pPixelData,PixelDataLength,1,pWritingFile); //释放内存和关闭文件 fclose(pDummyFile); fclose(pWritingFile); free(pPixelData); } void myDisplay() { glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); glColor3f(1.0,0.0,0.0); glVertex2f(0.0f,0.0f); glColor3f(0.0,1.0,0.0); glVertex2f(1.0f,0.0f); glColor3f(0.0,0.0,1.0); glVertex2f(0.5f,1.0f); glEnd(); glPixelZoom(-0.5f,-0.5f); glRasterPos2i(1,1); glCopyPixels(WindowWidth/2,WindowHeight/2, WindowWidth/2,WindowHeight/2,GL_COLOR); glutSwapBuffers(); grap(); } void myIdle() { cout<<"doing"<<endl; grap(); return; } int main(int argc, char* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE); glutInitWindowPosition(400,400); glutInitWindowSize(400,400); glutCreateWindow("Study04"); glutDisplayFunc(&myDisplay); glutMainLoop(); cout<<"ok"<<endl; return 0; }
10.20 纹理测试
32.1纹理的使用方法,只要指定每一个顶点在纹理图象中所对应的像素位置,OpenGL就会自动计算顶点以外的其它点在纹理图象中所对应的像素位置
#define WindowWidth 400 #define WindowHeight 400 #define WindowTitle "OpenGL纹理测试" #include<GL/glut.h> #include<stdio.h> #include<stdlib.h> /*函数grap *抓取窗口中的像素 *假设窗口宽度为WindowWidth,高度为WindowHeight */ #define BMP_Header_Length 54 void grap() { FILE* pDummyFile; FILE* pWritingFile; GLubyte* pPixelData; GLubyte BMP_Header[BMP_Header_Length]; GLint i,j; GLint PixelDataLength; //计算像素数据的实际长度 i = WindowWidth * 3; //得到每一行的像素数据长度 while(i%4 == 0) ++i; PixelDataLength = i * WindowHeight; //分配内存和打开文件 pPixelData = (GLubyte*)malloc(PixelDataLength); if(pPixelData == 0) exit(0); pDummyFile = fopen("dummy.bmp","rb"); if(pDummyFile == 0) exit(0); pWritingFile = fopen("grap.bmp","wb"); if(pWritingFile == 0) exit(0); //读取像素 glPixelStorei(GL_UNPACK_ALIGNMENT,4); glReadPixels(0,0,WindowWidth,WindowHeight, GL_BGR_EXT,GL_UNSIGNED_BYTE,pPixelData); //把dummy.bmp的文件头复制为新文件的文件头 fread(BMP_Header,sizeof(BMP_Header),1,pDummyFile); fwrite(BMP_Header,sizeof(BMP_Header),1,pWritingFile); fseek(pWritingFile,0x0012,SEEK_SET); i = WindowWidth; j = WindowHeight; fwrite(&i,sizeof(i),1,pWritingFile); fwrite(&j,sizeof(j),1,pWritingFile); //写入像素数据 fseek(pWritingFile,54,SEEK_SET); fwrite(pPixelData,PixelDataLength,1,pWritingFile); //释放内存并关闭文件 fclose(pDummyFile); fclose(pWritingFile); free(pPixelData); } /* 函数power_of_two * 检查一个整数是否为2的整数次方,如果是,返回1,否则返回0 * 实际上只要查看其二进制位中有多少个1,如果正好有1个,返回1,否则返回0 * 在“查看其二进制位中有多少个”时使用了一个小技巧 * 使用n &= (n-1)可以使得n中的减少一个 */ int power_of_two(int n) { if(n <= 0) return 0; return (n&(n-1)) == 0; } /* 函数load_texture * 读取一个BMP文件作为纹理 * 如果失败,返回0,如果成功,返回纹理编号 */ GLuint load_texture(const char* file_name) { GLint width,height,total_bytes; GLubyte* pixels=0; GLuint last_texture_ID,texture_ID=0; //打开文件,如果失败,返回 FILE* pFile=fopen(file_name,"rb"); if(pFile == 0) return 0; //读取文件中图像的宽度和高度 fseek(pFile,0x0012,SEEK_SET); fread(&width,4,1,pFile); fread(&height,4,1,pFile); fseek(pFile,BMP_Header_Length,SEEK_SET); //计算每行像素所占的字节数,并根据此数据计算总像素字节数 { GLint line_bytes = width*3; while(line_bytes % 4 != 0) ++line_bytes; total_bytes = line_bytes*height; } //根据总像素字节数分配内存 pixels = (GLubyte*)malloc(total_bytes); if(pixels == 0) { fclose(pFile); return 0; } //读取像素数据 if(fread(pixels,total_bytes,1,pFile) <= 0) { free(pixels); fclose(pFile); return 0; } //在旧版本的OpenGL中 //如果图像宽度和高度不是2的整数次方,则需要进行缩放 //这里并没有检查openGL版本,出于对版本兼容性的考虑,按旧版本处理 //另外,无论是旧版本还是新版本 //当图像的宽度和高度超过当前openGL实现所支持的最大值时,也要进行缩放 { GLint max; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&max); if(!power_of_two(width) || !power_of_two(height) || width>max || height>max) { const GLint new_width = 256; const GLint new_height = 256; //规定缩放后新的大小为256的正方形 GLint new_line_bytes,new_total_bytes; GLubyte* new_pixels=0; //计算每行所需要的字节数和总字节数 new_line_bytes = new_width * 3; while(new_line_bytes % 4 != 0) ++new_line_bytes; new_total_bytes = new_line_bytes * new_height; //分配内存 new_pixels = (GLubyte*)malloc(new_total_bytes); if(new_pixels == 0) { free(pixels); fclose(pFile); return 0; } //进行像素缩放 gluScaleImage(GL_RGB, width,height,GL_UNSIGNED_BYTE,pixels, new_width,new_height,GL_UNSIGNED_BYTE,new_pixels); //释放原来的像素数据,把pixels指向新的像素数据,并重新设置width和height free(pixels); pixels = new_pixels; width = new_width; height = new_height; } } //分配一个新的纹理编号 glGenTextures(1,&texture_ID); if(texture_ID == 0) { free(pixels); fclose(pFile); return 0; } //绑定新的纹理,载入纹理并设置纹理参数 //在绑定前,先获得原来绑定的纹理编号,以便在最后进行恢复 glGetIntegerv(GL_TEXTURE_BINDING_2D,(int*)&last_texture_ID); glBindTexture(GL_TEXTURE_2D,texture_ID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0, GL_BGR_EXT,GL_UNSIGNED_BYTE,pixels); glBindTexture(GL_TEXTURE_2D,last_texture_ID); //之前为pixels分配的内存可在使用glTexImage2D后释放 //因为此时像素数据已经被openGL另行保存了一份(可能被保存在专门的图形硬件中) free(pixels); return texture_ID; } /* 两个纹理对象的编号 */ GLuint texGround; GLuint texWall; void display() { //清除屏幕 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //设置视角 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(75,1,1,21); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(1,5,5,0,0,0,0,0,1); //使用“地”纹理绘制土地 glBindTexture(GL_TEXTURE_2D,texWall); glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3f(-8.0f,-8.0f,0.0f); glTexCoord2f(0.0f,5.0f); glVertex3f(-8.0f,8.0f,0.0f); glTexCoord2f(5.0f,5.0f); glVertex3f(8.0f,8.0f,0.0f); glTexCoord2f(5.0f,0.0f); glVertex3f(8.0f,-8.0f,0.0f); glEnd(); //使用“墙”纹理绘制栅栏 glBindTexture(GL_TEXTURE_2D,texWall); glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3f(-6.0f,-3.0f,0.0f); glTexCoord2f(0.0f,1.0f); glVertex3f(-6.0f,-3.0f,1.5f); glTexCoord2f(5.0f,1.0f); glVertex3f(6.0f,-3.0f,1.5f); glTexCoord2f(5.0f,0.0f); glVertex3f(6.0f,-3.0f,0.0f); glEnd(); //旋转后再绘制一个 glRotatef(-90,0,0,1); glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3f(-6.0f,-3.0f,0.0f); glTexCoord2f(0.0f,1.0f); glVertex3f(-6.0f,-3.0f,1.5f); glTexCoord2f(5.0f,1.0f); glVertex3f(6.0f,-3.0f,1.5f); glTexCoord2f(5.0f,0.0f); glVertex3f(6.0f,-3.0f,0.0f); glEnd(); //交换缓冲区,并保存像素数据到文件 glutSwapBuffers(); grap(); } int main(int argc, char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(200,200); glutInitWindowSize(WindowWidth,WindowHeight); glutCreateWindow(WindowTitle); glutDisplayFunc(&display); //在这里做一些初始化 glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); texGround = load_texture("ground.bmp"); texWall = load_texture("wall.bmp"); //开始显示 glutMainLoop(); return 0; }
32 跟上个程序原理一样,上一个载入的都是墙的坐标,所以图像也不是很正确
#define WindowWidth 400 #define WindowHeight 400 #define WindowTitle "OpenGL纹理测试" #include<GL/glut.h> #include<stdio.h> #include<stdlib.h> /*函数grap *抓取窗口中的像素 *假设窗口宽度为WindowWidth,高度为WindowHeight */ #define BMP_Header_Length 54 void grap() { FILE* pDummyFile; FILE* pWritingFile; GLubyte* pPixelData; GLubyte BMP_Header[BMP_Header_Length]; GLint i,j; GLint PixelDataLength; //计算像素数据的实际长度 i = WindowWidth * 3; //得到每一行的像素数据长度 while(i%4 == 0) ++i; PixelDataLength = i * WindowHeight; //分配内存和打开文件 pPixelData = (GLubyte*)malloc(PixelDataLength); if(pPixelData == 0) exit(0); pDummyFile = fopen("dummy.bmp","rb"); if(pDummyFile == 0) exit(0); pWritingFile = fopen("grap.bmp","wb"); if(pWritingFile == 0) exit(0); //读取像素 glPixelStorei(GL_UNPACK_ALIGNMENT,4); glReadPixels(0,0,WindowWidth,WindowHeight, GL_BGR_EXT,GL_UNSIGNED_BYTE,pPixelData); //把dummy.bmp的文件头复制为新文件的文件头 fread(BMP_Header,sizeof(BMP_Header),1,pDummyFile); fwrite(BMP_Header,sizeof(BMP_Header),1,pWritingFile); fseek(pWritingFile,0x0012,SEEK_SET); i = WindowWidth; j = WindowHeight; fwrite(&i,sizeof(i),1,pWritingFile); fwrite(&j,sizeof(j),1,pWritingFile); //写入像素数据 fseek(pWritingFile,54,SEEK_SET); fwrite(pPixelData,PixelDataLength,1,pWritingFile); //释放内存并关闭文件 fclose(pDummyFile); fclose(pWritingFile); free(pPixelData); } /* 函数power_of_two * 检查一个整数是否为2的整数次方,如果是,返回1,否则返回0 * 实际上只要查看其二进制位中有多少个1,如果正好有1个,返回1,否则返回0 * 在“查看其二进制位中有多少个”时使用了一个小技巧 * 使用n &= (n-1)可以使得n中的减少一个 */ int power_of_two(int n) { if(n <= 0) return 0; return (n&(n-1)) == 0; } /* 函数load_texture * 读取一个BMP文件作为纹理 * 如果失败,返回0,如果成功,返回纹理编号 */ GLuint load_texture(const char* file_name) { GLint width,height,total_bytes; GLubyte* pixels=0; GLuint last_texture_ID,texture_ID=0; //打开文件,如果失败,返回 FILE* pFile=fopen(file_name,"rb"); if(pFile == 0) return 0; //读取文件中图像的宽度和高度 fseek(pFile,0x0012,SEEK_SET); fread(&width,4,1,pFile); fread(&height,4,1,pFile); fseek(pFile,BMP_Header_Length,SEEK_SET); //计算每行像素所占的字节数,并根据此数据计算总像素字节数 { GLint line_bytes = width*3; while(line_bytes % 4 != 0) ++line_bytes; total_bytes = line_bytes*height; } //根据总像素字节数分配内存 pixels = (GLubyte*)malloc(total_bytes); if(pixels == 0) { fclose(pFile); return 0; } //读取像素数据 if(fread(pixels,total_bytes,1,pFile) <= 0) { free(pixels); fclose(pFile); return 0; } //在旧版本的OpenGL中 //如果图像宽度和高度不是2的整数次方,则需要进行缩放 //这里并没有检查openGL版本,出于对版本兼容性的考虑,按旧版本处理 //另外,无论是旧版本还是新版本 //当图像的宽度和高度超过当前openGL实现所支持的最大值时,也要进行缩放 { GLint max; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&max); if(!power_of_two(width) || !power_of_two(height) || width>max || height>max) { const GLint new_width = 256; const GLint new_height = 256; //规定缩放后新的大小为256的正方形 GLint new_line_bytes,new_total_bytes; GLubyte* new_pixels=0; //计算每行所需要的字节数和总字节数 new_line_bytes = new_width * 3; while(new_line_bytes % 4 != 0) ++new_line_bytes; new_total_bytes = new_line_bytes * new_height; //分配内存 new_pixels = (GLubyte*)malloc(new_total_bytes); if(new_pixels == 0) { free(pixels); fclose(pFile); return 0; } //进行像素缩放 gluScaleImage(GL_RGB, width,height,GL_UNSIGNED_BYTE,pixels, new_width,new_height,GL_UNSIGNED_BYTE,new_pixels); //释放原来的像素数据,把pixels指向新的像素数据,并重新设置width和height free(pixels); pixels = new_pixels; width = new_width; height = new_height; } } //分配一个新的纹理编号 glGenTextures(1,&texture_ID); if(texture_ID == 0) { free(pixels); fclose(pFile); return 0; } //绑定新的纹理,载入纹理并设置纹理参数 //在绑定前,先获得原来绑定的纹理编号,以便在最后进行恢复 glGetIntegerv(GL_TEXTURE_BINDING_2D,(int*)&last_texture_ID); glBindTexture(GL_TEXTURE_2D,texture_ID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0, GL_BGR_EXT,GL_UNSIGNED_BYTE,pixels); glBindTexture(GL_TEXTURE_2D,last_texture_ID); //之前为pixels分配的内存可在使用glTexImage2D后释放 //因为此时像素数据已经被openGL另行保存了一份(可能被保存在专门的图形硬件中) free(pixels); return texture_ID; } /* 两个纹理对象的编号 */ GLuint texGround; GLuint texWall; void display() { //清除屏幕 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //设置视角 glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(75,1,1,21); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); gluLookAt(1,5,5,0,0,0,0,0,1); //使用“地”纹理绘制土地 glBindTexture(GL_TEXTURE_2D,texGround); glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3f(-8.0f,-8.0f,0.0f); glTexCoord2f(0.0f,5.0f); glVertex3f(-8.0f,8.0f,0.0f); glTexCoord2f(5.0f,5.0f); glVertex3f(8.0f,8.0f,0.0f); glTexCoord2f(5.0f,0.0f); glVertex3f(8.0f,-8.0f,0.0f); glEnd(); //使用“墙”纹理绘制栅栏 glBindTexture(GL_TEXTURE_2D,texWall); glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3f(-6.0f,-3.0f,0.0f); glTexCoord2f(0.0f,1.0f); glVertex3f(-6.0f,-3.0f,1.5f); glTexCoord2f(5.0f,1.0f); glVertex3f(6.0f,-3.0f,1.5f); glTexCoord2f(5.0f,0.0f); glVertex3f(6.0f,-3.0f,0.0f); glEnd(); //旋转后再绘制一个 glRotatef(-90,0,0,1); glBegin(GL_QUADS); glTexCoord2f(0.0f,0.0f); glVertex3f(-6.0f,-3.0f,0.0f); glTexCoord2f(0.0f,1.0f); glVertex3f(-6.0f,-3.0f,1.5f); glTexCoord2f(5.0f,1.0f); glVertex3f(6.0f,-3.0f,1.5f); glTexCoord2f(5.0f,0.0f); glVertex3f(6.0f,-3.0f,0.0f); glEnd(); //交换缓冲区,并保存像素数据到文件 glutSwapBuffers(); grap(); } int main(int argc, char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(200,200); glutInitWindowSize(WindowWidth,WindowHeight); glutCreateWindow(WindowTitle); glutDisplayFunc(&display); //在这里做一些初始化 glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); texGround = load_texture("ground.bmp"); texWall = load_texture("wall.bmp"); //开始显示 glutMainLoop(); return 0; }
33.alpha测试
#define WindowWidth 400 #define WindowHeight 400 #define WindowTitle "OpenGL纹理测试" #include<GL/glut.h> #include<stdio.h> #include<stdlib.h> /*函数grap *抓取窗口中的像素 *假设窗口宽度为WindowWidth,高度为WindowHeight */ #define BMP_Header_Length 54 /* 函数power_of_two * 检查一个整数是否为2的整数次方,如果是,返回1,否则返回0 * 实际上只要查看其二进制位中有多少个1,如果正好有1个,返回1,否则返回0 * 在“查看其二进制位中有多少个”时使用了一个小技巧 * 使用n &= (n-1)可以使得n中的减少一个 */ int power_of_two(int n) { if(n <= 0) return 0; return (n&(n-1)) == 0; } /* 函数load_texture * 读取一个BMP文件作为纹理 * 如果失败,返回0,如果成功,返回纹理编号 */ GLuint load_texture(const char* file_name) { GLint width,height,total_bytes; GLubyte* pixels=0; GLuint last_texture_ID,texture_ID=0; //打开文件,如果失败,返回 FILE* pFile=fopen(file_name,"rb"); if(pFile == 0) return 0; //读取文件中图像的宽度和高度 fseek(pFile,0x0012,SEEK_SET); fread(&width,4,1,pFile); fread(&height,4,1,pFile); fseek(pFile,BMP_Header_Length,SEEK_SET); //计算每行像素所占的字节数,并根据此数据计算总像素字节数 { GLint line_bytes = width*3; while(line_bytes % 4 != 0) ++line_bytes; total_bytes = line_bytes*height; } //根据总像素字节数分配内存 pixels = (GLubyte*)malloc(total_bytes); if(pixels == 0) { fclose(pFile); return 0; } //读取像素数据 if(fread(pixels,total_bytes,1,pFile) <= 0) { free(pixels); fclose(pFile); return 0; } //在旧版本的OpenGL中 //如果图像宽度和高度不是2的整数次方,则需要进行缩放 //这里并没有检查openGL版本,出于对版本兼容性的考虑,按旧版本处理 //另外,无论是旧版本还是新版本 //当图像的宽度和高度超过当前openGL实现所支持的最大值时,也要进行缩放 { GLint max; glGetIntegerv(GL_MAX_TEXTURE_SIZE,&max); if(!power_of_two(width) || !power_of_two(height) || width>max || height>max) { const GLint new_width = 256; const GLint new_height = 256; //规定缩放后新的大小为256的正方形 GLint new_line_bytes,new_total_bytes; GLubyte* new_pixels=0; //计算每行所需要的字节数和总字节数 new_line_bytes = new_width * 3; while(new_line_bytes % 4 != 0) ++new_line_bytes; new_total_bytes = new_line_bytes * new_height; //分配内存 new_pixels = (GLubyte*)malloc(new_total_bytes); if(new_pixels == 0) { free(pixels); fclose(pFile); return 0; } //进行像素缩放 gluScaleImage(GL_RGB, width,height,GL_UNSIGNED_BYTE,pixels, new_width,new_height,GL_UNSIGNED_BYTE,new_pixels); //释放原来的像素数据,把pixels指向新的像素数据,并重新设置width和height free(pixels); pixels = new_pixels; width = new_width; height = new_height; } } //分配一个新的纹理编号 glGenTextures(1,&texture_ID); if(texture_ID == 0) { free(pixels); fclose(pFile); return 0; } //绑定新的纹理,载入纹理并设置纹理参数 //在绑定前,先获得原来绑定的纹理编号,以便在最后进行恢复 glGetIntegerv(GL_TEXTURE_BINDING_2D,(int*)&last_texture_ID); glBindTexture(GL_TEXTURE_2D,texture_ID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,GL_REPEAT); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0, GL_BGR_EXT,GL_UNSIGNED_BYTE,pixels); glBindTexture(GL_TEXTURE_2D,last_texture_ID); //之前为pixels分配的内存可在使用glTexImage2D后释放 //因为此时像素数据已经被openGL另行保存了一份(可能被保存在专门的图形硬件中) free(pixels); return texture_ID; } /* 将当前纹理BGR格式转换为BGRA格式 * 纹理中像素的RGB值如果与指定rgb相差不超过absolute,则将Alpha设置为0.0,否则设置为1.0 */ void texture_colorKey(GLubyte r,GLubyte g,GLubyte b,GLubyte absolute) { GLint width,height; GLubyte* pixels=0; //获得纹理的大小信息 glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_WIDTH,&width); glGetTexLevelParameteriv(GL_TEXTURE_2D,0,GL_TEXTURE_HEIGHT,&height); //分配空间并获得纹理像素 pixels = (GLubyte*)malloc(width*height*4); if(pixels == 0) return; glGetTexImage(GL_TEXTURE_2D,0,GL_BGRA_EXT,GL_UNSIGNED_BYTE,pixels); //修改像素中的Alpha值 //其中pixels[i*4],pixels[i*4+1],pixels[i*4+2],pixels[i*4+3] //分别表示第i个像素的蓝、绿、红、Alpha四种分量,0表示最小,255表示最大 { GLint i; GLint count = width*height; for(i=0;i<count;++i) { if(abs(pixels[i*4]-b) <= absolute && abs(pixels[i*4+1]-g) <= absolute && abs(pixels[i*4+2]-r) <= absolute) pixels[i*4+3] = 0; else pixels[i*4+3] = 255; } } //将修改后的像素重新设置到纹理中,释放内存 glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,width,height,0, GL_BGRA_EXT,GL_UNSIGNED_BYTE,pixels); free(pixels); } void display() { static int initialized=0; static GLuint texWindow=0; static GLuint texPicture=0; //执行初始化操作,包括:读取相片,读取相框,将相框由BGR颜色转换为BGRA, //启用二维纹理 if(!initialized) { texPicture = load_texture("picture.bmp"); texWindow = load_texture("window.bmp"); glBindTexture(GL_TEXTURE_2D,texWindow); texture_colorKey(255,255,255,10); glEnable(GL_TEXTURE_2D); initialized = 1; } glClear(GL_COLOR_BUFFER_BIT); //绘制相片,此时不需要进行Alpha测试,所有的像素都进行绘制 glBindTexture(GL_TEXTURE_2D,texPicture); glDisable(GL_ALPHA_TEST); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2f(-1.0f,-1.0f); glTexCoord2f(0,1); glVertex2f(-1.0f,1.0f); glTexCoord2f(1,1); glVertex2f(1.0f,1.0f); glTexCoord2f(1,0); glVertex2f(1.0f,-1.0f); glEnd(); //绘制相框,此时进行Alpha测试,只绘制不透明部分的像素 glBindTexture(GL_TEXTURE_2D,texWindow); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER,0.5f); glBegin(GL_QUADS); glTexCoord2f(0,0); glVertex2f(-1.0f,-1.0f); glTexCoord2f(0,1); glVertex2f(-1.0f,1.0f); glTexCoord2f(1,1); glVertex2f(1.0f,1.0f); glTexCoord2f(1,0); glVertex2f(1.0f,-1.0f); glEnd(); //交换缓冲 glutSwapBuffers(); } int main(int argc, char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowPosition(200,200); glutInitWindowSize(WindowWidth,WindowHeight); glutCreateWindow("alpha-test"); glutDisplayFunc(&display); //开始显示 glutMainLoop(); return 0; }
10.21
34. 模版测试。我的测试失败,具体的写法可以参考开头给的网址。
#include<GL/glut.h> void draw_sphere() { //设置光源 glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); { GLfloat pos[] = {5.0f,5.0f,0.0f,1.0f}, ambient[] = {0.0f,0.0f,1.0f,1.0f}; glLightfv(GL_LIGHT0,GL_POSITION,pos); glLightfv(GL_LIGHT0,GL_AMBIENT,ambient); } //绘制一个球体 glColor3f(1,0,0); glPushMatrix(); glTranslatef(0,0,2); glutSolidSphere(0.5,20,20); glPopMatrix(); } void display() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //设置观察点 glMatrixMode(GL_PROJECTION); //采用投影矩阵 glLoadIdentity(); gluPerspective(60,1,5,25); //投影区域,角度,宽高比,近距离,远距离 glMatrixMode(GL_MODELVIEW); //采用模型矩阵 glLoadIdentity(); gluLookAt(5,0,6.5,0,0,0,0,1,0); glEnable(GL_DEPTH_TEST); //绘制球体 //glDisable(GL_STENCIL_TEST); draw_sphere(); //绘制一个平面镜。在绘制的同时注意设置模版缓冲 //另外,为了保证平面镜之后的镜像能够正确绘制,在绘制平面 //镜像时需要将深度缓冲区设置为只读的。 //在绘制时暂时关闭光照效果 glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); glStencilFunc(GL_ALWAYS,1,0xFF); glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE); glEnable(GL_STENCIL_TEST); glDisable(GL_LIGHTING); glColor3f(0.5f,0.5f,0.5f); glDepthMask(GL_FALSE); glRectf(-1.5f,-1.5f,1.5f,1.5f); glDepthMask(GL_TRUE); //绘制一个与先前球体关于平面镜对称的球体,注意光源的位置也要发生对称改变 //因为平面镜是在X轴和Y轴所确定的平面,所以只要Z坐标取反即可实现对称 //为了保证球体的绘制范围被限制在平面镜内部,使用模版测试 glEnable(GL_STENCIL_TEST); glStencilFunc(GL_EQUAL,1,0xFF); glStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE); glScalef(1.0f,1.0f,-1.0f); draw_sphere(); //交换缓冲 glutSwapBuffers(); } int main(int argc, char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowPosition(200,200); glutInitWindowSize(400,400); glutCreateWindow("study"); glutDisplayFunc(&display); glutMainLoop(); return 0; }
35 这题只敲了代码,没插件就没有运行,也没有图,具体大家可以看开头的网址
//#include"GLee.h" #include<GL/glut.h> #include<stdio.h> void display() { glClear(GL_COLOR_BUFFER_BIT); //if(GLEE_ARB_window_pos) //{//如果支持GL_ARB_window_pos //则使用glWindowPos2iARB函数,指定绘制位置 // printf("支持GL_ARB_window_pos\n"); // printf("使用glWindowPos函数\n"); // glWindowPos2iARB(100,100); // }else{ GLint viewport[4]; GLdouble modelview[16],projection[16]; GLdouble x, y, z; printf("不支持GL_ARB_window_pos\n"); printf("使用glRasterPos函数\n"); glGetIntegerv(GL_VIEWPORT,viewport); glGetDoublev(GL_MODELVIEW_MATRIX,modelview); glGetDoublev(GL_PROJECTION_MATRIX,projection); gluUnProject(100,100,0.5,modelview,projection,viewport,&x,&y,&z); glRasterPos3d(x,y,z); // } {//绘制一个5*5的像素块 GLubyte pixels[5][4][4]; //把像素中的所有像素都设置为红色 int i,j; for(i=0;i<5;++i) for(j=0;j<5;++j) { pixels[i][j][0] = 255; pixels[i][j][1] = 0; pixels[i][j][2] = 0; pixels[i][j][3] = 255; } glDrawPixels(5,5,GL_RGBA,GL_UNSIGNED_BYTE,pixels); } glutSwapBuffers(); } int main(int argc,char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowPosition(100,100); glutInitWindowSize(512,512); glutCreateWindow("OpenGL"); glutDisplayFunc(&display); glutMainLoop(); return 0; }
36 显示字体 用的显示列表
#include<GL/glut.h> #include<windows.h> //ASCII字符总共只有0到127,一共128种字符 #define MAX_CHAR 128 void drawString(const char* str) { static int isFirstCall = 1; static GLuint lists; if(isFirstCall){//如果是第一次调用,执行初始化 //为每一个ASCII字符产生一个显示列表 isFirstCall = 0; //申请MAX_CHAR个连续的显示列表编号 lists = glGenLists(MAX_CHAR); //把每个字符的绘制命令都装到对应的显示列表中 wglUseFontBitmaps(wglGetCurrentDC(),0,MAX_CHAR,lists); //调用每个字符对应的显示列表,绘制每个字符 for(;*str!='\0';++str) glCallList(lists + *str); } } void display() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f,0.0f,0.0f); glRasterPos2f(0.0f,0.0f); drawString("hello,world"); glutSwapBuffers(); } int main(int argc,char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowPosition(100,100); glutInitWindowSize(512,512); glutCreateWindow("OpenGL"); glutDisplayFunc(&display); glutMainLoop(); return 0; }
37 字体设置
#include<GL/glut.h> #include<windows.h> //ASCII字符总共只有0到127,一共128种字符 #define MAX_CHAR 128 void drawString(const char* str) { static int isFirstCall = 1; static GLuint lists; if(isFirstCall){//如果是第一次调用,执行初始化 //为每一个ASCII字符产生一个显示列表 isFirstCall = 0; //申请MAX_CHAR个连续的显示列表编号 lists = glGenLists(MAX_CHAR); //把每个字符的绘制命令都装到对应的显示列表中 wglUseFontBitmaps(wglGetCurrentDC(),0,MAX_CHAR,lists); //调用每个字符对应的显示列表,绘制每个字符 for(;*str!='\0';++str) glCallList(lists + *str); } } void selectFont(int size,int charset,const char* face){ HFONT hFont=CreateFontA(size,0,0,0,FW_MEDIUM,0,0,0, charset,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS,face); HFONT hOldFont = (HFONT)SelectObject(wglGetCurrentDC(),hFont); DeleteObject(hOldFont); } void display() { selectFont(48,ANSI_CHARSET,"Comic Sans MS"); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0f,0.0f,0.0f); glRasterPos2f(0.0f,0.0f); drawString("Hello,World!"); glutSwapBuffers(); } int main(int argc,char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowPosition(100,100); glutInitWindowSize(512,512); glutCreateWindow("OpenGL"); glutDisplayFunc(&display); glutMainLoop(); return 0; }
38 显示汉字
#include<GL/glut.h> #include<windows.h> //ASCII字符总共只有0到127,一共128种字符 #define MAX_CHAR 128 void drawCNString(const char* str) { int len,i; wchar_t* wstring; HDC hDC=wglGetCurrentDC(); GLuint list = glGenLists(1); //计算字符个数 //如果是双字节字符的(比如中文字符),两个字节才算一个字符 //否则一个字节算一个字符 len=0; for(i=0;str[i]!='\0';++i) { if(IsDBCSLeadByte(str[i])) ++i; ++len; } //将混合字符转化为宽字符 wstring = (wchar_t*)malloc((len+1)*sizeof(wchar_t)); MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,str,-1,wstring,len); wstring[len] = '\0'; //逐个输出字符 for(i=0;i<len;++i) { wglUseFontBitmapsW(hDC,wstring[i],1,list); glCallList(list); } //回收所有临时资源 free(wstring); glDeleteLists(list,1); } void selectFont(int size,int charset,const char* face){ HFONT hFont=CreateFontA(size,0,0,0,FW_MEDIUM,0,0,0, charset,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH | FF_SWISS,face); HFONT hOldFont = (HFONT)SelectObject(wglGetCurrentDC(),hFont); DeleteObject(hOldFont); } void display() { glClear(GL_COLOR_BUFFER_BIT); selectFont(48,ANSI_CHARSET,"Comic Sans MS"); glColor3f(1.0f,0.0f,0.0f); glRasterPos2f(-0.7f,0.4f); drawCNString("Hello,World!"); selectFont(48,GB2312_CHARSET,"楷体_GB2312"); glColor3f(1.0f,1.0f,0.0f); glRasterPos2f(-0.7f,-0.1f); drawCNString("当代中国汉字"); selectFont(48,GB2312_CHARSET,"华文仿宋"); glColor3f(0.0f,1.0f,0.0f); glRasterPos2f(-0.7f,-0.6f); drawCNString("傳統中國漢字"); glutSwapBuffers(); } int main(int argc,char* argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE); glutInitWindowPosition(100,100); glutInitWindowSize(512,512); glutCreateWindow("OpenGL"); glutDisplayFunc(&display); glutMainLoop(); return 0; }
OVER!