如何正确地相互正确地翻译对象?

时间:2016-05-19 04:35:12

标签: opengl

我正在尝试使用glTranslatef();翻译一个独立于固定圆圈的圆圈。但是,使用我当前的完整代码,我的每个圈子都保持不动。为了研究为什么会这样,我已经研究了几个答案,每个答案都与herehere的答案相当。另外,我阅读了glLoadIdentity以及GL_MODELVIEW and GL_PROJECTION之间的差异,只是为了了解他们的详细信息是否会提供进一步的说明。我还咨询了OpenGL API,以获得上述每一个的正确定义。

根据这些解决方案的风格,我制作了以下do...while循环:

do{
    glClear(GL_COLOR_BUFFER_BIT);
    glDisable(GL_DEPTH_TEST);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, fb_width, fb_height, 0, 0, 1);
    glMatrixMode(GL_MODELVIEW);            

    glPushMatrix();
    glTranslatef(0,1,0);
    drawCircle(1280 * 0.50, 720 * 0.25,e[2]);
    glPopMatrix();

    glPushMatrix();
    glTranslatef(0,0,0);
    drawTarget(1280 * 0.50, 720 * 0.75,50);
    glPopMatrix();

    glfwSwapBuffers(w);
    glfwPollEvents();
  }
while (!glfwWindowShouldClose(w));

在此代码段中,drawCircle绘图保持不变,但我希望它能够遵循书面glTranslatef(0,1,0)。由于错误放置glMatrixModeglLoadIdentity,或者由于它们是在do...while循环内被调用而且正确的矩阵从未真正存在,因此圆的静止性质是不是利用?对于为什么上述和接受的答案在我的课程中不能正常运作,我将不胜感激。

为了完全透明,以下是我的全部代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <math.h>
#include <stddef.h>
#include <stdbool.h>

#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow *w;

int fb_width, fb_height;

static void error(int error, const char *desc)
{
        fputs(desc, stderr);
}

static void key_callback(GLFWwindow *w, int key, int scancode, int action, int mods)
{
        if ((key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) && action == GLFW_PRESS)
                glfwSetWindowShouldClose(w, GL_TRUE);
}

void drawCircle(float cx, float cy, float radius) 
{ 
    float num_segments = 360;
    float theta = 2 * 3.1415926 / num_segments; 
    float c = cosf(theta);//precalculate the sine and cosine
    float s = sinf(theta);
    float t;

    float x = radius;//we start at angle = 0 
    float y = 0; 

    glBegin(GL_TRIANGLE_FAN);
    glColor3f(1, 0, 1); 
    for(int ii = 0; ii < num_segments; ii++) 
    { 
        glVertex2f(x + cx, y + cy);//output vertex 

        //apply the rotation matrix
        t = x;
        x = c * x - s * y;
        y = s * t + c * y;
    } 
    glEnd();
}

void drawTarget(float cx, float cy, float radius) 
{ 
    float num_segments = 360;
    float theta = 2 * 3.1415926 / num_segments; 
    float c = cosf(theta);//precalculate the sine and cosine
    float s = sinf(theta);
    float t;

    float x = radius;//we start at angle = 0 
    float y = 0; 

    glBegin(GL_LINE_LOOP);
    glColor3f(1, 1, 1); 
    for(int ii = 0; ii < num_segments; ii++) 
    { 
        glVertex2f(x + cx, y + cy);//output vertex 

        //apply the rotation matrix
        t = x;
        x = c * x - s * y;
        y = s * t + c * y;
    } 
    glEnd(); 
}

int main(void)
{
        int i;
        float e[3] = {140,120,100};
        float m[3] = {90,80,70};
        float h[3] = {60,50,40};

        glfwSetErrorCallback(error);

        if (!glfwInit())
            exit(EXIT_FAILURE);

        w = glfwCreateWindow(1280, 720, "AxTest", NULL, NULL);
        if (!w)
        {
            glfwTerminate();
            return 1;
        }

        glfwMakeContextCurrent(w);

        glfwSetKeyCallback(w, key_callback);
        glfwGetFramebufferSize(w, &fb_width, &fb_height);

        do{
            glClear(GL_COLOR_BUFFER_BIT);
            glDisable(GL_DEPTH_TEST);
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            glOrtho(0, fb_width, fb_height, 0, 0, 1);
            glMatrixMode(GL_MODELVIEW);            

            glPushMatrix();
            glTranslatef(0,1,0);
            drawCircle(1280 * 0.50, 720 * 0.25,e[2]);
            glPopMatrix();

            glPushMatrix();
            glTranslatef(0,0,0);
            drawTarget(1280 * 0.50, 720 * 0.75,50);
            glPopMatrix();

            glfwSwapBuffers(w);
            glfwPollEvents();
          }
        while (!glfwWindowShouldClose(w));

        glfwDestroyWindow(w);

        glfwTerminate();
        exit(EXIT_SUCCESS);

        return 0;
}

2 个答案:

答案 0 :(得分:1)

用于绘制圆的顶点位置的值大约为数百(可能,因为您想要处理由投影矩阵的值指示的像素)。但glTranslates只看到一小部分,所以转变是微不足道的(一个像素),因此你认为没有发生任何事情。如果您重写代码以便不通过显式修改顶点位置偏移来指定圆/目标中心,那么它就会更清晰。

EnumerationExtension

答案 1 :(得分:-1)

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, fb_width, fb_height, 0, 0, 1);

您不必在每个循环中制作投影矩阵,将其放在循环之前。

然后你的错误肯定是由于:

glMatrixMode(GL_MODELVIEW);            
// it miss glLoadIdentity() here
glPushMatrix();
glTranslatef(0,1,0);