Welcome to collectivesolver - Programming & Software Q&A with code examples. A website with trusted programming answers. All programs are tested and work.

Contact: aviboots(AT)netvision.net.il

Buy a domain name - Register cheap domain names from $0.99 - Namecheap

Scalable Hosting That Grows With You

Secure & Reliable Web Hosting, Free Domain, Free SSL, 1-Click WordPress Install, Expert 24/7 Support

Semrush - keyword research tool

Boost your online presence with premium web hosting and servers

Disclosure: My content contains affiliate links.

39,885 questions

51,811 answers

573 users

How to move a triangle using OpenGL with FreeGLUT, Shaders with rotation matrix, uniform, and GLEW in C++

1 Answer

0 votes
#include <iostream> // For std::cerr, std::cout
#include <fstream>  // For std::ifstream
#include <string>   // For std::string
#include <cstring>  // For strlen
#include <sstream>  // For std::stringstream (used in ReadFile)
#include <GL/glew.h> 
#include <freeglut.h> 

struct Vec3 {
    float x, y, z;

    Vec3() {}

    Vec3(float _x, float _y, float _z) {
        x = _x;
        y = _y;
        z = _z;
    }
};

struct Mat4
{
    float m[4][4] = { 0.0f };

    Mat4() {}

    Mat4(float v00, float v01, float v02, float v03,
         float v10, float v11, float v12, float v13,
         float v20, float v21, float v22, float v23,
         float v30, float v31, float v32, float v33)
    {
        m[0][0] = v00; m[0][1] = v01; m[0][2] = v02; m[0][3] = v03;
        m[1][0] = v10; m[1][1] = v11; m[1][2] = v12; m[1][3] = v13;
        m[2][0] = v20; m[2][1] = v21; m[2][2] = v22; m[2][3] = v23;
        m[3][0] = v30; m[3][1] = v31; m[3][2] = v32; m[3][3] = v33;
    }
};

GLuint VBO;
GLint gRotationLocation;

static void RenderScene() { 
    glClear(GL_COLOR_BUFFER_BIT);

    static float AngleRadians = 0.0f;
    static float Delta = 0.01f;

    // 1.5708 Radians = 90.0 Degrees

    // Rotate 90.0 Degrees to the left and to the right, 
    // and again to the left and to the right, and again...
    AngleRadians += Delta;
    if ((AngleRadians >= 1.5708f) || (AngleRadians <= -1.5708f)) { 
        Delta *= -1.0f; // change direction
    }

    Mat4 Rotation(cosf(AngleRadians), -sinf(AngleRadians), 0.0f, 0.0f,
                  sinf(AngleRadians), cosf(AngleRadians), 0.0f, 0.0f,
                  0.0, 0.0f, 1.0f, 0.0f,
                  0.0f, 0.0f, 0.0f, 1.0f);

    glUniformMatrix4fv(gRotationLocation, 1, GL_TRUE, &Rotation.m[0][0]); // glew

    glBindBuffer(GL_ARRAY_BUFFER, VBO); // glew

    glEnableVertexAttribArray(0); // glew

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); // glew

    // void glDrawArrays(GLenum mode, GLint first, GLsizei count);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    glDisableVertexAttribArray(0); // glew

    glutPostRedisplay(); // freeglut

    glutSwapBuffers(); // freeglut
}

static void AddShader(GLuint ShaderProgram, const char* pShaderText, GLenum ShaderType) {
    GLuint ShaderObj = glCreateShader(ShaderType); // glew

    if (ShaderObj == 0) {
        fprintf(stderr, "Error creating shader type %d\n", ShaderType);
        exit(0);
    }

    const GLchar* p[1]; // glew
    p[0] = pShaderText;

    GLint len[1];
    len[0] = (GLint)strlen(pShaderText);

    glShaderSource(ShaderObj, 1, p, len); // glew

    glCompileShader(ShaderObj); // glew

    GLint success;
    glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success); // glew

    if (!success) {
        GLchar InfoLog[1024]; // glew
        glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog); // glew
        fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog);
        exit(1);
    }

    glAttachShader(ShaderProgram, ShaderObj); // glew
}

const char* pVSFileName = "shader.vs";
const char* pFSFileName = "shader.fs";

static bool ReadFile(const char* pFileName, std::string& outFile)
{
    std::ifstream f(pFileName); // Open the file

    bool rv = false;
    if (f.is_open()) {
        std::stringstream ss;
        ss << f.rdbuf(); // Read entire file buffer into stringstream
        outFile = ss.str(); // Convert stringstream to std::string
        rv = true;
    }
    else {
        std::cerr << "Error opening file: " << pFileName << std::endl;
    }

    return rv;
}

static void CompileShaders()
{
    GLuint ShaderProgram = glCreateProgram(); // glew

    if (ShaderProgram == 0) {
        fprintf(stderr, "Error creating shader program - glCreateProgram\n");
        exit(1);
    }

    std::string vs, fs;

    if (!ReadFile(pVSFileName, vs)) {
        exit(1);
    };

    AddShader(ShaderProgram, vs.c_str(), GL_VERTEX_SHADER); // glew

    if (!ReadFile(pFSFileName, fs)) {
        exit(1);
    };

    AddShader(ShaderProgram, fs.c_str(), GL_FRAGMENT_SHADER); // glew

    GLint Success = 0;
    GLchar ErrorLog[1024] = { 0 }; // glew

    glLinkProgram(ShaderProgram); // glew

    glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success); // glew
    if (Success == 0) {
        glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog); // glew
        fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);
        exit(1);
    }

    gRotationLocation = glGetUniformLocation(ShaderProgram, "guRotation");
    if (gRotationLocation == -1) {
        printf("Error getting uniform location of 'guRotation'\n");
        exit(1);
    }

    glValidateProgram(ShaderProgram); // glew
    glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success); // glew
    if (!Success) {
        glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog); // glew
        fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);
        exit(1);
    }

    glUseProgram(ShaderProgram); // glew
}

static void CreateVertexBuffer() {
    Vec3 Vertices[3];

    Vertices[0] = Vec3(-0.5f, -0.5f, 0.0f); // bottom left
    Vertices[1] = Vec3(0.0f, 1.0f, 0.0f);   // top
    Vertices[2] = Vec3(0.5f, -0.5f, 0.0f);  // bottom right

    glGenBuffers(1, &VBO); // glew
    glBindBuffer(GL_ARRAY_BUFFER, VBO); // glew
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); // glew
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv); // freeglut
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); // freeglut

    int width = 800;
    int height = 600;
    glutInitWindowSize(width, height); // freeglut
     
    // freeglut
    int win = glutCreateWindow("freeglut - glutCreateWindow() - Draw Triangle with Shaders"); 

    GLenum res = glewInit(); // glew
    if (res != GLEW_OK) { // glew
        std::cout << glewGetErrorString(res); // glew
        return 1;
    }

    GLclampf Red = 0.0f, Green = 0.0f, Blue = 0.0f, Alpha = 0.0f;
    glClearColor(Red, Green, Blue, Alpha);

    CreateVertexBuffer();

    CompileShaders();

    glutDisplayFunc(RenderScene); // freeglut

    glutMainLoop(); // freeglut

    return 0;
}



/*
run



*/

 

// shader.vs
   
// vertex shader 

#version 460 core

layout (location = 0) in vec3 Position;

uniform mat4 guRotation;

void main()
{
    gl_Position = guRotation * vec4(Position, 1.0);
}

   
// shader.fs
   
// fragment shader 

#version 460 core

out vec4 FragColor;

void main()
{
    FragColor = vec4(1.0, 0.0, 0.0, 0.0);
}

 



answered Jul 8, 2025 by avibootz
edited Jul 8, 2025 by avibootz
...