环境:Windows、VS2012。
简介:一个用OpenGL实现的2D(所有点的Z坐标设为0.0f)随手画,刚开始学opengl的时候,只是按照教程写了一遍代码,对其理解还不是很深刻,本功能把各功能分开,让其看上去更像一个工程。这个随手画其实效率很低,实现的方法是画点,由n个点组成一条线,每个点我定义成一个正n边形(因为点小,近似圆)。
结构图如下:
效果(鼠标点击时画线,鼠标释放线消失):
关键代码在Line.h Point.h 源.cpp中:
//Line.h
#include
#include
#include
#include
#include
#include "Point.h"
using namespace std;
class Line{
public :
Line();
Line(GLfloat);
void add(Point,int);
int getLength();
void clear();
//void createBuffer(GLuint&,GLuint&);
void createBuffer();
void deleteBuffer();
GLuint getVAO();
private :
GLfloat radius;
vector clickPoint;
vector allPoint;
GLfloat num[999999];
GLuint VAO;
GLuint VBO;
int edges;
};
//设置每个点的大小(类似圆的半径),边的数量
Line::Line(GLfloat radius = 0.1f,int edges = 4){
this->radius = radius;
}
//添加新的点,每个点都是由n个正三角形组成的正n六边形
void Line::add(Point p){
clickPoint.push_back(p);
const GLfloat PI = 3.141592653;
Point pointTemp[16]={p};
for(int i=1;i<=edges;++i){
pointTemp[i].x = p.x + radius * cos(PI*(360/edges * i)/180.0);
pointTemp[i].y = p.y + radius * sin(PI*(360/edges * i)/180.0);
}
for(int i = 1;i <= edges - 1;++i){
allPoint.push_back(pointTemp[0].x);
allPoint.push_back(pointTemp[0].y);
allPoint.push_back(0.0f);
allPoint.push_back(pointTemp[i].x);
allPoint.push_back(pointTemp[i].y);
allPoint.push_back(0.0f);
allPoint.push_back(pointTemp[i+1].x);
allPoint.push_back(pointTemp[i+1].y);
allPoint.push_back(0.0f);
}
allPoint.push_back(pointTemp[0].x);
allPoint.push_back(pointTemp[0].y);
allPoint.push_back(0.0f);
allPoint.push_back(pointTemp[edges].x);
allPoint.push_back(pointTemp[edges].y);
allPoint.push_back(0.0f);
allPoint.push_back(pointTemp[1].x);
allPoint.push_back(pointTemp[1].y);
allPoint.push_back(0.0f);
for(int i=0;i
//Point.h
#ifndef __POINT_HH__
#define __POINT_HH__
struct Point{
GLfloat x,y;
Point() {};
Point(GLfloat x,GLfloat y) {
this->x=x;
this->y=y;
}
};
#endif
//Shader.h
#ifndef SHADER_H
#define SHADER_H
#include
#include
#include
#include
#include
class Shader{
public :
// 程序ID
GLuint Program;
// 构造器读取并构建着色器
Shader(const GLchar* vertexPath, const GLchar* fragmentPath){
//1.从文件路径中获取着色器
std::string vertexCode,fragmentCode;
std::ifstream vShaderFile,fShaderFile;
//保证ifstream异常能抛出
vShaderFile.exceptions(std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::badbit);
try{
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
//读取文件的缓冲内容到流中
std::stringstream vShaderStream,fShaderStream;
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
vShaderFile.close();
fShaderFile.close();
//转换为GLchar数组
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
}catch(std::ifstream::failure e){
std::cout<<"ERROR::SHADER::FILEW_NOT_SUCCESS_READ"<Program = glCreateProgram();
glAttachShader(this->Program,vertex);
glAttachShader(this->Program,fragment);
glLinkProgram(this->Program);
glGetShaderiv(this->Program,GL_LINK_STATUS,&success);
if(!success){
glGetShaderInfoLog(this->Program,512,NULL,infoLog);
std::cout<<"ERROR::SHADER_PROGRAM_LINKING_FAILED\n" << infoLog<Program);
}
};
#endif
//源.cpp
#include
// GLEW
#define GLEW_STATIC
#include
#include
#include
#include
#include
#include "Shader.h"
#include "Point.h"
#include "Line.h"
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
void mouse_callback(GLFWwindow *window,double xpos,double ypos);
void mouse_button_callback(GLFWwindow* window, int button, int action, int mods) ;
// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;
Line line(0.01f);
// The MAIN function, from here we start the application and run the game loop
int main()
{
GLfloat num;
std::cout<
//vertexShader.txt
#version 330 core
layout (location = 0) in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0f);
}
//fragmentShader.txt
#version 330 core
out vec4 color;
void main()
{
color = vec4(1.0f,0.5f,0.0f,1.0f);
}