在 OpenGL 中将视图更改为对象
Changing the view to object in OpenGL
我正在尝试使用 OpenGL,这是我的第一个代码。如何更改屏幕上绘制的 2 个对象的不同视图?
是否可以手动执行此操作,而不是使用函数 gluPerspective()
?
我尝试了 glRotatef(60, 0.0, 0.0, 5.0)
但没有任何反应。因为我想看到金字塔的其他面以及旋转球体的不同视图。
我还想为我在屏幕上绘制的不同对象设置不同的颜色,我该怎么做?
为每个对象设置颜色的代码,即 glColor3f
,我把它放在 glPushMatrix()
和 glPopMatrix()
之间,而且我总是包含行 glLoadIdentity()
在开始在屏幕上绘制对象之前。据我所知,这一行将重置以前对象的设置,并允许我为新对象设置新属性。
那为什么当我按下按钮 D
时,本该是白色的球体却是蓝色的?
这是我的完整代码:
#include <windows.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <math.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define X .525731112119133606
#define Z .850650808352039932
#define Y 0.0
#define PI 3.1415926535898
#define CIRCLE_STEP 5000
using namespace std;
// Open an OpenGL window
GLFWwindow* window;
int keyboard = 0, itr;
bool big_Sphere = true, sphereWithNormalV = false, animation = false;
GLdouble angle = 0;
/****Step 1: define vertices in (x, y, z) form****/
// Coordinates to draw a Icosahedron
GLfloat icoVertices[12][3] = {
{-X, Y, Z}, {X, Y, Z}, {-X, Y, -Z}, {X, Y, -Z},
{Y, Z, X}, {Y, Z, -X}, {Y, -Z, X}, {Y, -Z, -X},
{Z, X, Y}, {-Z, X, Y}, {Z, -X, Y}, {-Z, -X, Y}
};
// Coordinates to draw a Pyramid
GLfloat pyVertices[4][3] = {
{0.0f, 1.0f, 0.0f},
{1.0f, 0.0f, 0.0f},
{-1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, -1.0f}
};
static GLuint icoIndices[20][3] = {
{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
{8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };
static GLuint pyIndices[4][3] = {
{0,1,2}, {0,1,3}, {0,2,3}, {1,2,3}
};
/************************/
void normalize3f(float v[3]) {
GLfloat d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
if (d == 0.0) {
fprintf(stderr, "zero length vector");
return;
}
v[0] /= d; v[1] /= d; v[2] /= d;
}
void sphereNormalV(GLfloat p1[3], GLfloat p2[3], GLfloat p3[3])
{
glBegin(GL_LINES);
glVertex3f(p1[0] *1.5,p1[1] *1.5, p1[2] *1.5);
glVertex3fv(p1);
glEnd();
glBegin(GL_LINES);
glVertex3f(p2[0] *1.1,p2[1] *1.1, p2[2] *1.1);
glVertex3fv(p2);
glEnd();
glBegin(GL_LINES);
glVertex3f(p3[0] *1.1,p3[1] *1.1, p3[2] *1.1);
glVertex3fv(p3);
glEnd();
}
void drawtriangle(float *v1, float *v2, float *v3)
{
glBegin(GL_LINE_LOOP);
//glNormal3fv(v1);
glVertex3fv(v1);
//glNormal3fv(v2);
glVertex3fv(v2);
//glNormal3fv(v3);
glVertex3fv(v3);
glEnd();
}
void subdivide(GLfloat *v1, GLfloat *v2, GLfloat *v3, long depth)
{
GLfloat v12[3], v23[3], v31[3];
GLint i;
if (depth == 0){
drawtriangle(v1, v2, v3);
if (sphereWithNormalV == true){
sphereNormalV(v1, v2, v3);
}
return;
}
for (i = 0; i < 3; i++) {
v12[i] = v1[i]+v2[i];
v23[i] = v2[i]+v3[i];
v31[i] = v3[i]+v1[i];
}
normalize3f(v12);
normalize3f(v23);
normalize3f(v31);
subdivide(v1, v12, v31, depth-1);
subdivide(v2, v23, v12, depth-1);
subdivide(v3, v31, v23, depth-1);
subdivide(v12, v23, v31, depth-1);
}
void drawSphere(GLfloat x, GLfloat y, GLfloat z){
glLoadIdentity();
glPushMatrix();
if (big_Sphere == true){
glScaled(0.4, 0.55, 0.4);
}else{
glScaled(0.13, 0.18, 0.13);
}
if (animation){
glTranslatef(x, y, z);
}
glBegin(GL_LINE_LOOP);
for (int i = 0; i < 20; i++) {
subdivide(&icoVertices[icoIndices[i][0]][0], &icoVertices[icoIndices[i][1]][0], &icoVertices[icoIndices[i][2]][0], 3);
}
glEnd();
glPopMatrix();
}
void drawPyramid(){//(GLfloat x, GLfloat y, GLfloat z){
glLoadIdentity();
glPushMatrix();
glScaled(0.13, 0.18, 0.13);
glBegin(GL_LINE_LOOP);
for (int i = 0; i < 4; i++){
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3fv(pyVertices[pyIndices[i][0]]);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3fv(pyVertices[pyIndices[i][1]]);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3fv(pyVertices[pyIndices[i][2]]);
}
glEnd();
glPopMatrix();
}
int getKeyPressed(){
if (glfwGetKey(window, GLFW_KEY_A)){
keyboard = GLFW_KEY_A;
}
if (glfwGetKey(window, GLFW_KEY_B)){
keyboard = GLFW_KEY_B;
}
if (glfwGetKey(window, GLFW_KEY_C)){
keyboard = GLFW_KEY_A;
}
if (glfwGetKey(window, GLFW_KEY_D)){
keyboard = GLFW_KEY_D;
}
if (glfwGetKey(window, GLFW_KEY_E)){
keyboard = GLFW_KEY_E;
}
return keyboard;
}
void controlSphere(bool _big_Sphere, bool _sphereNormalV, bool _animation){
big_Sphere = _big_Sphere;
sphereWithNormalV = _sphereNormalV;
animation = _animation;
}
void gluPerspective(double fovy,double aspect, double zNear, double zFar)
{
// Start in projection mode.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double xmin, xmax, ymin, ymax;
ymax = zNear * tan(fovy * PI / 360.0);
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
int main( void ) {
if (!glfwInit()){
fprintf(stderr, "Failed to initialize GLFW.\n");
return -1;
}
// Create a windowed mode window and its OpenGL context
window = glfwCreateWindow(1100, 800, "Hello World", NULL, NULL);
if (window == NULL) {
fprintf(stderr, "glfw failed to create window.\n");
//glfwTerminate();
return -1;
}
// Make the window's context current
glfwMakeContextCurrent(window);
glewInit();
if (glewInit() != GLEW_OK){
fprintf(stderr, "Failed to initialize GLEW: %s.\n", glewGetErrorString(glewInit()));
return -1;
}
// 4x anti aliasing
glfwWindowHint(GLFW_SAMPLES, 4);
/**Step 3: Main loop for OpenGL draw the shape**
/* Main loop */
int i = 0;
GLfloat pos_X, pos_Y;
glRotatef(60, 0.0f, 0.3f, 0.4f);
do{
//glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
switch(getKeyPressed()){
case 65:
controlSphere(true, false, false);
drawSphere(0, 0, 0);
break;
case 66:
controlSphere(true, true, false);
drawSphere(0, 0, 0);
break;
case 67:
// drawPyramid();
break;
case 68:
// drawing a Sphere moving in a circular path
controlSphere(false, false, true);
angle = 2*PI*i/CIRCLE_STEP;
pos_X = cos(angle) * 4.5;
pos_Y = sin(angle) * 4.5;
drawSphere(pos_X, pos_Y, 0);
i += 1;
angle += 1;
if (angle >= 360){
angle = 0;
}
// drawing a Pyramid rotate around its y axis
drawPyramid();
break;
default:
controlSphere(true, false, false);
drawSphere(0, 0, 0);
break;
}
Sleep(1);
// Swap front and back rendering buffers
glfwSwapBuffers(window);
//Poll for and process events
glfwPollEvents();
} // check if the ESC key was pressed or the window was closed
while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0);
/***********************************************/
// Close window and terminate GLFW
glfwDestroyWindow(window);
glfwTerminate();
// Exit program
exit( EXIT_SUCCESS );
}
您正在寻找允许分割屏幕的多视口。在您的情况下,两个不同的视口两个不同的相机(每个相机一个)就足够了。
检查此 post。
Is there anyway to do this manually, in stead of using function gluPerspective()?
这个问题我不是很懂。但是如果你想设置具有不同变换、缩放、旋转 and/or 平移的多个对象(具有相同的参数),你需要将其推入堆栈,然后绘制所需的对象。可以在这里找到一个很好的起点:http://www.songho.ca/opengl/gl_transform.html
Also I want to set different colours to different objects that I draw on the screen, how can I do that?
您的球体是蓝色的,因为对 glColor3f()
的最后一次调用是在 drawPyramid()
。
您可以通过在绘制函数的开头调用 glColor3f (1.0f, 1.0f, 1.0f);
来更改球的颜色:
void drawSphere (GLfloat x, GLfloat y, GLfloat z)
{
glColor3f (1.0f, 1.0f, 1.0f);
...
}
从旧管道(您刚刚实现的)到新管道 (GLSL) 学习 OpenGL 的一个非常好的网站是 http://www.lighthouse3d.com/tutorials/。
我正在尝试使用 OpenGL,这是我的第一个代码。如何更改屏幕上绘制的 2 个对象的不同视图?
是否可以手动执行此操作,而不是使用函数 gluPerspective()
?
我尝试了 glRotatef(60, 0.0, 0.0, 5.0)
但没有任何反应。因为我想看到金字塔的其他面以及旋转球体的不同视图。
我还想为我在屏幕上绘制的不同对象设置不同的颜色,我该怎么做?
为每个对象设置颜色的代码,即 glColor3f
,我把它放在 glPushMatrix()
和 glPopMatrix()
之间,而且我总是包含行 glLoadIdentity()
在开始在屏幕上绘制对象之前。据我所知,这一行将重置以前对象的设置,并允许我为新对象设置新属性。
那为什么当我按下按钮 D
时,本该是白色的球体却是蓝色的?
这是我的完整代码:
#include <windows.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <math.h>
#include <GLFW/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#define X .525731112119133606
#define Z .850650808352039932
#define Y 0.0
#define PI 3.1415926535898
#define CIRCLE_STEP 5000
using namespace std;
// Open an OpenGL window
GLFWwindow* window;
int keyboard = 0, itr;
bool big_Sphere = true, sphereWithNormalV = false, animation = false;
GLdouble angle = 0;
/****Step 1: define vertices in (x, y, z) form****/
// Coordinates to draw a Icosahedron
GLfloat icoVertices[12][3] = {
{-X, Y, Z}, {X, Y, Z}, {-X, Y, -Z}, {X, Y, -Z},
{Y, Z, X}, {Y, Z, -X}, {Y, -Z, X}, {Y, -Z, -X},
{Z, X, Y}, {-Z, X, Y}, {Z, -X, Y}, {-Z, -X, Y}
};
// Coordinates to draw a Pyramid
GLfloat pyVertices[4][3] = {
{0.0f, 1.0f, 0.0f},
{1.0f, 0.0f, 0.0f},
{-1.0f, 0.0f, 0.0f},
{0.0f, 0.0f, -1.0f}
};
static GLuint icoIndices[20][3] = {
{0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
{8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
{7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
{6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };
static GLuint pyIndices[4][3] = {
{0,1,2}, {0,1,3}, {0,2,3}, {1,2,3}
};
/************************/
void normalize3f(float v[3]) {
GLfloat d = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
if (d == 0.0) {
fprintf(stderr, "zero length vector");
return;
}
v[0] /= d; v[1] /= d; v[2] /= d;
}
void sphereNormalV(GLfloat p1[3], GLfloat p2[3], GLfloat p3[3])
{
glBegin(GL_LINES);
glVertex3f(p1[0] *1.5,p1[1] *1.5, p1[2] *1.5);
glVertex3fv(p1);
glEnd();
glBegin(GL_LINES);
glVertex3f(p2[0] *1.1,p2[1] *1.1, p2[2] *1.1);
glVertex3fv(p2);
glEnd();
glBegin(GL_LINES);
glVertex3f(p3[0] *1.1,p3[1] *1.1, p3[2] *1.1);
glVertex3fv(p3);
glEnd();
}
void drawtriangle(float *v1, float *v2, float *v3)
{
glBegin(GL_LINE_LOOP);
//glNormal3fv(v1);
glVertex3fv(v1);
//glNormal3fv(v2);
glVertex3fv(v2);
//glNormal3fv(v3);
glVertex3fv(v3);
glEnd();
}
void subdivide(GLfloat *v1, GLfloat *v2, GLfloat *v3, long depth)
{
GLfloat v12[3], v23[3], v31[3];
GLint i;
if (depth == 0){
drawtriangle(v1, v2, v3);
if (sphereWithNormalV == true){
sphereNormalV(v1, v2, v3);
}
return;
}
for (i = 0; i < 3; i++) {
v12[i] = v1[i]+v2[i];
v23[i] = v2[i]+v3[i];
v31[i] = v3[i]+v1[i];
}
normalize3f(v12);
normalize3f(v23);
normalize3f(v31);
subdivide(v1, v12, v31, depth-1);
subdivide(v2, v23, v12, depth-1);
subdivide(v3, v31, v23, depth-1);
subdivide(v12, v23, v31, depth-1);
}
void drawSphere(GLfloat x, GLfloat y, GLfloat z){
glLoadIdentity();
glPushMatrix();
if (big_Sphere == true){
glScaled(0.4, 0.55, 0.4);
}else{
glScaled(0.13, 0.18, 0.13);
}
if (animation){
glTranslatef(x, y, z);
}
glBegin(GL_LINE_LOOP);
for (int i = 0; i < 20; i++) {
subdivide(&icoVertices[icoIndices[i][0]][0], &icoVertices[icoIndices[i][1]][0], &icoVertices[icoIndices[i][2]][0], 3);
}
glEnd();
glPopMatrix();
}
void drawPyramid(){//(GLfloat x, GLfloat y, GLfloat z){
glLoadIdentity();
glPushMatrix();
glScaled(0.13, 0.18, 0.13);
glBegin(GL_LINE_LOOP);
for (int i = 0; i < 4; i++){
glColor3f(1.0f, 0.0f, 0.0f);
glVertex3fv(pyVertices[pyIndices[i][0]]);
glColor3f(0.0f, 1.0f, 0.0f);
glVertex3fv(pyVertices[pyIndices[i][1]]);
glColor3f(0.0f, 0.0f, 1.0f);
glVertex3fv(pyVertices[pyIndices[i][2]]);
}
glEnd();
glPopMatrix();
}
int getKeyPressed(){
if (glfwGetKey(window, GLFW_KEY_A)){
keyboard = GLFW_KEY_A;
}
if (glfwGetKey(window, GLFW_KEY_B)){
keyboard = GLFW_KEY_B;
}
if (glfwGetKey(window, GLFW_KEY_C)){
keyboard = GLFW_KEY_A;
}
if (glfwGetKey(window, GLFW_KEY_D)){
keyboard = GLFW_KEY_D;
}
if (glfwGetKey(window, GLFW_KEY_E)){
keyboard = GLFW_KEY_E;
}
return keyboard;
}
void controlSphere(bool _big_Sphere, bool _sphereNormalV, bool _animation){
big_Sphere = _big_Sphere;
sphereWithNormalV = _sphereNormalV;
animation = _animation;
}
void gluPerspective(double fovy,double aspect, double zNear, double zFar)
{
// Start in projection mode.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
double xmin, xmax, ymin, ymax;
ymax = zNear * tan(fovy * PI / 360.0);
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
glFrustum(xmin, xmax, ymin, ymax, zNear, zFar);
}
int main( void ) {
if (!glfwInit()){
fprintf(stderr, "Failed to initialize GLFW.\n");
return -1;
}
// Create a windowed mode window and its OpenGL context
window = glfwCreateWindow(1100, 800, "Hello World", NULL, NULL);
if (window == NULL) {
fprintf(stderr, "glfw failed to create window.\n");
//glfwTerminate();
return -1;
}
// Make the window's context current
glfwMakeContextCurrent(window);
glewInit();
if (glewInit() != GLEW_OK){
fprintf(stderr, "Failed to initialize GLEW: %s.\n", glewGetErrorString(glewInit()));
return -1;
}
// 4x anti aliasing
glfwWindowHint(GLFW_SAMPLES, 4);
/**Step 3: Main loop for OpenGL draw the shape**
/* Main loop */
int i = 0;
GLfloat pos_X, pos_Y;
glRotatef(60, 0.0f, 0.3f, 0.4f);
do{
//glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT);
switch(getKeyPressed()){
case 65:
controlSphere(true, false, false);
drawSphere(0, 0, 0);
break;
case 66:
controlSphere(true, true, false);
drawSphere(0, 0, 0);
break;
case 67:
// drawPyramid();
break;
case 68:
// drawing a Sphere moving in a circular path
controlSphere(false, false, true);
angle = 2*PI*i/CIRCLE_STEP;
pos_X = cos(angle) * 4.5;
pos_Y = sin(angle) * 4.5;
drawSphere(pos_X, pos_Y, 0);
i += 1;
angle += 1;
if (angle >= 360){
angle = 0;
}
// drawing a Pyramid rotate around its y axis
drawPyramid();
break;
default:
controlSphere(true, false, false);
drawSphere(0, 0, 0);
break;
}
Sleep(1);
// Swap front and back rendering buffers
glfwSwapBuffers(window);
//Poll for and process events
glfwPollEvents();
} // check if the ESC key was pressed or the window was closed
while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && glfwWindowShouldClose(window) == 0);
/***********************************************/
// Close window and terminate GLFW
glfwDestroyWindow(window);
glfwTerminate();
// Exit program
exit( EXIT_SUCCESS );
}
您正在寻找允许分割屏幕的多视口。在您的情况下,两个不同的视口两个不同的相机(每个相机一个)就足够了。
检查此 post。
Is there anyway to do this manually, in stead of using function gluPerspective()?
这个问题我不是很懂。但是如果你想设置具有不同变换、缩放、旋转 and/or 平移的多个对象(具有相同的参数),你需要将其推入堆栈,然后绘制所需的对象。可以在这里找到一个很好的起点:http://www.songho.ca/opengl/gl_transform.html
Also I want to set different colours to different objects that I draw on the screen, how can I do that?
您的球体是蓝色的,因为对 glColor3f()
的最后一次调用是在 drawPyramid()
。
您可以通过在绘制函数的开头调用 glColor3f (1.0f, 1.0f, 1.0f);
来更改球的颜色:
void drawSphere (GLfloat x, GLfloat y, GLfloat z)
{
glColor3f (1.0f, 1.0f, 1.0f);
...
}
从旧管道(您刚刚实现的)到新管道 (GLSL) 学习 OpenGL 的一个非常好的网站是 http://www.lighthouse3d.com/tutorials/。