QT_OPENGL-------- 4.可编程管线绘制三角形
一、环境:qt下qmake编译
首先在qt .pro文件中添加glew和glfw的链接
LIBS+= -L/usr/lib64 -lGLEW
LIBS +=-L/usr/local/lib -lglfw3 -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lGL -lpthread -ldl
二、用可编程管线实现画三角形分为三步
1.创建vertexshader和fragramshader作为gpu program,
2.创建vertexdata上传数据到gpu
3.调用显卡程序渲染vertexdata,也就是画三角形
三、具体实现
main.cpp
#include<GL/glew.h>
#include <GLFW/glfw3.h>
#include<stdio.h>
#include<glm/glm.hpp>
#include<glm/ext.hpp> GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;
struct Vertex
{
float pos[];
float color[]; }; char *LoadFileContent(const char*path)
{
FILE*pFile = fopen(path, "rb");
if (pFile)
{
fseek(pFile, , SEEK_END);
int nLen = ftell(pFile);
char*buffer = new char[nLen+];
rewind(pFile);
fread(buffer, nLen, , pFile);
buffer[nLen]='\0';
fclose(pFile);
return buffer;
}
fclose(pFile);
return nullptr;
}
GLint CreateGPUProgram(const char*vsShaderPath,const char*fsShaderPath)
{
GLuint vsShader=glCreateShader(GL_VERTEX_SHADER);
GLuint fsShader=glCreateShader(GL_FRAGMENT_SHADER);
const char*vsCode=LoadFileContent(vsShaderPath);
const char*fsCode=LoadFileContent(fsShaderPath);
glShaderSource(vsShader,,&vsCode,nullptr);
glShaderSource(fsShader,,&fsCode,nullptr);
glCompileShader(vsShader);
glCompileShader(fsShader);
GLuint program=glCreateProgram();
glAttachShader(program,vsShader);
glAttachShader(program,fsShader);
glLinkProgram(program);
glDetachShader(program,vsShader);
glDetachShader(program,fsShader);
glDeleteShader(vsShader);
glDeleteShader(fsShader);
return program;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(, , width, height);
}
int main(void)
{
GLFWwindow* window; if (!glfwInit())
return -; window = glfwCreateWindow(, , "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
// 还需要注册这个函数,告诉GLFW我们希望每当窗口调整大小的时候调用这个函数。
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback); glewInit();//初始化glew可以使用高级opengl接口函数
GLuint program=CreateGPUProgram("/home/jun/OpenGL/FirstTriangle/sample.vs","/home/jun/OpenGL/FirstTriangle/sample.fs");
//在创建程序之后取得每一个变量的位置
GLint posLocation,colorLocation,MLocation,PLocation,VLocation;//分别代表sample.vs文件中pos,color,M,P,V的位置
//获取变量的值
posLocation=glGetAttribLocation(program,"pos");//第一个参数是你的程序是什么,第二个参数是要获取的sample.vs变量名
colorLocation=glGetAttribLocation(program,"color");
MLocation=glGetUniformLocation(program,"M");
PLocation=glGetUniformLocation(program,"P");
VLocation=glGetUniformLocation(program,"V");
//创建vertex data (顶点数据)
Vertex vertex[];
vertex[].pos[] = ;
vertex[].pos[] = ;
vertex[].pos[] = -100.0f;
vertex[].color[] = 1.0f;
vertex[].color[] = 1.0f;
vertex[].color[] = 1.0f;
vertex[].color[] = 1.0f; vertex[].pos[] = ;
vertex[].pos[] = ;
vertex[].pos[] = -100.0f;
vertex[].color[] = 1.0f;
vertex[].color[] = 1.0f;
vertex[].color[] = 1.0f;
vertex[].color[] = 1.0f; vertex[].pos[] = ;
vertex[].pos[] = ;
vertex[].pos[] = -100.0f;
vertex[].color[] = 1.0f;
vertex[].color[] = 1.0f;
vertex[].color[] = 1.0f;
vertex[].color[] = 1.0f; GLuint vbo;//vertex buffer
//object创建并绑定VBO对象
glGenBuffers(,&vbo);//需要声明一个vbo对象
glBindBuffer(GL_ARRAY_BUFFER,vbo);//设置为当前操作的对象
// 分配空间 传送数据
glBufferData(GL_ARRAY_BUFFER,sizeof(vertex)*,vertex,GL_STATIC_DRAW);//将内存中的数据传入显卡buffer数据包含三个顶点和4个color
// 解除绑定
glBindBuffer(GL_ARRAY_BUFFER,);
//创建一个单位矩阵
float identity[]=
{
,,,,
,,,,
,,,,
,,, };
//创建一个投影矩阵
glm::mat4 projection=glm::perspective(45.0f,800.0f/600.0f,0.1f,1000.0f); glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE); while (!glfwWindowShouldClose(window))
{
GLfloat currentFrame = (GLfloat)glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
glfwPollEvents(); glClearColor(1.0f, 0.04f, 0.14f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//调用显卡程序渲染数据
glUseProgram(program);//创建一个程序,调用渲染程序
// 在上面已经获取到了posLocation,colorLocation,MLocation,PLocation,VLocation在gpu中地址的值,这里就可以把定义的三角形的顶点的值付给地址了
glUniformMatrix4fv(MLocation,,GL_FALSE,identity);//第一个参数传地址,第二份是size,第三个是否转置,第四个参数是要传的数据,这里传单位矩阵
glUniformMatrix4fv(VLocation,,GL_FALSE,identity);//视图矩阵
glUniformMatrix4fv(PLocation,,GL_FALSE,glm::value_ptr(projection));//投影矩阵 //给pos 和color传值
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glEnableVertexAttribArray(posLocation);
//指定显卡中vbo数据分别对应的是sample中的pos和color
glVertexAttribPointer(posLocation,,GL_FLOAT,GL_FALSE,sizeof(Vertex),nullptr);//第一个参数传位置,第二个数量,第三变量类型,第四个是否归一化,第五个间隔多少,第六感是数据开始的地方
//color
glEnableVertexAttribArray(colorLocation);
glVertexAttribPointer(colorLocation,,GL_FLOAT,GL_FALSE,sizeof(Vertex),(const GLvoid*)(*sizeof(float)));
//画图
glDrawArrays(GL_TRIANGLES,,);//起始位置是0,画3个点
glBindBuffer(GL_ARRAY_BUFFER,); glUseProgram();//结束时重置
glfwSwapBuffers(window); } glfwTerminate();
return ;
}
sample.vs
attribute vec3 pos;
attribute vec4 color; uniform mat4 M;
uniform mat4 V;
uniform mat4 P; varying vec4 V_Color; void main()
{
V_Color=color;
gl_Position=P*V*M*vec4(pos,1.0);
}
sample.fs
varying vec4 V_Color; void main()
{
gl_FragColor=V_Color;
}
四、结果展示
QT_OPENGL-------- 4.可编程管线绘制三角形的更多相关文章
- WebGL编程指南案例解析之绘制三角形
//案例3.绘制三角形,将顶点数据存到缓冲区对象(gl.ARRAY_BUFFER)中,然后顶点着色器从里面读数据(3个顶点) //顶点着色器中去掉gl_PointSize = 10.0,绘制三角不能设 ...
- Linux OpenGL 实践篇-3 绘制三角形
本次实践是绘制两个三角形,重点理解顶点数组对象和OpenGL缓存的使用. 顶点数组对象 顶点数组对象负责管理一组顶点属性,顶点属性包括位置.法线.纹理坐标等. OpenGL缓存 OpenGL缓存实质上 ...
- opengl绘制三角形
顶点数组对象:Vertex Array Object,VAO 顶点缓冲对象:Vertex Buffer Object,VBO 索引缓冲对象:Element Buffer Object,EBO或Inde ...
- GPU的历史:从固定管线到可编程管线再到通用计算平台
开始的时候GPU不能编程,也叫固定管线的,就是把数据按照固定的通路走完. 和CPU同样作为计算处理器,顺理成章就出来了可编程的GPU,但是那时候想在GPU上编程可不是容易的事,你只能使用GPU汇编来写 ...
- iOS OpenGL ES简单绘制三角形
OpenGL 是用于2D/3D图形编程的一套基于C语言的统一接口. windows,Linux,Unix上均可兼容. OpenGL ES 是在OpenGL嵌入式设备上的版本, android/iOS ...
- SharpDX初学者教程第4部分:绘制三角形
原文 http://www.johanfalk.eu/blog/sharpdx-beginners-tutorial-part-4-drawing-a-triangle 现在我们有了一个Direct3 ...
- 从0开发3D引擎(九):实现最小的3D程序-“绘制三角形”
目录 上一篇博文 运行测试截图 需求分析 目标 特性 头脑风暴 确定需求 总体设计 具体实现 新建Engine3D项目 实现上下文 实现_init 实现"获得WebGL上下文" 实 ...
- 1.opengl绘制三角形
顶点数组对象:Vertex Array Object,VAO,用于存储顶点状态配置信息,每当界面刷新时,则通过VAO进行绘制. 顶点缓冲对象:Vertex Buffer Object,VBO,通过VB ...
- 纯CCS绘制三角形箭头图案
用CSS绘制三角形箭头.使用纯CSS,你只需要很少的代码就可以创作出各种浏览器都兼容的三角形箭头! CSS代码: /* create an arrow that points up */ div.ar ...
随机推荐
- js 中直接调用和new的区别
var test = new Test(); // 这里的 test 是什么? 是一个 Test 对象吗?错!这里 test 是一个函数——Test 中返回的 function() { return ...
- OpenCV2.4和OpenCV3之间函数的转变
OpenCV3里面没有自带opencv-contrib,需要自己手动安装,也很简单,直接在命令行里面打:pip install opencv-contrib-python 就能安装好了 OpenCV3 ...
- LA3905 Meteor
https://vjudge.net/problem/UVALive-3905 计算出每个点在相框中的时间段,扫描线做即可 关键在如何快速计算每个点在相框中的时间段.对每个点进行运动分解,进入的时间L ...
- php获取数据转换成json格式
<?php header("content-type:text/html;charset=utf-8"); $con=mysql_connect("localhos ...
- springmvc 支持对象与json 自动转换的配置
基于maven的工程, 需要在pom.xml中添加如下依赖 <dependency> <groupId>javax.servlet</groupId> <ar ...
- springmvc jsp向controller传参,一直为null
怎么检查都无解 重启电脑好了
- linux学习 网络系统&文件查找
被用来配置和操作网络系统的命令数目非常巨大,这里仅仅介绍一些经常会使用的 这一章会介绍ssh远程登录程序哦 ping 命令(掠过) traceroute 会显示主机到指定的主机要经过的跳数的网络流量列 ...
- java-Map-system
一 概述 0--星期日1--星期一... 有对应关系,对应关系的一方是有序的数字,可以将数字作为角标. public String getWeek(int num){ if(num<0 || n ...
- Linux监听的网络服务$ netstat -ntlp$ netstat -nulp$ netstat -nxlp
我一般都分开运行这三个命令,不想一下子看到列出一大堆所有的服务.netstat -nalp倒也可以.不过我绝不会用 numeric 选项 (鄙人一点浅薄的看法:IP 地址看起来更方便). 找到所有正在 ...
- 【模板】倍增LCA [2017年5月计划 清北学堂51精英班 Day3]
P3379 [模板]最近公共祖先(LCA) 题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询 ...