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 draw triangle with mixture of 3 colors using OpenGL in C

1 Answer

0 votes
#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdarg.h>
#include <stdbool.h>
#include <assert.h>

static const GLint WIDTH = 800, HEIGHT = 600;

GLuint VAO, VBO, shader;

static const char* vertexShader =
"#version 460\n"
"layout(location = 0) in vec3 vertex_position;"
"layout(location = 1) in vec3 vertex_color;"
"out vec3 color;"
"void main()"
"{"
"color = vertex_color;"
"gl_Position = vec4(vertex_position, 1.0);"
"}";

static const char* fragmentShader =
"#version 460\n"
"in vec3 color;"
"out vec4 FragmentColor;"
"void main()"
"{"
"   FragmentColor = vec4(color, 1.0);"
"}";

static const char OPENGL_LOG_FILE[11] = "opengl.log";

bool start_opengl_log_file() {
    FILE* file = fopen(OPENGL_LOG_FILE, "w");
    if (!file) {
        fprintf(stderr, "ERROR: could not open: %s\n", OPENGL_LOG_FILE);
        return false;
    }
    time_t now = time(NULL);
    char* date = ctime(&now);
    fprintf(file, "time: %s\n", date);
    fclose(file);

    return true;
}

bool write_to_opengl_log(const char* message, ...) {
    va_list valist;
    FILE* file = fopen(OPENGL_LOG_FILE, "a");
    if (!file) {
        fprintf(stderr, "ERROR: could not open: %s\n", OPENGL_LOG_FILE);
        return false;
    }
    va_start(valist, message);
    vfprintf(file, message, valist);
    va_end(valist);
    fclose(file);

    return true;
}

bool write_error_to_opengl_log_file(const char* message, ...) {
    va_list valist;
    FILE* file = fopen(OPENGL_LOG_FILE, "a");
    if (!file) {
        fprintf(stderr, "ERROR: could not open: %s\n", OPENGL_LOG_FILE);
        return false;
    }
    va_start(valist, message);
    vfprintf(file, message, valist);
    va_end(valist);
    va_start(valist, message);
    vfprintf(stderr, message, valist);
    va_end(valist);
    fclose(file);

    return true;
}

void glfw_error_callback(int error, const char* description) {
    write_error_to_opengl_log_file("GLFW ERROR: code %i msg: %s\n", error, description);
}

void CreateTriangle() {
    float vertices[] = {
        0.0f,  0.5f,  0.0f,
        0.5f, -0.5f,  0.0f,
       -0.5f, -0.5f,  0.0f
    };

    float colors[] = {
        1.0f, 0.0f,  0.0f,
        0.0f, 1.0f,  0.0f,
        0.0f, 0.0f,  1.0f
    };

    // VBO
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    GLuint vbo_colors = 0;
    glGenBuffers(1, &vbo_colors);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);

    // VAO
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);

    glBindBuffer(GL_ARRAY_BUFFER, vbo_colors);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, NULL);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
}

void AddShader(GLuint program, const char* shaderCode, GLenum shaderType) {
    GLuint theShader = glCreateShader(shaderType);

    const GLchar* theCode[1]; // Array of pointers
    theCode[0] = shaderCode;

    GLint codeLength[1];
    codeLength[0] = (GLint)strlen(shaderCode);

    glShaderSource(theShader, 1, theCode, codeLength);
    glCompileShader(theShader);

    GLint result = 0;
    GLchar error[1024] = { 0 };

    glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
    if (!result) {
        glGetShaderInfoLog(theShader, sizeof(error), NULL, error);
        printf("Error compiling the %d shader: %s", shaderType, error);
        return;
    }

    glAttachShader(program, theShader);
}
 

void CompileShaders() {
    shader = glCreateProgram();

    if (!shader) {
        printf("glCreateProgram() Error");
        return;
    }

    AddShader(shader, vertexShader, GL_VERTEX_SHADER);
    AddShader(shader, fragmentShader, GL_FRAGMENT_SHADER);

    glBindAttribLocation(shader, 0, "vertex_position");
    glBindAttribLocation(shader, 1, "vertex_color");

    GLint result = 0;
    GLchar error[1024] = { 0 };

    glLinkProgram(shader);

    glGetProgramiv(shader, GL_LINK_STATUS, &result);
    if (!result) {
        glGetProgramInfoLog(shader, sizeof(error), NULL, error);
        printf("glLinkProgram() Error: %s", error);
        return;
    }
}

int main(void)
{
    assert(start_opengl_log_file());
    write_to_opengl_log("starting GLFW version: %s\n", glfwGetVersionString());
    glfwSetErrorCallback(glfw_error_callback);
    if (!glfwInit()) {
        fprintf(stderr, "glfwInit() Error\n");
        return 1;
    }

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "window title", NULL, NULL);
    if (!window) {
        printf("glfwCreateWindow() Error");
        glfwTerminate();
        return 1;
    }

    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;

    if (glewInit() != GLEW_OK) {
        printf("glewInit() Error");
        glfwDestroyWindow(window);
        glfwTerminate();
    }

    CreateTriangle();
    CompileShaders();

    while (!glfwWindowShouldClose(window)) {
        glfwPollEvents();

        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
            glfwSetWindowShouldClose(window, 1);
        }

        glClearColor(1.0f, 0.5f, 0.25f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(shader);
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        glfwSwapBuffers(window);
    }

    glfwDestroyWindow(window);
    glfwTerminate();

    return 0;
}




/*
run:


*/

 



answered Mar 22, 2022 by avibootz
...