0

I am attempting to translate one circle independent of a separate, stationary circle, utilizing glTranslatef();. However, with my current, full code, each of my circles remains immobile. To investigate why this may be so, I have researched several answers, each comparable to those found here and here. Additionally, I read up on glLoadIdentity as well as the differences between GL_MODELVIEW and GL_PROJECTION, just to see if their details would offer any further clarification. I've also consulted the OpenGL API for the proper definitions of each of the above.

In the style of these solutions, I produced the following do...while loop:

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));

In this snippet, the drawCircle drawing remains stationary, but I would like for it to follow the written glTranslatef(0,1,0) instead. Is the stationary nature of the circle due to misplaced a glMatrixMode or glLoadIdentity, or perhaps due to the fact that they are being called within the do...while loop and the proper matrix is never really being utilized? I would appreciate any guidance you may have as to why the aforementioned and accepted answers are not functioning quite as well within my program.

For the sake of full transparency, here is the entirety of my code:

#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;
}
Community
  • 1
  • 1
zzz
  • 123
  • 1
  • 9

2 Answers2

1

The values for the vertex positions with which you draw your circles are in the order of hundreds (likely, because you want to address pixels as indicated by the values for the projection matrix). But glTranslates sees only a small number, so the shift is miniscule (one pixel) and hence you think nothing did happen. If you rewrite your code so that you don't specify the circle/target center by explicit modification of the vertex position offset it'd be clearer.

void drawCircle(float radius) 
{
    /* ... */
    for(int ii = 0; ii < num_segments; ii++) 
    { 
        glVertex2f(x, y); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    /* ... */
}

void drawTarget(float radius) 
{ 

    /* ... */
    for(int ii = 0; ii < num_segments; ii++) 
    { 
        glVertex2f(x, y); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    /* ... */
}

int main(void)
{
    /* ... */
            glPushMatrix();
            glTranslatef(1280*0.50, 720*0.25, 0);
            drawCircle(e[2]);
            glPopMatrix();

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

    /* ... */
}
datenwolf
  • 159,371
  • 13
  • 185
  • 298
  • Just tried this out now. It unfortunately still leaves the `drawCircle` immobile. What this code seems to have done is just shift the burden of placing the circle center offset onto the `glTranslatef`. With it, nothing has changed in appearance with no translation occurring. Should I add an additional `glTranslatef` to ensure for the actual, desired motion? – zzz May 20 '16 at 03:10
  • @zzz: "motion"? Uh, OpenGL just draws things. If you want things to actually move around you'll have to implement an animation loop. There's nothing in your code that could animate the drawing. – datenwolf May 20 '16 at 07:01
  • You are correct. My apologies. I misspoke and meant to ask about gltranslatef () over time, displaying motion, but that is perhaps a different question all together. – zzz May 20 '16 at 23:27
-1
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, fb_width, fb_height, 0, 0, 1);

You don't have to make the projection matrix at every loop, put it before the loop.

Then the error you have is surely due to :

glMatrixMode(GL_MODELVIEW);            
// it miss glLoadIdentity() here
glPushMatrix();
glTranslatef(0,1,0);
GLCraft
  • 144
  • 7
  • Setting the projection matrix at every frame iteration is good style and avoids problems down the road (e.g. when using FBOs for intermediate renderings). The problem is not where you think it is. – datenwolf May 19 '16 at 08:18
  • 1 is very small for a translate. Because right here, it's just a pixel. Did you try 50 or 100 in your gltranslate ? – GLCraft May 19 '16 at 08:26