OpenGL移动对象不起作用

Posted

技术标签:

【中文标题】OpenGL移动对象不起作用【英文标题】:OpenGL moving object doesn't work 【发布时间】:2016-06-09 08:01:10 【问题描述】:

我只想做水平移动的***。有一个代码,但它不起作用 - ***只是绕圈移动,留下痕迹。我试过glTranslatef(0.0f, moveY, 0.0f);,但它也不起作用。

#include "stdafx.h"
#include <math.h>
#include <GL/freeglut.h>
#include <GL\GL.h>

#define window_width  1080  
#define window_height 720 

GLfloat angle; // wheel's rotator
GLfloat moveX; // wheel's mover by X

void DrawCircle(float cx, float cy, float r, int num_segments) 
    glLoadIdentity();

    glTranslatef(0, 0, -10); // set place where wheel starts to draw

    glRotatef(angle, 0.0f, 0.0f, -0.1f); // rotate our wheel. it works correctly I think

    glTranslatef(moveX, 0.0f, 0.0f); // but it makes me wonder. moving circle by X doesn't work 

    // part of a circle
    glBegin(GL_TRIANGLE_FAN);
    glColor3f(255, 255, 255);
    for (int ii = 0; ii < num_segments; ii++) 
        double twicePi = 2.0 * 3.142;
        float theta = 2.0f * 3.1415926f * float(ii) / float(num_segments);
        float x = r * cosf(theta);
        float y = r * sinf(theta);
        glVertex2f(x + cx, y + cy);
    

    glEnd();

    // second part of a circle
    int i, x, y;
    double radius = 1.20;    

    glColor3ub(0.0, 0.0, 0.0);
    double twicePi = 2.0 * 3.142;
    x = 0, y = 0;
    glBegin(GL_TRIANGLE_FAN); 
    glVertex2f(x, y); 
    for (i = 0; i <= 20; i++) 
        glVertex2f(
            (x + (radius * cos(i * twicePi / 20))),
            (y + (radius * sin(i * twicePi / 20)))
        );
    
    glEnd();
    // there's an end of drawning of a circle

    // this is where wheel starts to rotate and move
    angle += 0.02f;
    moveX += 0.00005f;



    // there are spokes of a wheel
    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(0.0, -1.2f, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(0.0, 1.2f, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(1.2f, 0.0, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(-1.2f, 0.0, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(1.f, 1.f, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(-1.f, 1.f, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(1.f, -1.f, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(-1.f, -1.f, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(1.2f, 0.5f, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(-1.2f, -0.5f, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(-1.2f, -0.5f, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(-1.2f, 0.5f, 0.0);
    glEnd();

    glBegin(GL_LINES);
        glColor3f(255, 255, 255);
        glVertex3f(0.0, 0.0, 0.0);
        glVertex3f(1.2f, -0.5f, 0.0);
    glEnd();




void main_loop_function() 
    DrawCircle(0.0, 0.0, 1.45, 200);
    glutSwapBuffers();


void GL_Setup(int width, int height) 
    glViewport(0, 0, width, height);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(45, (float) width / height, 0.1, 100);
    glMatrixMode(GL_MODELVIEW);


int main(int argc, char** argv) 
    glutInit(&argc, argv);
    glutInitWindowSize(window_width, window_height);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
    glutCreateWindow("trata");
    glutIdleFunc(main_loop_function);
    GL_Setup(window_width, window_height);
    glutMainLoop();

【问题讨论】:

能否添加结果截图?什么不起作用?我认为您需要在 glTranslatef 之前调用 glRotatef。 @Unick 你太棒了! 【参考方案1】:

这只是使您的代码工作的快速修复,以便您可以进一步开发和调试它。我在您的代码中看到了一些关键问题:

(0) 将 POSIX 路径与 Windows 路径混合:

#include <GL/freeglut.h>
#include <GL\GL.h>

(1) 包括自定义标题并期望社区猜测它是关于什么的。我把它注释掉了。

//#include "stdafx.h" 

(2) 将 casts 误写为函数 - 应该是:

    float theta = 2.0f * 3.1415926f * (float)ii / (float)num_segments;

(3) 您的代码中没有glutDisplayFunc。您应该注册以下内容:

glutDisplayFunc(main_display_function);

在注册glutIdleFunc() 之前。然后,在您的代码中,您应该通过以下方式对其进行一些定义:

void main_display_function() 
    DrawCircle(0.0, 0.0, 1.45, 200);
    glutSwapBuffers();    

(4) 即使在该功能中,您也不会在重绘之前清除“窗口内容”:

void DrawCircle(float cx, float cy, float r, int num_segments) 
    glClearColor (0., 0., 0., 1);
    glClear (GL_COLOR_BUFFER_BIT);
    …   …   …  //the rest of your code

(5) 传递数据类型错误的颜色值:

    glColor3f(255, 255, 255);  //unsigned byte passed, float expected!

    glColor3ub(0.0, 0.0, 0.0); //float passed, unsigned byte expected!

还有几个问题可以直接解决您的问题 - 一旦您修复程序以使其正常工作(调用顺序),您将轻松了解并自己调试 glRotatef 和第二个 glTranslatef,正确计算 movex,绘制梁或辐条)。请也看看this SO post。

PS。您使用 C++ 编译器构建此程序不会使其成为 C++ 代码。您的程序中没有一行 C++ 特定代码。此外,OpenGL 和 GLUT 都是纯 C API。

【讨论】:

天啊glClear (GL_COLOR_BUFFER_BIT); 非常有用。又来了! 仍然有很多代码效率低下,例如在循环中划分常量:twicePi / 20,或者冗余:所有重复的glColor3f() 调用辐条,而实际上您只使用一种颜色为所有人... 对不起,我是 opengl 的新手。 twicePi /20 怎么了? 你将两个常数相除 20 次。就像您在循环外计算 twicePi 以防止乘以常数一样,您也可以在循环外定义 float rad = twicePi/20.(或任何数量的粉丝)。这与OpenGL无关。在每种计算机语言或 API 中都是一样的,因为它是 math

以上是关于OpenGL移动对象不起作用的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL相机扫射不起作用

OpenGL顶点缓冲区对象不起作用

多个 OpenGL 纹理在某些情况下不起作用?

在 OpenGL ES 1.1 中使用顶点缓冲区对象绘图不起作用

OpenGL - 对象在随机方向移动

为啥我的 OpenGL 纹理不起作用?