OpenGL: Wireframe Rectangle(CR)

PART ONE

 codes.cpp

#include <stdio.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <iostream>
using namespace std;

#define width 222
#define height 207
#define num 3 //三角形顶点计数器
#define point_num 4	//顶点空间计数器
#define triangle_num 2 //三角形图元计数器

struct Vector3f {
	GLfloat x;
	GLfloat y;
	GLfloat z;
};

struct Color {
	GLubyte r;
	GLubyte g;
	GLubyte b;
	GLubyte a;
};

struct Indice {
	int v0;
	int v1;
	int v2;
};

GLubyte image[height][width][4];
void initRectangle()
{
	//NDC下点位置信息的初始化
	Vector3f points[point_num] = {
		{0.0f,0.0f,0.0f},
		{0.5f,0.0f,0.0f},
		{0.5f,0.5f,0.0f},
		{0.0f,0.5f,0.0f}
	};
	//颜色空间初始化
	Color colors[point_num] = {
		{255,0,0,0},
		{0,255,0,0},
		{0,0,255,0},
		{255,255,0,0}
	};
	//索引空间初始化 
	Indice indices[triangle_num] = {
		{0,1,3},
		{3,2,1},	
	};

	for (int j = 0; j < triangle_num; j++) {
		//采样出三角形的索引存入v[num]
		int v[num] = { indices[j].v0,indices[j].v1,indices[j].v2 };
		//cout << v[0] << " " << v[1] << " " <<v[2] << endl;
		//根据采样出的索引v[]对points[]和colors[]空间进行采样
		Vector3f triangle_points[num] = { points[v[0]],points[v[1]],points[v[2]] };
		Color triangle_colors[num] = { colors[v[0]],colors[v[1]],colors[v[2]] };	
		//cout << triangle_points[0].x << " " << triangle_points[0].y << " " << triangle_points[0].z << endl;
		
		//triangle_points[]空间转换的结果存入screen[]空间
		Vector3f screen[num];
		for (int i = 0; i < num; i++) { 
			screen[i].x = (triangle_points[i].x + 1.0f) * (width / 2 - 1);
			screen[i].y = (triangle_points[i].y + 1.0f) * (height / 2 - 1);
			screen[i].z = triangle_points[i].z;	//zbuffer维持NDC空间
		}
		
		int LINE_LOOP = num;	//模式选择器
		//if (j == 0) { 
		//	LINE_LOOP = num; //GL_LINE_LOOP
		//	cout << "GL_LINE_LOOP" << endl;
		//}
		//else {
		//	LINE_LOOP = num - 1;//GL_LINE_STRIP
		//	cout << "GL_LINE_STRIP" << endl;
		//}
		for (int i = 0; i < LINE_LOOP; i++) {
			//screen[]空间线段起点和终点x、y的采样
			int start_x = (int)screen[i].x;
			int start_y = (int)screen[i].y;
			int end_x;
			int end_y;
			if (i == LINE_LOOP - 1) {
				end_x = (int)screen[0].x;
				end_y = (int)screen[0].y;
			}
			else {
				end_x = (int)screen[i+1].x;
				end_y = (int)screen[i+1].y;
			}

			//点关于x轴的排序
			if (start_x > end_x) {
				swap(start_x, end_x);
				swap(start_y, end_y);
			}

			//斜率算法画线
			float delta_x = end_x - start_x;
			float delta_y = end_y - start_y;
			if (delta_x == 0) {
				if (delta_y < 0) {
					swap(start_y, end_y);
				}
				for (int y = start_y, x = start_x; y < end_y; y++) {
					image[y][x][0] = triangle_colors[i].r;
					image[y][x][1] = triangle_colors[i].g;
					image[y][x][2] = triangle_colors[i].b;
					image[y][x][3] = triangle_colors[i].a;
				}
			}
			else {
				float gradient = (float)delta_y / delta_x; //斜率定义
				for (int x = start_x; x < end_x; x++) {		
					int y = (int)(gradient * (x - start_x) + start_y);//斜率公式变形
					image[y][x][0] = triangle_colors[i].r;
					image[y][x][1] = triangle_colors[i].g;
					image[y][x][2] = triangle_colors[i].b;
					image[y][x][3] = triangle_colors[i].a;

				}
			}
		}
	}
}

void render()
{
	glClear(GL_COLOR_BUFFER_BIT);
	glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, image);
	glutSwapBuffers();
}

int main(int argc, char** argv)
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
	glutInitWindowSize(width, height);
	glutInitWindowPosition(200, 100);
	int id = glutCreateWindow("线框矩形");

	GLenum err = glewInit();
	if (err != GLEW_OK) {
		fprintf(stderr, "Error: '%s'\n", glewGetErrorString(err));
		return 1;
	}

	initRectangle();
	glutDisplayFunc(render);
	glutMainLoop();

	return 0;
}

部分二

代码分析

1、将顶点计数器point_num设为4,在initRectangle()中定义四个顶点points[point_num]。将三角形计数器triangle_num设为2,通过对indices[triangle_num]初始化构造出两个三角形的顶点索引。通过for (int i = 0; i < point_num; i++){.......}对NDC顶点坐变换成屏幕空间的像素坐标。通过for (int j = 0; j < triangle_num; j++){......}实现对不同三角形顶点的索引数据的获取,indices[j].v0、indices[j].v1、indices[j].v2实现第j个三角形的三个顶点v0、v1、v2索引的采样。将当前三角形的顶点索引indices[j].v0、indices[j].v1、indices[j].v2放入points[?]中的“?”后,有points[indices[j].v0]、points[indices[j].v1]、points[indices[j].v2] ,根据三角形顶点的索引数据完成对顶点坐标数据的采样。triangle[3] = {points[indices[j].v1, points[indices[j].v1], points[indices[j].v2] }实现对三角形三个顶点位置数据的装配,生成一个三角形图元;color[3] = { colors[indices[j].v0], colors[indices[j].v1], colors[indices[j].v2] }实现相应顶点的颜色采样。通过for (int i = 0; i < 3; i++) {......}实现GL_LINE_LOOP模式的“连点成线”。

2、在计算机图形学中,三角形是最简单的多边形,任何复杂的多边形都可以拆成n个三角形的形式。将一个矩阵拆成两个三角形,分别进行绘制,得到由两个线框三角形合成的线框矩形。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱书网

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值