一、异或操作
1.复制模式(GL_COPY)
1.1. 复制模式为Opengl默认的逻辑运算模式
2.1.画线的时候,如果采用复制模式,则是用当前状态机中的颜色像素替换窗口里相应位置的像素。比如:
glColor3f(1, 0, 0);
glBegin(GL_LINES);
glVertex2i(0, 0);
glVertex2i(0, 1);
glEnd();
这就会画一条从(0,0)到(0, 1)的直线,并且用红色替换这条像素上的颜色
2.异或运算模式(GL_XOR)
2.1.这种方式是用当前状态机中的颜色像素与窗口相应位置的像素做异或操作,而非替换
2.2.所以如果glColor3f(1, 0, 0),计算机中表现为11111111,00000000,00000000 ,背景窗口为RGB(0, 1, 0),计算机表现为
00000000,11111111,00000000则异或操作为 00000000,00000000,11111111, 为RGB(0, 0, 1),而不是红色
2.3要使用异或运算,首先要开启逻辑运算功能
glEnable(GL_COLOR_LOGIC_OP);<span style="white-space:pre"> </span>//千万别写成GL_LOGIC_OP
glLogicOp(GL_XOR); //变换到异或运算模式
二、橡皮条程序
#include <iostream>
#include <list>
#include "GL/glut.h"
#include "DataStruct.h"
using namespace std;
const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 600;
Point g_firstPoint; //鼠标左键点击后的第一个端点
Point g_lastMousePoint; //鼠标移动时的点
void init();
void drawLine(Point firstPoint, Point lastPoint);
/*回调函数*/
void reshape();
void display();
void mouse(int button, int state, int x, int y);
void move(int x, int y);
void drawLine(Point firstPoint, Point lastPoint)
{
glBegin(GL_LINES);
glVertex2i(firstPoint.x, firstPoint.y);
glVertex2i(lastPoint.x, lastPoint.y);
glEnd();
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glColor3f(1, 0, 0);
glEnable(GL_COLOR_LOGIC_OP);<span style="white-space:pre"> </span><span style="color:#ff0000;">//启用逻辑运算功能</span>
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
void reshape(int width, int height)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, width, 0, height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glViewport(0, 0, width, height);
}
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN)
{
g_firstPoint.x = x;
g_firstPoint.y = WINDOW_HEIGHT - y;
g_lastMousePoint.x = x;
g_lastMousePoint.y = WINDOW_HEIGHT - y;
glLogicOp(GL_XOR);<span style="white-space:pre"> </span><span style="color:#ff0000;">//启用XOR模式</span>
}
else if(button == GLUT_LEFT_BUTTON && state == GLUT_UP)
{
glLogicOp(GL_COPY);
drawLine(g_firstPoint, g_lastMousePoint);
glFlush();
}
}
void move(int x, int y)
{
//擦除上一条直线
drawLine(g_firstPoint, g_lastMousePoint);
//最新直线更新
Point newPoint;
newPoint.x = x;
newPoint.y = WINDOW_HEIGHT - y;
drawLine(g_firstPoint, newPoint);
glFlush();
g_lastMousePoint.x = x;
g_lastMousePoint.y = WINDOW_HEIGHT - y;
}
int main(int argc,char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(0, 0);
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
glutCreateWindow("Rubber");
init();
glutReshapeFunc(reshape);
glutDisplayFunc(display);
glutMouseFunc(mouse);
glutMotionFunc(move);
glutMainLoop();
}
|