7天学习opengl入门

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;
}

7.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);
	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;
}


8.

#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;
}


15.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);
	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;
}


16.设置了线宽

#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;
}


20.opengl中面是具有两面的,opengl画点的顺序不变,但从面的两个面来看这些点的相连顺序相反。设置不同的目标方向,出现的面就不同。

#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!


  • 25
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
1 课程简介:本课程详细讲解了OpenGL入门到精通的理论+实践知识,对于每一个知识点都会带领学员通过代码来实现功能。其中涵盖了基础图元绘制,基础光照,高级过程,高级光照等内容;当前图形引擎的应用已经越来越广泛,春晚以及各大综艺节目已经开始使用XR作为主流的内容制作技术,房地产漫游及Web渲染技术已经开始茁壮发展,VR也即将突破硬件瓶颈;普遍的游戏引擎在独特的领域已经无法完全实用,且我们国家要发展自主科技技术,图形引擎以及CAD等卡脖子技术一定会蓬勃发展,所以同学们要抓住机会,趁势而上,熟悉底层,博取更大发展,学习OpenGL底层接口的应用以及图形学算法,将是您向纵深发展的第一步!2 课程解决优势:很多同学学习OpenGL最难的是找到路径,并且其中牵扯到的理论知识点无法完全理解透彻(比如VAO与VBO的区别,MVP矩阵变换的推导及原理,光照系统的设计及算法推导,帧缓存的灵活应用等),我们的课程可以带领大家从原理+实践的角度进行学习,每一个知识点都会:a 推导基础公式及原理 b 一行一行进行代码实践从而能够保证每位同学都学有所得,能够看得懂,学得会,用得上,并且能够培养自主研究的能力。学习课程所得:学习本课程完毕之后,学员可以全方位的完全了解OpenGL当中的必要接口,并且可以对图形学的基础知识融会贯通,可以制作中级的特效。并且对于UnrealEngine以及Unity3D的学习更加轻松,对于各类商业引擎当中的算法以及内容制作手法更加深刻理解把控。学员也可以自行进行图形引擎的设计以及研究,并且将本课程的知识点进行代码模块化编写;能够自主推导图形学管线以及应用当中的各类公式,并且理解其几何含义。 代码与PPT资源,已随课程附赠,请同学们对应课程下载 

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值