#include "myopenglwidget.h"
#include <QOpenGLVersionFunctionsFactory>
#include "vertices.h"
#define timeOutmSec 50
QVector3D viewInitPos(0.0,5.0,25.0);
float _near=0.1f,_far=100.0f;
QMatrix4x4 model;
QMatrix4x4 view;
QMatrix4x4 projection;
QPoint lastPos;
MyOpenglWidget::MyOpenglWidget(QWidget *parent)
: QOpenGLWidget{parent}
{
connect(&m_timer,&QTimer::timeout,this,&MyOpenglWidget::on_timeOut);
m_timer.start(timeOutmSec);
m_time.start();
m_camera.Position = viewInitPos;
setFocusPolicy(Qt::StrongFocus);
setMouseTracking(true);
}
MyOpenglWidget::~MyOpenglWidget()
{
for(auto iter=m_Models.begin();iter!=m_Models.end();iter++)
{
ModelInfo *modelInfo=&iter.value();
delete modelInfo->model;
}
}
void MyOpenglWidget::loadModel(string path)
{
static int i = 0;
makeCurrent();
Model *_model = new Model(QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_3_3_Core>(QOpenGLContext::currentContext()),
path.c_str());
//m_camera.Position = getCameraInitPos(_model->m_minY,_model->m_maxY);
m_Models["张三"+QString::number(i++)]=
ModelInfo{_model,QVector3D(0,0,0),0.0,0.0,0.0,false,"张三"};
doneCurrent();
}
void MyOpenglWidget::initializeGL()
{
initializeOpenGLFunctions();
bool success;
m_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shaders/shaders/shapes.vert");
m_shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shaders/shaders/shapes.frag");
success=m_shaderProgram.link();
if(!success) qDebug()<<"ERR:"<<m_shaderProgram.log();
m_SingleColorShaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex,":/shaders/shaders/shapes.vert");
m_SingleColorShaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment,":/shaders/shaders/singleColor.frag");
success=m_SingleColorShaderProgram.link();
if(!success) qDebug()<<"ERR:"<<m_SingleColorShaderProgram.log();
m_BoxDiffuseTex=new
QOpenGLTexture(QImage(":/images/images/container2.png").mirrored());
m_PlaneDiffuseTex=new
QOpenGLTexture(QImage(":/images/images/wall.jpg").mirrored());
m_PlaneMesh = processMesh(planeVertices,6,m_PlaneDiffuseTex->textureId());
}
void MyOpenglWidget::resizeGL(int w, int h)
{
Q_UNUSED(w);
Q_UNUSED(h);
}
void MyOpenglWidget::paintGL()
{
model.setToIdentity();
view.setToIdentity();
projection.setToIdentity();
//float time=m_time.elapsed()/50.0;
projection.perspective(m_camera.Zoom,(float)width()/height(),_near,_far);
view=m_camera.GetViewMatrix();
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glStencilMask(0x00);
m_shaderProgram.bind();
//m_shaderProgram.setUniformValue("light.position",lightPos);
m_shaderProgram.setUniformValue("viewPos",m_camera.Position);
m_shaderProgram.setUniformValue("projection", projection);
m_shaderProgram.setUniformValue("view", view);
//model.rotate(1.0f, 1.0f, 1.0f, 0.5f);
m_shaderProgram.setUniformValue("model", model);
// light properties, note that all light colors are set at full intensity
m_shaderProgram.setUniformValue("light.ambient", 0.7f, 0.7f, 0.7f);
m_shaderProgram.setUniformValue("light.diffuse", 0.9f, 0.9f, 0.9f);
m_shaderProgram.setUniformValue("light.specular", 1.0f, 1.0f, 1.0f);
// material properties
m_shaderProgram.setUniformValue("material.shininess", 32.0f);
m_shaderProgram.setUniformValue("light.direction", -0.2f, -1.0f, -0.3f);
m_PlaneMesh->Draw(m_shaderProgram);
m_SingleColorShaderProgram.bind();
m_SingleColorShaderProgram.setUniformValue("projection", projection);
m_SingleColorShaderProgram.setUniformValue("view", view);
m_SingleColorShaderProgram.release();
foreach(auto modelInfo,m_Models)
{
//将需要渲染的片段的模板测试缓冲值设为1
glStencilFunc(GL_ALWAYS, 1, 0xFF);
glStencilMask(0xFF);
model.setToIdentity();
model.translate(modelInfo.worldPos);
model.rotate(modelInfo.pitch,QVector3D(1.0,0.0,0.0));
model.rotate(modelInfo.yaw,QVector3D(0.0,1.0,0.0));
model.rotate(modelInfo.roll,QVector3D(0.0,0.0,1.0));
m_shaderProgram.bind();
m_shaderProgram.setUniformValue("model", model);
modelInfo.model->Draw(m_shaderProgram);
m_shaderProgram.release();
if(!modelInfo.isSelected)
continue;
//第二次渲染渲染模板值不为1的地方
glStencilFunc(GL_NOTEQUAL, 1, 0xFF);
glStencilMask(0x00);
m_SingleColorShaderProgram.bind();
float height=modelInfo.model->m_maxY-modelInfo.model->m_minY;
float width=modelInfo.model->m_maxX-modelInfo.model->m_minX;
if(modelInfo.model->m_minY>=0)
model.translate(0.0f,height/2,0.0f);
model.scale(1.1f,1.0+0.1*(width/height));
if(modelInfo.model->m_minY>=0)
model.translate(0.0f,-height/2,0.0f);
m_SingleColorShaderProgram.setUniformValue("model", model);
modelInfo.model->Draw(m_SingleColorShaderProgram);
m_SingleColorShaderProgram.release();
glStencilMask(0xFF);
}
}
void MyOpenglWidget::on_timeOut()
{
update();
}
QVector3D MyOpenglWidget::getCameraInitPos(float min, float max)
{
QVector3D temp={0.0,0.0,0.0};
float height=max-min;
temp.setZ(1.5*height);
if(min>=0)
temp.setY(height/2.0);
viewInitPos=temp;
return temp;
}
Mesh *MyOpenglWidget::processMesh(float *vertices, int size, unsigned int textureId)
{
vector<Vertex> _vertices;
vector<unsigned int> _indices;
vector<Texture> _textures; //memcpy(&_vertices[0],vertices,5*size*sizeof(float));
for(int i=0;i<size;i++){
Vertex vert;
vert.Position[0]=vertices[i*5+0];
vert.Position[1]=vertices[i*5+1];
vert.Position[2]=vertices[i*5+2];
vert.TexCoords[0]=vertices[i*5+3];
vert.TexCoords[1]=vertices[i*5+4];
_vertices.push_back(vert); _indices.push_back(i);
}
Texture tex; tex.id=textureId;
tex.type="texture_diffuse";
_textures.push_back(tex);
return new Mesh(QOpenGLVersionFunctionsFactory::get<QOpenGLFunctions_3_3_Core>(QOpenGLContext::currentContext())
,_vertices,_indices,_textures);
}
QVector4D MyOpenglWidget::worldPostionFromViewPort(int posX, int posY)
{
float winZ;
glReadPixels(
posX,
this->height()-posY
,1,1
,GL_DEPTH_COMPONENT,GL_FLOAT
,&winZ);
float x=(2.0f*posX)/this->width()-1.0f;
float y=1.0f-(2.0f*posY)/this->height();
float z=winZ*2.0-1.0f;
float w = (2.0 * _near * _far) / (_far + _near - z * (_far - _near));
QVector4D wolrdPostion(x,y,z,1);
wolrdPostion=w*wolrdPostion;
return view.inverted()*projection.inverted()*wolrdPostion;
}
void MyOpenglWidget::mouseMoveEvent(QMouseEvent *event)
{
makeCurrent();
if(m_modelMoving){
for(QMap<QString, ModelInfo>::iterator iter=m_Models.begin();
iter!=m_Models.end();iter++){
ModelInfo *modelInfo=&iter.value();
if(!modelInfo->isSelected) continue;
modelInfo->worldPos=
QVector3D(worldPostionFromViewPort(event->pos().x(),event->pos().y()));
}
}else
{
if(event->buttons() & Qt::RightButton
|| event->buttons() & Qt::LeftButton
|| event->buttons() & Qt::MiddleButton){
auto currentPos=event->pos();
QPoint deltaPos=currentPos-lastPos;
lastPos=currentPos;
if(
没有合适的资源?快使用搜索试试~ 我知道了~
LearnOpenGL(十六)之模板测试
共26个文件
h:7个
cpp:5个
png:4个
需积分: 5 1 下载量 178 浏览量
2024-05-14
15:23:39
上传
评论
收藏 1.27MB RAR 举报
温馨提示
详细介绍:
资源推荐
资源详情
资源评论
收起资源包目录
14Stencil.rar (26个子文件)
14Stencil
Stencil
mainwindow.h 472B
model.h 1KB
mainwindow.cpp 1006B
camera.h 4KB
mesh.cpp 2KB
main.cpp 187B
shaders
light.frag 124B
singleColor.frag 101B
shapes.frag 1KB
shapes.vert 482B
light.vert 210B
Stencil.pro 1KB
mainwindow.ui 3KB
model.cpp 4KB
ui_mainwindow.h 4KB
mesh.h 836B
res.qrc 570B
images
matrix.jpg 291KB
container2_specular.png 141KB
wall.jpg 251KB
awesomeface.png 58KB
lighting_maps_specular_color.png 142KB
container2.png 457KB
vertices.h 511B
myopenglwidget.cpp 11KB
myopenglwidget.h 2KB
共 26 条
- 1
资源评论
码农客栈
- 粉丝: 1569
- 资源: 40
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功