-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathxopenglwidget.cpp
199 lines (153 loc) · 5.56 KB
/
xopenglwidget.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include "xopenglwidget.h"
#include <QPalette>
#include "model.h"
#include "light.h"
#include "resourcemanager.h"
const QVector3D CAMERA_POSITION(0.0f, 0.0f, 3.0f);
const QVector3D LIGHT_POSITION(0.0f, 3.0f, 3.0f);
const int XOpenGLWidget_WIDTH = 815;
const int XOpenGLWidget_HEIGHT = 500;
Light *light;
Model *objModel;
SkyBox *skyBox;
XOpenGLWidget::XOpenGLWidget(QWidget *parent) : QOpenGLWidget(parent){
this->setGeometry(20,40, XOpenGLWidget_WIDTH, XOpenGLWidget_HEIGHT);
}
XOpenGLWidget::~XOpenGLWidget(){
if(camera)
delete camera;
}
void XOpenGLWidget::handleKeyPressEvent(QKeyEvent *event){
GLuint key = event->key();
if(key >= 0 && key <= 1024)
this->keys[key] = GL_TRUE;
}
void XOpenGLWidget::handleKeyReleaseEvent(QKeyEvent *event){
GLuint key = event->key();
if(key >= 0 && key <= 1024)
this->keys[key] = GL_FALSE;
}
void XOpenGLWidget::changeObjModel(QString fileName){
objModel->init(fileName);
}
void XOpenGLWidget::initializeGL(){
/*********** OGL核心 ***********/
core = QOpenGLContext::currentContext()->versionFunctions<QOpenGLFunctions_3_3_Core>();
core->glEnable(GL_DEPTH_TEST);
/*********** 初始化模型细节参数 *************/
isOpenLighting = GL_TRUE;
isLineMode = GL_FALSE;
modelScaling = 0.001f;
/*********** 键鼠响应及时间帧数操作 *************/
for(GLuint i = 0; i != 1024; ++i) //初始化键盘按键
keys[i] = GL_FALSE;
deltaTime = 0.0f;
lastFrame = 0.0f;
isFirstMouse = GL_TRUE;
isLeftMousePress = GL_FALSE;
lastX = width() / 2.0f;
lastY = height() / 2.0f;
time.start();
/************ 摄像机 ***********/
camera = new Camera(CAMERA_POSITION);
/*********** 灯 *************/
light = new Light();
light->init();
/************ obj模型 ***********/
objModel = new Model();
objModel->init(":/res/Model/huapen/penzi.obj");
/************ 载入shader ***********/
ResourceManager::loadShader("model", ":/res/shader/model.vert", ":/res/shader/model.frag");
ResourceManager::loadShader("light", ":/res/shader/light.vert", ":/res/shader/light.frag");
ResourceManager::getShader("model").use().setInteger("material.ambientMap", 0);
ResourceManager::getShader("model").use().setInteger("material.diffuseMap", 1);
ResourceManager::getShader("model").use().setVector3f("light.position", LIGHT_POSITION);
QMatrix4x4 model;
model.translate(LIGHT_POSITION);
model.scale(0.1f);
ResourceManager::getShader("light").use().setMatrix4f("model", model);
/************ 天空盒 ***********/
skyBox = new SkyBox();
/************ 背景颜色参数调控 ***********/
core->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
core->glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
}
void XOpenGLWidget::resizeGL(int w, int h){
core->glViewport(0, 0, w, h);
}
void XOpenGLWidget::paintGL(){
/*********** 计算两次帧数之间的时间间隔 ***************/
GLfloat currentFrame = (GLfloat)time.elapsed()/100;
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
this->processInput(deltaTime);
this->updateGL();
/********* 绘制灯 ************/
ResourceManager::getShader("light").use();
light->drawLight();
/********* 绘制花盆 ************/
ResourceManager::getShader("model").use();
objModel->draw(this->isOpenLighting);
}
void XOpenGLWidget::processInput(GLfloat dt){
if (keys[Qt::Key_W])
camera->processKeyboard(FORWARD, dt);
if (keys[Qt::Key_S])
camera->processKeyboard(BACKWARD, dt);
if (keys[Qt::Key_A])
camera->processKeyboard(LEFT, dt);
if (keys[Qt::Key_D])
camera->processKeyboard(RIGHT, dt);
if (keys[Qt::Key_E])
camera->processKeyboard(UP, dt);
if (keys[Qt::Key_Q])
camera->processKeyboard(DOWN, dt);
}
void XOpenGLWidget::updateGL(){
if(this->isLineMode)
core->glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
core->glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
QMatrix4x4 projection, view;
projection.perspective(camera->zoom, (GLfloat)width()/(GLfloat)height(), 0.1f, 200.f);
view = camera->getViewMatrix();
ResourceManager::getShader("light").use().setMatrix4f("projection", projection);
ResourceManager::getShader("light").use().setMatrix4f("view", camera->getViewMatrix());
ResourceManager::getShader("model").use().setMatrix4f("projection", projection);
ResourceManager::getShader("model").use().setMatrix4f("view", camera->getViewMatrix());
ResourceManager::getShader("model").use().setVector3f("viewPos", camera->position);
skyBox->render(view, projection);
QMatrix4x4 scaling;
scaling.scale(modelScaling);
ResourceManager::getShader("model").use().setMatrix4f("model", scaling);
}
void XOpenGLWidget::mouseMoveEvent(QMouseEvent *event){
GLint xpos = event->pos().x();
GLint ypos = event->pos().y();
if(isLeftMousePress){
if (isFirstMouse){
lastX = xpos;
lastY = ypos;
isFirstMouse = GL_FALSE;
}
GLint xoffset = xpos - lastX;
GLint yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
lastX = xpos;
lastY = ypos;
camera->processMouseMovement(xoffset, yoffset);
}
}
void XOpenGLWidget::mousePressEvent(QMouseEvent *event){
if(event->button() == Qt::LeftButton)//注意是button()不是buttons();
isLeftMousePress = GL_TRUE;
}
void XOpenGLWidget::mouseReleaseEvent(QMouseEvent *event){
if(event->button() == Qt::LeftButton){ //注意是button()不是buttons();
isLeftMousePress = GL_FALSE;
isFirstMouse = GL_TRUE;
}
}
void XOpenGLWidget::wheelEvent(QWheelEvent *event){
QPoint offset = event->angleDelta();
camera->processMouseScroll(offset.y()/20.0f);
}