gpt4 book ai didi

c++ - Blade 的扭曲效果 (glRotatef) 不起作用

转载 作者:行者123 更新时间:2023-11-30 04:00:33 24 4
gpt4 key购买 nike

我正在尝试为 Blade 创建一个扭曲效果(不是旋转),但它根本不起作用。特别是,我正在尝试使用 glRotatef 函数来旋转轴并使其看起来像 Blade 在扭曲。

任何帮助都会很棒。

enter image description here

#include <GL/glut.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>

#define PI 3.14159265

static GLfloat lpos[] = { 0.0, 0.0, 4.0, 1.0 };
static GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
static GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
static GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };
static GLfloat yellow[] = { 1.0, 1.0, 0.0, 1.0 };
static float alpha = 0.0;
static float beta = PI / 6.0;
static float zoom = 10.0;
static bool lightSource = true;
float twistConstant = 0;
float rotateConstant = 0;
float numberOfObj = 3;
float numberOfTriangles = 1;
static GLdouble cpos[3];



void DrawTopTriangleSet(){
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glMaterialfv(GL_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, yellow);
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, yellow);
glBegin(GL_TRIANGLE_STRIP);

for (int i = 180; i >= 0; i = i - numberOfTriangles){
if (i > 90){
glPushMatrix();
glLoadIdentity();
glRotatef(i, 1, 0, 0);
glPopMatrix();
}
glNormal3f(0, sin(PI / 4 + twistConstant), cos(PI / 4 + twistConstant - PI / 4));
glVertex3f(i*PI / 180, 0, 0.5*sin(i*PI / 180));
glVertex3f(i*PI / 180, 0.5*sin(i*PI / 180), twistConstant*-sin(i*PI / 180));
}
glEnd();
}

void DrawBottomTriangleSet(){
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glMaterialfv(GL_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, yellow);
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, yellow);
glBegin(GL_TRIANGLE_STRIP);

for (int i = 180; i >= 0; i = i - numberOfTriangles){
if (i > 90){
glPushMatrix();
glLoadIdentity();
glRotatef(i, 1, 0, 0);
glPopMatrix();
}
glNormal3f(0, -sin(PI / 4 + twistConstant), cos(PI / 4 + twistConstant - PI / 4));
glVertex3f(i*PI / 180, -0.5*sin(i*PI / 180), twistConstant*sin(i*PI / 180));
glVertex3f(i*PI / 180, 0, 0.5*sin(i*PI / 180));
}

glEnd();
}

void DrawBackTriangleSet(){
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glMaterialfv(GL_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, yellow);
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, yellow);
glBegin(GL_TRIANGLE_STRIP);


for (int i = 180; i >= 0; i = i - numberOfTriangles){
if (i > 90){
glPushMatrix();
glLoadIdentity();
glRotatef(i, 1, 0, 0);
glPopMatrix();
}
glNormal3f(0, 5 * sin(PI - twistConstant), 5 * cos(PI - twistConstant));
glVertex3f(i*PI / 180, 0.5*sin(i*PI / 180), twistConstant*-sin(i*PI / 180));
glVertex3f(i*PI / 180, -0.5*sin(i*PI / 180), twistConstant*sin(i*PI / 180));
}
glEnd();

}

void DrawInsideTriangleSet(){
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glMaterialfv(GL_BACK, GL_EMISSION, black);
glBegin(GL_TRIANGLE_STRIP);

for (int i = 180; i >= 0; i = i - numberOfTriangles){
if (i > 90){
glPushMatrix();
glLoadIdentity();
glRotatef(i, 1, 0, 0);
glPopMatrix();
}
glVertex3f(i*PI / 180, 0.5*sin(i*PI / 180), twistConstant*-sin(i*PI / 180));
glVertex3f(i*PI / 180, 0, 0.5*sin(i*PI / 180));
glVertex3f(i*PI / 180, -0.5*sin(i*PI / 180), twistConstant*sin(i*PI / 180));
}

glEnd();
}

void writemessage()
{
printf(" X => x++ <= Move light source in direction of +X\n");
printf(" Y => y++ <= Move light source in direction of +Y\n");
printf(" Z => z++ <= Move light source in direction of +Z\n");
printf("\n");
printf("^X => x-- <= Move light source in direction of -X\n");
printf("^Y => y-- <= Move light source in direction of -Y\n");
printf("^Z => z-- <= Move light source in direction of -Z\n");
printf("\n");
printf(" ^ => Move camera up\n");
printf(" > => Move camera right\n");
printf(" < => Move camera left\n");
printf(" down arrow => Move camera down\n");
printf("\n");
printf(" t => More Twist\n");
printf(" f => Less Twist\n");
printf("\n");
printf(" q => More Propeller\n");
printf(" f => Less Propeller\n");
printf("\n");
printf(" w => More Triangles\n");
printf(" s => Less Triangles\n");
printf("\n");
printf(" 0 => Toggling light source\n");
printf("\n");
printf(" r => Rotates Propeller\n");
printf("\n");
printf(" You can not move the light source when the light source is off !!!");
}

void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (GLfloat)w / (GLfloat)h, 0.01, 20.0);
glMatrixMode(GL_MODELVIEW);
}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
cpos[0] = zoom * cos(beta) * sin(alpha);
cpos[1] = zoom * sin(beta);
cpos[2] = zoom * cos(beta) * cos(alpha);
gluLookAt(cpos[0], cpos[1], cpos[2], 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
if (lightSource == true){
glLightfv(GL_LIGHT0, GL_POSITION, lpos);
glMaterialfv(GL_FRONT, GL_EMISSION, white);
glPushMatrix();
glTranslatef(lpos[0], lpos[1], lpos[2]);
glutSolidSphere(0.1, 10, 8);
glPopMatrix();
glMaterialfv(GL_FRONT, GL_EMISSION, black);
}
glRotatef(rotateConstant, 0, 0, 1);


for (int i = 0; i < numberOfObj; i++){
glPushMatrix();
glRotatef(i * 360 / numberOfObj, 0, 0, 1);

DrawTopTriangleSet();
DrawBottomTriangleSet();
DrawBackTriangleSet();
DrawInsideTriangleSet();

glPopMatrix();
}


// Cone
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glMaterialfv(GL_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, red);
glPushMatrix();
glTranslated(0, 0, -1.5);
glutSolidCone(1, 2, 50, 50);
glPopMatrix();

// Back of Cone
glMaterialfv(GL_FRONT, GL_EMISSION, black);
glMaterialfv(GL_BACK, GL_EMISSION, black);
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
glMaterialfv(GL_BACK, GL_AMBIENT_AND_DIFFUSE, red);
glBegin(GL_POLYGON);
glNormal3f(0, 0, 1);
for (int i = 0; i <= 360; i++)
{
glVertex3f(cos(i*PI / 180) * 1, sin(i*PI / 180) * 1, -1.5);
}

glEnd();


glutSwapBuffers();
glFlush();
}


void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
case 'x':
if (lightSource == true)
lpos[0] = lpos[0] + 0.2;
glutPostRedisplay();
break;
case 'X':
if (lightSource == true)
lpos[0] = lpos[0] - 0.2;
glutPostRedisplay();
break;
case 'y':
if (lightSource == true)
lpos[1] = lpos[1] + 0.2;
glutPostRedisplay();
break;
case 'Y':
if (lightSource == true)
lpos[1] = lpos[1] - 0.2;
glutPostRedisplay();
break;
case 'z':
if (lightSource == true)
lpos[2] = lpos[2] + 0.2;
glutPostRedisplay();
break;
case 'Z':
if (lightSource == true)
lpos[2] = lpos[2] - 0.2;
glutPostRedisplay();
break;

case '+':
if (zoom != 1.5)zoom = zoom - 0.5;
glutPostRedisplay();
break;
case '-':
if (zoom != 15)zoom = zoom + 0.5;
glutPostRedisplay();
break;
case '0':
if (lightSource == true){
glDisable(GL_LIGHT0);
lightSource = false;
}
else{
glEnable(GL_LIGHT0);
lightSource = true;
}
glutPostRedisplay();
break;
case 't':
if (twistConstant <= PI/4){
twistConstant = twistConstant + 0.05;
glutPostRedisplay();
}
break;
case 'f':
if (twistConstant >= 0){
twistConstant = twistConstant - 0.05;
glutPostRedisplay();
}
break;
case 'r':
rotateConstant = rotateConstant + 2;
glutPostRedisplay();

break;
case 'q':
if (numberOfObj <= 6){
numberOfObj++;
glutPostRedisplay();
}

break;
case 'a':
if (numberOfObj >= 0){
numberOfObj--;
glutPostRedisplay();
}

break;
case 's':
if (numberOfTriangles <90){
numberOfTriangles++;
glutPostRedisplay();
}

break;
case 'w':
if (numberOfTriangles > 1){
numberOfTriangles--;
glutPostRedisplay();
}

break;
default:
break;
}
}


void specialkey(GLint key, int x, int y)
{
switch (key) {
case GLUT_KEY_RIGHT:
alpha = alpha + PI / 180;
if (alpha > 2 * PI) alpha = alpha - 2 * PI;
glutPostRedisplay();
break;
case GLUT_KEY_LEFT:
alpha = alpha - PI / 180;
if (alpha < 0) alpha = alpha + 2 * PI;
glutPostRedisplay();
break;
case GLUT_KEY_UP:
if (beta < 0.45*PI) beta = beta + PI / 180;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
if (beta > -0.05*PI) beta = beta - PI / 180;
glutPostRedisplay();
break;


default:
break;
}
}

int main(int argc, char** argv)
{
writemessage();
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1200, 800);
glutInitWindowPosition(0, 0);
glutCreateWindow(argv[0]);

glClearColor(0.0, 0.0, 0.0, 0.0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);

glEnable(GL_LIGHTING);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_LIGHT0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 5.0, 10.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0);

glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutSpecialFunc(specialkey);

glutMainLoop();
return 0;
}

最佳答案

glBegin()glEnd() 之间只有一组有限的 OpenGL 调用有效。修改当前转换的命令不在其中。有效调用的完整列表,复制自 glBegin() man page :

Only a subset of GL commands can be used between glBegin and glEnd. The commands are glVertex, glColor, glSecondaryColor, glIndex, glNormal, glFogCoord, glTexCoord, glMultiTexCoord, glVertexAttrib, glEvalCoord, glEvalPoint, glArrayElement, glMaterial, and glEdgeFlag. Also, it is acceptable to use glCallList or glCallLists to execute display lists that include only the preceding commands. If any other GL command is executed between glBegin and glEnd, the error flag is set and the command is ignored.

每当您的 OpenGL 调用无法按预期工作时,您应该尝试调用 glGetError() 以查看它是否标记了任何错误。在这种情况下,您会看到无效调用的 GL_INVALID_OPERATION 错误。

由于您无法更改图元中间的变换,因此最好在计算点时简单地将扭曲效果所需的旋转应用于点。假设您想要围绕 x 轴进行扭曲,并且您在没有扭曲的情况下计算了 xyz,那么您可以使用类似:

float twistAng = someFactor * x;
float twistCos = cos(twistAng);
float twistSin = sin(twistAng);
float yTwisted = twistCos * y - twistSin * z;
float zTwisted = twistSin * y + twistCos * z;

然后你使用 (x, yTwisted, zTwisted) 作为你的顶点。

关于c++ - Blade 的扭曲效果 (glRotatef) 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26269582/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com