如何在OpenGL中旋转三角形?

如何在OpenGL中旋转三角形?,opengl,opengl-es,Opengl,Opengl Es,我想在OpenGL中旋转我的三角形,并在Raspberry Pi上运行程序 我可以画三角形并移动它。 但我不知道如何旋转它。。 什么都不旋转 #include <cstdio> #include <ctime> #include <cmath> #include <string> #include <EGL/egl.h> #include <EGL/eglext.h> #include <GLES2/gl2.h>

我想在OpenGL中旋转我的三角形,并在Raspberry Pi上运行程序

我可以画三角形并移动它。 但我不知道如何旋转它。。 什么都不旋转

#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;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
EGLDisplay Disp;
EGL表面;
语境;
国际ScrWidth、ScrHeight;
浮动MVP矩阵[16];
浮动投影矩阵[16];
浮动视图矩阵[16];
使用名称空间std;
类着色器
{
私人:
字符串顶点着色器文件;
字符串碎片着色器文件;
GLuint加载(GLenum类型,字符串文件名)
{
(编译着色器)
}
GLuint程序;
布尔链接;
公众:
着色器(字符串FileNameV、字符串FileNameF)
{
链接=假;
VertexShaderFile=FileNameV;
FragmentShaderFile=FileNameF;
}
布尔负荷()
{
(链接顶点/片段着色器)
}
无效使用()
{
glUseProgram(程序);
}
int GetAttrLoc(常量字符*名称)
{
GLGetAttriblLocation(程序、名称);
}
int GetUniformLoc(常量字符*名称)
{
返回glGetUniformLocation(程序,名称);
}
~Shader()
{
如果(链接)
{
链接=假;
glDeleteProgram(Program);
}
}
};
阶级三角
{
私人:
每个顶点的常数int坐标=3;
const int vertexCount=9/COORDS\u PER\u顶点;//9:三角形坐标的长度
const int vertexStride=COORDS\u PER\u VERTEX*4;//每个顶点4字节
静态浮动三角形坐标[];
浮色[4];
浮动XOff;
浮动约夫;
浮子佐夫;
着色器*S;
公众:
三角形()
{
XOff=YOff=ZOff=0;
S=新着色器(“着色器/test.vsh”、“着色器/test.fsh”);
如果(!S->Load())
{
删除S;
S=零;
}
}
void SetColor(int R、int G、int B、int A)
{
颜色[0]=R/255.0;
颜色[1]=G/255.0;
颜色[2]=B/255.0;
颜色[3]=A/255.0;
}
void SetXYZ(整数X,整数Y,整数Z)
{
(设置位置)
}
布尔图()
{
按逆时针顺序浮动三角形坐标[]={//:
-0.0+XOff,0.622008459+YOff,0.0+ZOff,//顶部
-0.5+XOff,-0.311004243+YOff,0.0+ZOff,//左下角
0.5+XOff,-0.311004243+YOff,0.0+ZOff//右下角
};
printf(“%f\n”,三角形字体[1]);
//glMatrixMode(GL_投影);
如果(S==NULL)
返回false;
S->Use();
//加载顶点数据
glvertexattributepointer(0,3,GL_FLOAT,GL_FALSE,0,TriangleCoords);
//获取形状变换矩阵的句柄
//将投影和视图变换传递给着色器
//UniformMatrix4fv(S->GetUniformLoc(“uMVPMatrix”),1,false,MVPMatrix);
glUniform4fv(S->GetUniformLoc(“vColor”),1,颜色);
GlenableVertexAttributeArray(0);
//glPushMatrix();
glLoadIdentity();
glMatrixMode(GLU模型视图);
浮动X=本地时间->tm_小时/23.0;
浮动Y=本地时间->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);
gldrawArray(GL_三角形,0,3);
//glPopMatrix();
返回true;
}
};
bool InitDisplay()
{
bcm_主机_初始化();
Disp=eglGetDisplay(EGL_默认显示);
if(eglInitialize(Disp,NULL,NULL)!=EGL\u TRUE)
{
printf(“显示初始化错误。\n”);
返回false;
}
printf(“显示已初始化。\n”);
静态常量EGLint AttrList[]=
{
EGL_红色_尺寸,8,
EGL_绿色_尺寸,8,
EGL_蓝色_尺寸,8,
EGL_阿尔法_尺寸,8,
EGL_表面_类型,EGL_窗口_位,
无
};
EGLConfig配置;
int-ConfigCount;
if(eglChooseConfig(Disp、AttrList和Config、1和ConfigCount)!=EGL\u TRUE)
{
printf(“显示选择配置错误。\n”);
返回false;
}
printf(“已选择显示配置。%d个配置。\n”,ConfigCount);
//if(eglBindAPI(EGL\u OPENGL\u ES\u API)!=EGL\u TRUE)
//{
//printf(“绑定API错误。\n”);
//返回false;
//}
//printf(“API绑定的。\n”);
静态常量EGLint ContextAttr[]=
{
EGL_上下文_客户端_版本,2,
无
};
if((Context=eglCreateContext(Disp,Config,EGL\u NO\u Context,ContextAttr))==EGL\u NO\u Context)
{
printf(“创建上下文错误。\n”);
返回false;
}
printf(“已创建上下文。\n”);
if(图形显示尺寸(0/*LCD*/,&ScrWidth,&ScrHeight)<0)
{
printf(“获取屏幕大小错误。\n”);
返回false;
}
printf(“获取屏幕大小。%dx%d\n”,ScrWidth,ScrHeight);
DISPMANX\u显示\u处理\u DispmanDisp;
DispmanDisp=vc_dispmanx_display_open(0/*LCD*/);
printf(“Dispmanx-显示打开。\n”);
DISPMANX\u UPDATE\u HANDLE\u T DispmanUpdate;
DispmanUpdate=vc\U dispmanx\U update\U start(0);
printf(“Dispmanx-更新已开始。\n”);
DISPMANX\u元素\u句柄\u T DispmanElement;
VC__u u T DestRect;
VC_RECT_T srrect;
析取x=0;
析取y=0;
DestRect.width=ScrWidth;
DestRect.height=ScrHeight;
SrcRect.x=0;
srrect.y=0;
SrcRect.width=ScrWidth tm_min,LocalTime->tm_sec);
浮动R=LocalTime->tm_hour/23.0;
float G=LocalTime->tm_min/59.0;
浮动B=本地时间->tm_秒/59.0;
T1.SetColor(255,0,0,255);
T1.SetXYZ(B*ScrWidth,B*ScrHeight,0);
//glClearColor(0,0,0,1.0);
//glClear(GLU颜色缓冲位);
如果(!T1.Draw()| | |!T2.Draw()| |!T3.Draw()| |!T4.Draw())
{
返回;
}
glFlush();
eglSwapBuffers(显示,表面);
}
}
int main()
{
如果(!InitDisplay())
{
普林