画立体图 https://blog.csdn.net/heyuchang666/article/details/77508256
GLFW 画三角形
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <vector>
#include <iostream>
using namespace std;
const int Width = 1920;
const int Height = 1080;
// draw point / line / triangle
void drawPoint(double x, double y) {
/* Draw a point */
x = x / Width;
y = y / Height;
//glPointSize(2.0f);
glBegin(GL_POINTS);
glColor3f(1.0, 0.0, 0.0); // Red
glVertex2f(x, y);
glEnd();
}
void drawLint(double x1, double y1, double x2, double y2) {
//glLineWidth(2);//设置线段宽度
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(x1, y1); //定点坐标范围
glVertex2f(x2, y2);
glEnd();
}
void drawTriangle(double x1, double y1, double x2, double y2, double x3, double y3) {
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0); // Red
glVertex3f(x1, y1, 0.0);
glColor3f(0.0, 1.0, 0.0); // Green
glVertex3f(x2, y2, 0.0);
glColor3f(0.0, 0.0, 1.0); // Blue
glVertex3f(x3, y3, 0.0);
glEnd();
}
void initWindow(GLFWwindow* window)
{
glfwMakeContextCurrent(window);
设置按键回调
//glfwSetKeyCallback(window, mouse_button_callback);
//设置鼠标按键点下松开的回调
glfwSetMouseButtonCallback(window, mouse_button_callback);
//设置鼠标移动的回调
glfwSetCursorPosCallback(window, curse_poscallback);
设置窗口大小改变的回调,让绘画区域在窗口中间
//glfwSetWindowSizeCallback(window, windowResize_callback);
}
void initParam()
{
//显示规则:窗口左下角坐标为0,0;所以下行代码表示在窗口左下角向右向上的400个像素单位作为画布
glViewport(0, 0, Width, Height);//设置显示区域400*400,但是可以拖动改变窗口大小
glLineWidth(3.0);//设置线条宽度,3个像素
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);//设置点圆滑
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);//设置线光滑
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
int main(void) {
if (!glfwInit()) return -1;
// a windowed mode window and its OpenGL context
GLFWwindow* window = glfwCreateWindow(Width, Height, "Hello World", NULL, NULL);
if (window == NULL) {
glfwTerminate();
return -1;
}
// Make the window's context current
glfwMakeContextCurrent(window);
// Set Mouse
initWindow(window);
initParam();
pair<int, int> test[8] = { {100,200},{200,100},{200,-100},{100,-200},{-100,-200},{-200,-100},{-200,100},{-100,200} };
// Loop until the user closes the window
while (!glfwWindowShouldClose(window)) {
drawTriangle(0, 0, 0.5, 0, 0, 0.5);
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
glfwTerminate();
return 0;
}
GLFW 直线/圆
与鼠标交互坐标有问题。 圆与直线是在中心为原点,而取鼠标坐标是以左上角为原点。
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <vector>
#include <iostream>
using namespace std;
const int Width = 1920;
const int Height = 1080;
// draw point / line / triangle
void drawPoint(double x, double y) {
/* Draw a point */
x = x / Width;
y = y / Height;
//glPointSize(2.0f);
glBegin(GL_POINTS);
glColor3f(1.0, 0.0, 0.0); // Red
glVertex2f(x, y);
glEnd();
}
void drawLint(double x1, double y1, double x2, double y2) {
//glLineWidth(2);//设置线段宽度
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(x1, y1); //定点坐标范围
glVertex2f(x2, y2);
glEnd();
}
void drawTriangle(double x1, double y1, double x2, double y2, double x3, double y3){
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0); // Red
glVertex3f(x1, y1, 0.0);
glColor3f(0.0, 1.0, 0.0); // Green
glVertex3f(x2, y2, 0.0);
glColor3f(0.0, 0.0, 1.0); // Blue
glVertex3f(x3, y3, 0.0);
glEnd();
}
// HomeWork
void DDALine(int x1, int y1, int x2, int y2) {
bool change = false;
if (abs(y2 - y1) / abs(x2 - x1) > 1) {
change = true;
swap(x1, y1);
swap(x2, y2);
}
if (x2 - x1 < 0) {
swap(x1, x2);
swap(y1, y2);
}
double dx, dy, y, k;
dx = x2 - x1;
dy = y2 - y1;
k = dy / dx;
int x = x1;
y = y1;
for (; x <= x2; x++) {
if(!change)
drawPoint(x, int(y + 0.5));
else
drawPoint(int(y + 0.5),x);
y += k;
}
}
void MidPointLine(int x1, int y1, int x2, int y2) {
bool change = false;
bool x_change = false;
if (1.0*abs(y2 - y1) / abs(x2 - x1) > 1) {
change = true;
swap(x1, y1);
swap(x2, y2);
}
if (x2 - x1 < 0) {
swap(x1, x2);
swap(y1, y2);
}
if (1.0*(y1 - y2) / (x1 - x2) < 0 && 1.0*(y1 - y2) / (x1 - x2) > -1) {
y1 = -1 * y1; y2 = -1 * y2;
x_change = true;
}
int a, b, c, x, y, d0, d1, d2, d;
a = y1 - y2;
b = x2 - x1;
c = x1 * y2 - x2 * y1;
d0 = 2 * a + b;
d1 = 2 * a;
d2 = 2 * (a + b);
d = d0;
x = x1; y = y1;
drawPoint(x, y);
while (x <= x2) {
if (d < 0) {
d += d2;
x++; y++;
}
else {
d += d1;
x++;
}
if (!change)
if(x_change) drawPoint(x, -1*y);
else drawPoint(x, y);
else
if(x_change) drawPoint(y,-1*x);
else drawPoint(y, x);
}
}
void BresenHamline(int x1, int y1, int x2, int y2) {
bool change = false;
bool x_change = false;
if (1.0*abs(y2 - y1) / abs(x2 - x1) > 1) {
change = true;
swap(x1, y1);
swap(x2, y2);
}
if (x2 - x1 < 0) {
swap(x1, x2);
swap(y1, y2);
}
if (1.0*(y1 - y2) / (x1 - x2) < 0 && 1.0*(y1 - y2) / (x1 - x2) > -1) {
y1 = -1 * y1; y2 = -1 * y2;
x_change = true;
}
int x, y, dx, dy;
float k, e;
dx = x2 - x1;
dy = y2 - y1;
k = 1.0* dy / dx;
e = -0.5; x = x1; y = y1;
for (int i = 0; i <= dx; i++) {
if (!change)
if (x_change) drawPoint(x, -1 * y);
else drawPoint(x, y);
else
if (x_change) drawPoint(y, -1 * x);
else drawPoint(y, x);
x = x + 1;
e = e + k;
if (e >= 0) {
y++;
e -= 1;
}
}
}
void IntegerBresenhamline(int x1, int y1, int x2, int y2) {
bool change = false;
bool x_change = false;
if (1.0*abs(y2 - y1) / abs(x2 - x1) > 1) {
change = true;
swap(x1, y1);
swap(x2, y2);
}
if (x2 - x1 < 0) {
swap(x1, x2);
swap(y1, y2);
}
if (1.0*(y1 - y2) / (x1 - x2) < 0 && 1.0*(y1 - y2) / (x1 - x2) > -1) {
y1 = -1 * y1; y2 = -1 * y2;
x_change = true;
}
int x, y, dx, dy, e;
dx = x2 - x1;
dy = y2 - y1;
e = -1 * dx;
x = x1; y = y1;
for (int i = 0; i <= dx; i++) {
if (!change)
if (x_change) drawPoint(x, -1 * y);
else drawPoint(x, y);
else
if (x_change) drawPoint(y, -1 * x);
else drawPoint(y, x);
x++;
e = e + 2 * dy;
if (e >= 0) {
y++;
e -= 2 * dx;
}
}
}
void Drawlines(int x1, int y1, int x2, int y2) {
int x = x1, y = y1, dx = abs(x2 - x1), dy = abs(y2 - y1), s1 = 1, s2 = 1, e, flag = 0;
if (x1 >= x2) s1 = -1;
if (y1 >= y2) s2 = -1;
if (dy > dx) { int change = dx; dx = dy; dy = change; flag = 1; }
e = -dx;
int DX = 2 * dx, DY = 2 * dy;
for (int i = 1; i <= dx; i++) {
drawPoint(x, y);
if (e >= 0) {
if (!flag) y += s2;
else x += s1;
e = e - DX;
}
if (!flag) x += s1;
else y += s2;
e = e + DY;
}
}
void Bresenham_Circle(int xc, int yc, int r) {
int x, y, d;
x = 0; y = r; d = 5 - 4 * r;
drawPoint(x + xc, y + yc);
while (x < y)
{
if (d < 0) d = d + 8 * x + 12;
else {
d = d + 8 * (x - y) + 20;
y--;
}
x++;
drawPoint(x + xc, y + yc); drawPoint(y + xc, x + yc);
drawPoint(y + xc, -x + yc); drawPoint(x + xc, -y + yc);
drawPoint(-x + xc, -y + yc); drawPoint(-y + xc, -x + yc);
drawPoint(-x + xc, y + yc); drawPoint(-y + xc, x + yc);
}
}
// Listen Mouse
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
double X0, Y0;
glfwGetCursorPos(window, &X0, &Y0); //获得鼠标位置
printf("in %f %f ", X0, Y0);
Bresenham_Circle(X0 - Width / 2 , Height / 2 -Y0, 50);
}
}
void curse_poscallback(GLFWwindow *window, double x, double y){
cout << "(pos:" << x << "," << y << ")" << endl;
}
void initWindow(GLFWwindow* window)
{
glfwMakeContextCurrent(window);
设置按键回调
//glfwSetKeyCallback(window, mouse_button_callback);
//设置鼠标按键点下松开的回调
glfwSetMouseButtonCallback(window, mouse_button_callback);
//设置鼠标移动的回调
glfwSetCursorPosCallback(window, curse_poscallback);
设置窗口大小改变的回调,让绘画区域在窗口中间
//glfwSetWindowSizeCallback(window, windowResize_callback);
}
void initParam()
{
//显示规则:窗口左下角坐标为0,0;所以下行代码表示在窗口左下角向右向上的400个像素单位作为画布
glViewport(0, 0, Width, Height);//设置显示区域400*400,但是可以拖动改变窗口大小
glLineWidth(3.0);//设置线条宽度,3个像素
glEnable(GL_BLEND);
glEnable(GL_POINT_SMOOTH);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);//设置点圆滑
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);//设置线光滑
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
int main(void) {
if (!glfwInit()) return -1;
// a windowed mode window and its OpenGL context
GLFWwindow* window = glfwCreateWindow(Width, Height, "Hello World", NULL, NULL);
if (window == NULL) {
glfwTerminate();
return -1;
}
// Make the window's context current
glfwMakeContextCurrent(window);
// Set Mouse
initWindow(window);
initParam();
pair<int, int> test[8] = { {100,200},{200,100},{200,-100},{100,-200},{-100,-200},{-200,-100},{-200,100},{-100,200} };
// Loop until the user closes the window
while (!glfwWindowShouldClose(window)) {
for (int i = 0; i < 8; i++) {
IntegerBresenhamline(0, 0, test[i].first, test[i].second);
/* MidPointLine(test[i].first, test[i].second, 0, 0);*/
}
Bresenham_Circle(0, 0, 100);
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
glfwTerminate();
return 0;
}
GLUT成功代码
#include <string>
#include <assert.h>
#include <cmath>
#include <iostream>
#include <vector>
#include <GL/glut.h>
using namespace std;
typedef vector<int> list;
vector<list> ls, cs;
int old_x, old_y, new_x, new_y, cx, cy, cr;
int mouse_type;
// draw point / line / triangle
void drawPoint(int x, int y) {
/* Draw a point */
//glPointSize(2.0f);
glBegin(GL_POINTS);
glColor3f(1.0, 0.0, 0.0); // Red
glVertex2i(x, y);
glEnd();
}
void drawLint(double x1, double y1, double x2, double y2) {
//glLineWidth(2);//设置线段宽度
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex2f(x1, y1); //定点坐标范围
glVertex2f(x2, y2);
glEnd();
}
void drawTriangle(double x1, double y1, double x2, double y2, double x3, double y3) {
glBegin(GL_TRIANGLES);
glColor3f(1.0, 0.0, 0.0); // Red
glVertex3f(x1, y1, 0.0);
glColor3f(0.0, 1.0, 0.0); // Green
glVertex3f(x2, y2, 0.0);
glColor3f(0.0, 0.0, 1.0); // Blue
glVertex3f(x3, y3, 0.0);
glEnd();
}
// HomeWork
void DDALine(int x1, int y1, int x2, int y2) {
bool change = false;
bool x_change = false;
bool xy_change = false;
double kk = 1.0*(y2 - y1) / (x2 - x1);
if (kk > 1) {
change = true;
swap(x1, y1);
swap(x2, y2);
}
else if (kk < -1) {
xy_change = true;
x_change = true;
swap(x1, y1);
swap(x2, y2);
x1 = -1 * x1;
x2 = -1 * x2;
}
else if (kk < 0 && kk > -1) {
x_change = true;
y1 = -1 * y1; y2 = -1 * y2;
}
if (x2 - x1 < 0) {
swap(x1, x2);
swap(y1, y2);
}
double dx, dy, y, k;
dx = x2 - x1;
dy = y2 - y1;
k = dy / dx;
int x = x1;
y = y1;
for (; x <= x2; x++) {
if (!change)
if (x_change) {
if (xy_change) drawPoint(y, -1 * x);
else drawPoint(x, -1 * y);
}
else drawPoint(x, y);
else
drawPoint(y, x);
y += k;
}
}
void MidPointLine(int x1, int y1, int x2, int y2) {
bool change = false;
bool x_change = false;
bool xy_change = false;
double kk = 1.0*(y2 - y1) / (x2 - x1);
if (kk > 1) {
change = true;
swap(x1, y1);
swap(x2, y2);
}
else if (kk < -1) {
xy_change = true;
x_change = true;
swap(x1, y1);
swap(x2, y2);
x1 = -1 * x1;
x2 = -1 * x2;
}
else if (kk < 0 && kk > -1) {
x_change = true;
y1 = -1 * y1; y2 = -1 * y2;
}
if (x2 - x1 < 0) {
swap(x1, x2);
swap(y1, y2);
}
int a, b, c, x, y, d0, d1, d2, d;
a = y1 - y2;
b = x2 - x1;
c = x1 * y2 - x2 * y1;
d0 = 2 * a + b;
d1 = 2 * a;
d2 = 2 * (a + b);
d = d0;
x = x1; y = y1;
drawPoint(x, y);
while (x <= x2) {
if (d < 0) {
d += d2;
x++; y++;
}
else {
d += d1;
x++;
}
if (!change)
if (x_change) {
if (xy_change) drawPoint(y, -1 * x);
else drawPoint(x, -1 * y);
}
else drawPoint(x, y);
else
drawPoint(y, x);
}
}
void BresenHamline(int x1, int y1, int x2, int y2) {
bool change = false;
bool x_change = false;
bool xy_change = false;
double kk = 1.0*(y2 - y1) / (x2 - x1);
if (kk > 1) {
change = true;
swap(x1, y1);
swap(x2, y2);
}
else if (kk < -1) {
xy_change = true;
x_change = true;
swap(x1, y1);
swap(x2, y2);
x1 = -1 * x1;
x2 = -1 * x2;
}
else if (kk < 0 && kk > -1) {
x_change = true;
y1 = -1 * y1; y2 = -1 * y2;
}
if (x2 - x1 < 0) {
swap(x1, x2);
swap(y1, y2);
}
int x, y, dx, dy;
float k, e;
dx = x2 - x1;
dy = y2 - y1;
k = 1.0* dy / dx;
e = -0.5; x = x1; y = y1;
for (int i = 0; i <= dx; i++) {
if (!change)
if (x_change) {
if (xy_change) drawPoint(y, -1 * x);
else drawPoint(x, -1 * y);
}
else drawPoint(x, y);
else
drawPoint(y, x);
x = x + 1;
e = e + k;
if (e >= 0) {
y++;
e -= 1;
}
}
}
void IntegerBresenhamline(int x1, int y1, int x2, int y2) {
bool change = false;
bool x_change = false;
bool xy_change = false;
double kk = 1.0*(y2 - y1) / (x2 - x1);
if (kk > 1) {
change = true;
swap(x1, y1);
swap(x2, y2);
}
else if (kk < -1) {
xy_change = true;
x_change = true;
swap(x1, y1);
swap(x2, y2);
x1 = -1 * x1;
x2 = -1 * x2;
}
else if (kk < 0 && kk > -1) {
x_change = true;
y1 = -1 * y1; y2 = -1 * y2;
}
if (x2 - x1 < 0) {
swap(x1, x2);
swap(y1, y2);
}
int x, y, dx, dy, e;
dx = x2 - x1;
dy = y2 - y1;
e = -1 * dx;
x = x1; y = y1;
for (int i = 0; i <= dx; i++) {
if (!change)
if (x_change) {
if (xy_change) drawPoint(y, -1 * x);
else drawPoint(x, -1 * y);
}
else drawPoint(x, y);
else
drawPoint(y, x);
x++;
e = e + 2 * dy;
if (e >= 0) {
y++;
e -= 2 * dx;
}
}
}
void Drawlines(int x1, int y1, int x2, int y2) {
int x = x1, y = y1, dx = abs(x2 - x1), dy = abs(y2 - y1);
int s1 = 1, s2 = 1, e, flag = 0;
if (x1 >= x2) s1 = -1;
if (y1 >= y2) s2 = -1;
if (dy > dx) {
int change = dx;
dx = dy;
dy = change;
flag = 1;
}
e = -dx;
int DX = 2 * dx, DY = 2 * dy;
for (int i = 1; i <= dx; i++) {
drawPoint(x, y);
if (e >= 0) {
if (!flag) y += s2;
else x += s1;
e = e - DX;
}
if (!flag) x += s1;
else y += s2;
e = e + DY;
}
}
void Bresenham_Circle(int xc, int yc, int r) {
int x, y, d;
x = 0; y = r; d = 5 - 4 * r;
drawPoint(x + xc, y + yc);
while (x < y)
{
if (d < 0) d = d + 8 * x + 12;
else {
d = d + 8 * (x - y) + 20;
y--;
}
x++;
drawPoint(x + xc, y + yc); drawPoint(y + xc, x + yc);
drawPoint(y + xc, -x + yc); drawPoint(x + xc, -y + yc);
drawPoint(-x + xc, -y + yc); drawPoint(-y + xc, -x + yc);
drawPoint(-x + xc, y + yc); drawPoint(-y + xc, x + yc);
}
}
void draw() {
int i;
for (i = 0; i < ls.size(); ++i)
IntegerBresenhamline(ls[i][0], ls[i][1], ls[i][2], ls[i][3]);
for (i = 0; i < cs.size(); ++i)
Bresenham_Circle(cs[i][0], cs[i][1], cs[i][2]);
if (mouse_type == 1)
IntegerBresenhamline(old_x, old_y, new_x, new_y);
if (mouse_type == 3)
Bresenham_Circle(cx, cy, cr);
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3i(0, 0, 0);
draw();
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y) {
switch (key) {
case 27:
exit(0); break;
case 'a':
case 'A':
break;
default:
if (key <= 'z' && key >= 'a' || key <= 'Z' && key >= 'A' || key <= '9' && key >= '0') {
cout << char(key);
}
else {
cout << "\n字符码为 " << static_cast<int>(key);
display();
}
}
}
void mouseclick(int button, int state, int x, int y) {
cout << "(" << x << "," << y << ")";
switch (button) {
case GLUT_LEFT_BUTTON:
if (state == GLUT_DOWN) {
old_x = x;
old_y = 600 - y;
mouse_type = 1;
}
else if (state == GLUT_UP) {
list l;
l.push_back(old_x);
l.push_back(old_y);
l.push_back(x);
l.push_back(600 - y);
ls.push_back(l);
mouse_type = 0;
glutPostRedisplay();
for (int i = 0; i < ls.size(); ++i)
cout << endl << "line_" << i << ": " << ls[i][0] << "," << ls[i][1] << " " << ls[i]
[2] << "," << ls[i][3];
}
break;
case GLUT_MIDDLE_BUTTON:
break;
case GLUT_RIGHT_BUTTON:
if (state == GLUT_DOWN) {
cx = x;
cy = 600 - y; mouse_type = 3;
}
else if (state == GLUT_UP) {
list l;
l.push_back(cx);
l.push_back(cy);
cr = int(sqrt(double(x - cx)*(x - cx) + (600 - y - cy)*(600 - y - cy)) + 0.5);
l.push_back(cr);
cs.push_back(l);
mouse_type = 2;
glutPostRedisplay();
for (int i = 0; i < cs.size(); ++i)
cout << endl << "circle_" << i << ": " << cs[i][0] << "," << cs[i][1] << " " << cs[i][2];
}
break;
}
}
void screenmotion(int x, int y) {
if (mouse_type == 1) {
new_x = x;
new_y = 600 - y;
cout << endl << "new-line:" << old_x << "," << old_y << " " << new_x << "," << new_y << endl;
}
else if (mouse_type == 3) {
cr = int(sqrt(double(x - cx)*(x - cx) + (600 - y - cy)*(600 - y - cy)) + 0.5);
cout << endl << "new-circle: " << cx << "," << cy << " " << cr << endl;
}
glutPostRedisplay();
}
void init() {
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(-1.0, 600, 0.0, 601);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowPosition(100, 50);
glutInitWindowSize(600, 600);
glutCreateWindow("OpenGL");
init();
glutDisplayFunc(display);
glutMotionFunc(screenmotion);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouseclick);
glutMainLoop();
return 0;
}