所以这是我本应该做的一项任务,我目前关注的指导方针是:
用户可以通过单击选择“活动”视口(您应该更改颜色) 选择视口时的边框)。任何转换(轮换,翻译等)都应该是 仅在活动视口上执行。
用户应该能够使用WASD键和/或箭头在所选视口中导航场景 键(用于正投影)。鼠标控制(如在FPS游戏中)和WASD键和/或箭头 用于透视投影。只应在活动视口中允许导航。该 其他视口应保持静止。
我已经有了能够以fps方式转换透视视图的代码,并为前视图硬编码了一些相机转换,但我似乎无法弄清楚如何制作一个可以区分视口,如果我可以,我将能够只是插入代码转换为。我目前正在使用mouseclickcallback函数来检测鼠标的位置,但主要的问题是它在我的displaycallbackfunction之后运行,这是创建和运行视口的地方,这意味着我必须找到一种方法来实现它,所以我可以从显示功能转换而不是检测它的鼠标。
我的一些代码是:
void DisplayCallbackFunction(void)
{
/* clear the screen */
glViewport(0, 0, windowWidth, windowHeight);
glClearColor(0.2f, 0.2f, 0.2f, 0.8f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//create viewport
setViewport(1);
//Perspective
//glFrustum(-1.0f,1.0f, -1.0f, 1.0f, 1.0f, 100);
gluPerspective(45.0f,1.0f, 0.1f, 100.0f);
//Orthographic
//glOrtho(-1.0f, 1.0f, -1.0, 1.0, 1.0f, 100.0f);
//gluOrtho2D(1.0f, 1.0f, 1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/*
if (x < windowWidth / 2 && y < windowHeight / 2) {
viewport = 3;
std::cout << "Viewport =" << viewport << std::endl;
}
if (x > windowWidth / 2 && y < windowHeight / 2) {
viewport = 4;
std::cout << "Viewport =" << viewport << std::endl;
}
if (x > windowWidth / 2 && y > windowHeight / 2) {
viewport = 2;
std::cout << "Viewport =" << viewport << std::endl;
}
if (x < windowWidth / 2 && y > windowHeight / 2) {
viewport = 1;
std::cout << "Viewport =" << viewport << std::endl;
}
break;*/
gluLookAt(
cameraPosition.x, cameraPosition.y, cameraPosition.z,// camera position
cameraPosition.x + forwardVector.x,
cameraPosition.y + forwardVector.y,
cameraPosition.z + forwardVector.z,// what the camera is looking at
0.0f, 1.0f, 0.0f);//what the camera thinks is up
/* This is where we draw things */
//glColor3f(0.5f, 0.8f, 0.1f); //RGB or 4f-> RGBA
//drawObjects();
//cube code is here
//second viewport
setViewport(2);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(
rz, rz2, 6.0f,// camera position
rz, rz2, 0.0f,// what the camera is looking at
0.0f, 1.0f, 0.0f);//what the camera thinks is up
//other cube
//third viewport
setViewport(3);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(
-6.0f, 0.0f, 0.0f,// camera position
0.0f, 0.0f, 0.0f,// what the camera is looking at
0.0f, 1.0f, 0.0f);//what the camera thinks is up
//3rd cube
//fourth viewport
setViewport(4);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(
0.0f, 6.0f, 0.0f,// camera position
0.0f, 0.0f, 0.0f,// what the camera is looking at
0.0f, 0.0f, 1.0f);//what the camera thinks is up
//fourth cube
//HUD or Overlay viewport
glViewport(0, 0, windowWidth, windowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_QUADS);
glVertex3f(-0.02, -1.0, 0.0);// bottom left
glVertex3f(0.02, -1.0, 0.0); //bottom right
glVertex3f(0.02, 1.0, 0.0); // top right
glVertex3f(-0.02, 1.0, 0.0); // top left
glBegin(GL_QUADS);
glVertex3f(-1.0, -0.02, 0.0);// bottom left
glVertex3f(1.0, -0.02, 0.0); //bottom right
glVertex3f(1.0, 0.02, 0.0); // top right
glVertex3f(-1.0, 0.02, 0.0); // top left
glBegin(GL_QUADS);
glVertex3f(0.0, 0.0, 0.0);// bottom left
glVertex3f(0.02, 0.0, 0.0); //bottom right
glVertex3f(0.02, 1.0, 0.0); // top right
glVertex3f(0.0, 1.0, 0.0); // top left
glEnd();
/* Swap Buffers to Make it show up on screen */
glutSwapBuffers();
}
void KeyboardCallbackFunction(unsigned char key, int x, int y)
{
std::cout << "Key Down:" << (int)key << std::endl;
switch (key)
{
case 32: // the space bar
break;
case 27: // the escape key
//case 'q': // the 'q' key
exit(0);
break;
case 'W':
case 'w':
cameraPosition += (forwardVector * movementScalar);
break;
case 'S':
case 's':
cameraPosition -= (forwardVector * movementScalar);
break;
case 'A':
case 'a':
rightVector = glm::cross(forwardVector, glm::vec3(0.0f, 1.0f, 0.0f));
rightVector = glm::normalize(rightVector);
cameraPosition -= (rightVector * movementScalar);
break;
case 'D':
case 'd':
rightVector = glm::cross(forwardVector, glm::vec3(0.0f, 1.0f, 0.0f));
rightVector = glm::normalize(rightVector);
cameraPosition += (rightVector * movementScalar);
break;
}
}
void SpecialInput(int key, int x, int y)
{
switch (key)
{
case GLUT_KEY_LEFT:
rz += 1.0;
break;
case GLUT_KEY_RIGHT:
rz -= 1.0f;
break;
case GLUT_KEY_UP:
rz2 -= 1.0f;
break;
case GLUT_KEY_DOWN:
rz2 += 1.0f;
break;
}
glutPostRedisplay();
}
void MouseClickCallbackFunction(int button, int state, int x, int y)
{
// Handle mouse clicks
switch (button) {
if (state == GLUT_DOWN) {
case GLUT_RIGHT_BUTTON:
std::cout << "Mouse X: " << x << "Mouse Y: " << y << std::endl;
break;
case GLUT_LEFT_BUTTON:
std::cout << "Mouse X: " << x << "Mouse Y: " << y << std::endl;
if (x < windowWidth / 2 && y < windowHeight / 2) {
viewport = 3;
std::cout << "Viewport =" << viewport<<std::endl;
}
if (x > windowWidth / 2 && y < windowHeight / 2) {
viewport = 4;
std::cout << "Viewport ="<< viewport << std::endl;
}
if (x > windowWidth / 2 && y > windowHeight / 2) {
viewport = 2;
std::cout << "Viewport ="<< viewport << std::endl;
}
if (x < windowWidth / 2 && y > windowHeight / 2) {
viewport = 1;
std::cout << "Viewport ="<< viewport << std::endl;
}
break;
}
}
}
所以我可能已经搞砸了,因为这应该是午夜时分,老师并没有告诉我们足够的信息来正确地完成这个。如果有人能告诉我如何通过左键单击选择要转换的特定视口,我将不胜感激,然后通过箭头键转换相机。
答案 0 :(得分:0)
实际上你知道你需要做的一切。 OpenGL不会为您保存状态。相反,您负责记住状态并将其传输到您呈现的每个视口的OpenGL。所以定义:
struct ViewportState {
int vp[2], vs[2]; // position annd size of the viewport on screen
vec3 pos; // camera position in the world
vec3 rot; // euler angles of camera rotation
};
ViewportState viewports[number_of_viewports];
int active_viewport = 0;
编写一个函数来计算视口的视图矩阵:
mat4 ViewMatrix(const ViewportState &vp)
{
// build a view matrix m based on vp.pos and vp.rot
return m;
}
现在在渲染过程中使用这些:
void DisplayViewport(int i)
{
const ViewportState &vp = viewports[i];
glViewport(vp.vp[0], vp.vp[1], vp.vs[0], vp.vs[1]);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if(i == active_vieport)
{
// draw a highlighted border around viewport
}
// load ViewMatrix(vp)
// draw the actual 3d content of the viewport
}
void DisplayCallbackFunction(void)
{
// ...
for(int i = 0; i < nviewports; ++i)
DisplayViewport(i);
//...
}
键盘和鼠标将修改活动视口:
void KeyboardCallbackFunction(unsigned char key, int x, int y)
{
// ...
case 'w':
viewports[active_viewport].pos -= (ViewMatrix(viewports[active_viewport]) * vec4(0,0,movementScalar,1)).xyz;
break;
case 'a':
viewports[active_viewport].pos -= (ViewMatrix(viewports[active_viewport]) * vec4(movementScalar,0,0,1)).xyz;
break;
// ...
}
要激活其他视口:
void MouseClickCallbackFunction(int button, int state, int x, int y)
{
// iterate over viewports, find the one within x/y coordinates and set active_viewport accordingly
}
答案 1 :(得分:0)
您有2个选择。