How can I rotate triangle in OpenGL?

Gippeumi

I want to rotate my triangle in OpenGL, and running program on Raspberry Pi.

I can draw triangle and move it. But I have no idea to rotate it.. Nothing rotates.

#include <cstdio>
#include <ctime>
#include <cmath>
#include <string>

#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <GLES/gl.h>

#include <bcm_host.h>

EGLDisplay Disp;
EGLSurface Surface;
EGLContext Context;

int ScrWidth, ScrHeight;

float MVPMatrix[16];
float ProjectionMatrix[16];
float ViewMatrix[16];

using namespace std;

class Shader
{
    private:
    string VertexShaderFile;
    string FragmentShaderFile;
    GLuint Load(GLenum type, string FileName)
    {
        (Compile shader)
    }

    GLuint Program;
    bool Linked;
    public:
    Shader(string FileNameV, string FileNameF)
    {
        Linked = false;
        VertexShaderFile = FileNameV;
        FragmentShaderFile = FileNameF;
    }
    bool Load()
    {
        (Link vertex/fragment shader)
    }

    void Use()
    {
        glUseProgram(Program);
    }

    int GetAttrLoc(const char *Name)
    {
        glGetAttribLocation(Program, Name);
    }

    int GetUniformLoc(const char *Name)
    {
        return glGetUniformLocation(Program, Name);
    }

    ~Shader()
    {
        if(Linked)
        {
            Linked = false;
            glDeleteProgram(Program);
        }
    }
};

class Triangle
{
    private:
    const int COORDS_PER_VERTEX = 3;
    const int vertexCount = 9 / COORDS_PER_VERTEX;  //9: Length of triangleCoords
    const int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
    static float TriangleCoords [];
    float Color[4];
    float XOff;
    float YOff;
    float ZOff;
    Shader *S;
    public:

    Triangle()
    {
        XOff = YOff = ZOff = 0;
        S = new Shader("Shaders/test.vsh", "Shaders/test.fsh");
        if (!S->Load())
        {
            delete S;
            S = NULL;
        }
    }

    void SetColor(int R, int G, int B, int A)
    {
        Color[0] = R / 255.0;
        Color[1] = G / 255.0;
        Color[2] = B / 255.0;
        Color[3] = A / 255.0;
    }

    void SetXYZ(int X, int Y, int Z)
    {
        (Sets position)
    }

    bool Draw()
    {
        float TriangleCoords[] = {   // in counterclockwise order:
            -0.0 + XOff, 0.622008459 + YOff, 0.0 + ZOff, // top
            -0.5 + XOff, -0.311004243 + YOff, 0.0 + ZOff, // bottom left
            0.5 + XOff, -0.311004243 + YOff, 0.0 + ZOff  // bottom right
        };
        printf("%f\n", TriangleCoords[1]);

        //glMatrixMode(GL_PROJECTION);
        if (S == NULL)
            return false;
        S->Use();
        // Load the vertex data
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, TriangleCoords);
        // get handle to shape's transformation matrix
        // Pass the projection and view transformation to the shader
        //UniformMatrix4fv(S->GetUniformLoc("uMVPMatrix"), 1, false, MVPMatrix);
        glUniform4fv(S->GetUniformLoc("vColor"), 1, Color);
        glEnableVertexAttribArray(0);
        //glPushMatrix();
        glLoadIdentity();
        glMatrixMode(GL_MODELVIEW);
        float X = LocalTime->tm_hour / 23.0;
        float Y = LocalTime->tm_min / 59.0;
        float Z = LocalTime->tm_sec / 59.0;
        glTranslatef(0, 0, 1);
        glRotatef(60, 1.f, 0.f, 0.f);
        glRotatef(30, 0.f, 1.f, 0.f);
        glRotatef(30, 0.f, 0.f, 1.f);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        //glPopMatrix();
        return true;
    }
};

bool InitDisplay()
{
    bcm_host_init();
    Disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
    if(eglInitialize(Disp, NULL, NULL) != EGL_TRUE)
    {
        printf("Display initialize error.\n");
        return false;
    }
    printf("Display initialized.\n");


    static const EGLint AttrList[] =
    {
        EGL_RED_SIZE, 8,
        EGL_GREEN_SIZE, 8,
        EGL_BLUE_SIZE, 8,
        EGL_ALPHA_SIZE, 8,
        EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
        EGL_NONE
    };
    EGLConfig Config;
    int ConfigCount;
    if(eglChooseConfig(Disp, AttrList, &Config, 1, &ConfigCount) != EGL_TRUE)
    {
        printf("Display choose config error.\n");
        return false;
    }
    printf("Display config chosen. %d configs.\n", ConfigCount);


    //if(eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE)
    //{
    //  printf("Bind API error.\n");
    //  return false;
    //}
    //printf("API bound.\n");


    static const EGLint ContextAttr[] =
    {
        EGL_CONTEXT_CLIENT_VERSION, 2,
        EGL_NONE
    };

    if((Context = eglCreateContext(Disp, Config, EGL_NO_CONTEXT, ContextAttr)) == EGL_NO_CONTEXT)
    {
        printf("Create context error.\n");
        return false;
    }
    printf("Context created.\n");



    if(graphics_get_display_size(0 /* LCD */, &ScrWidth, &ScrHeight) < 0)
    {
        printf("Get screen size error.\n");
        return false;
    }
    printf("Got screen size. %dx%d\n", ScrWidth, ScrHeight);


    DISPMANX_DISPLAY_HANDLE_T DispmanDisp;
    DispmanDisp = vc_dispmanx_display_open(0 /* LCD */);
    printf("Dispmanx - Display opened.\n");


    DISPMANX_UPDATE_HANDLE_T DispmanUpdate;
    DispmanUpdate = vc_dispmanx_update_start(0);
    printf("Dispmanx - Update started.\n");


    DISPMANX_ELEMENT_HANDLE_T DispmanElement;   
    VC_RECT_T DestRect;
    VC_RECT_T SrcRect;
    DestRect.x = 0;
    DestRect.y = 0;
    DestRect.width = ScrWidth;
    DestRect.height = ScrHeight;
    SrcRect.x = 0;
    SrcRect.y = 0;
    SrcRect.width = ScrWidth << 16;
    SrcRect.height = ScrHeight << 16;   
    DispmanElement= vc_dispmanx_element_add(
                DispmanUpdate,
                DispmanDisp,
                0/*layer*/,
                &DestRect,
                0/*src*/,
                &SrcRect,
                DISPMANX_PROTECTION_NONE, 
                0 /*alpha*/,
                0/*clamp*/,
                0/*transform*/
                );
    printf("Dispmanx - Element added.\n");

    static EGL_DISPMANX_WINDOW_T NativeWindow;
    NativeWindow.element = DispmanElement;
    NativeWindow.width = ScrWidth;
    NativeWindow.height = ScrHeight;
    vc_dispmanx_update_submit_sync(DispmanUpdate);
    printf("Dispmanx - Sync submited.\n");

    if((Surface = eglCreateWindowSurface(Disp, Config, &NativeWindow, NULL)) == EGL_NO_SURFACE)
    {
        printf("Create surface error.\n");
        return false;
    }
    printf("Surface created\n");

    if(eglMakeCurrent(Disp, Surface, Surface, Context) != EGL_TRUE)
    {
        printf("Make onnection between context and surface error.\n");
        return false;
    }
    printf("Connection made between context and surface.\n");

    glEnable(GL_CULL_FACE);
    glMatrixMode(GL_MODELVIEW);
    printf("Graphics system ready.\n");
    return true;
}

void makeFrustum(float fovY, float aspectRatio, float front, float back)
{
    const float DEG2RAD = 3.14159265 / 180;

    float tangent = tan(fovY / 2 * DEG2RAD);   // tangent of half fovY
    float height = front * tangent;          // half height of near plane
    float width = height * aspectRatio;      // half width of near plane

    // params: left, right, bottom, top, near, far
    glFrustumf(-width, width, -height, height, front, back);
}

void DrawLoop()
{
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    glViewport(0, 0, ScrWidth, ScrHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    makeFrustum(45.0, ScrWidth / (float)ScrHeight, 1, 500);
    glEnableClientState(GL_VERTEX_ARRAY);
    Triangle T1;
    Triangle T2;
    Triangle T3;
    Triangle T4;

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0.f, 0.f, -50.f);

    while (1)
    {
        time_t Time;
        time(&Time);
        tm *LocalTime = localtime(&Time);

        printf("%d:%d:%d\n", LocalTime->tm_hour, LocalTime->tm_min, LocalTime->tm_sec);
        float R = LocalTime->tm_hour / 23.0;
        float G = LocalTime->tm_min / 59.0;
        float B = LocalTime->tm_sec / 59.0;

        T1.SetColor(255, 0, 0, 255);
        T1.SetXYZ(B * ScrWidth, B * ScrHeight, 0);

        //glClearColor(0, 0, 0, 1.0);
        //glClear(GL_COLOR_BUFFER_BIT);
        if (!T1.Draw() || !T2.Draw() || !T3.Draw() || !T4.Draw())
        {
            return;
        }

        glFlush();
        eglSwapBuffers(Disp, Surface);
    }
}

int main()
{
    if(!InitDisplay())
    {
        printf("Display initialize error.\n");
        return false;
    }
    DrawLoop();
    return 0;
}

What should I do to rotate triangle?

I referenced working code, but it still doesn't rotates.

solidpixel

You're trying to use OpenGL ES 1.1 functions (glLoadIdentity, glMatrixMode, glTranslatef, glRotatef, etc) in an OpenGL ES 2.0 context - this won't work. You can use either OpenGL ES 1.1 OR OpenGL ES 2.0, but you can't use both at the same time from the same context.

I would suggest sticking with OpenGL ES 2.0 using shaders, and learning the OpenGL ES 2.0 way of doing things, as this is how all of the newer APIs work.

To do translation and rotation you need to encode it into an MVP matrix and pass this as a uniform to the vertex shader which you use when calculating gl_Position. Some examples here:

https://open.gl/transformations

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related