Untitled

 avatar
unknown
plain_text
a month ago
14 kB
9
Indexable
#include <iostream>
#include <vector>

#include <GL/glew.h>
//#include <GL/gl.h> // OpenGL header not necessary, included by GLEW
#include <GL/freeglut.h>

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/matrix_inverse.hpp>

#include "GLSLProgram.h"
#include "GLTools.h"


#include <algorithm> //std::max() und std::min()
#include <cmath> //fmod(), fabs()



void hsvToRgb(float h, float s, float v, float& r, float& g, float& b)
{
    float c = v * s;
    float x = c * (1.0f - fabs(fmod(h / 60.0f, 2.0f) - 1.0f));
    float m = v - c;   // Helligkeit 

    float rp = 0.0f, gp = 0.0f, bp = 0.0f;

    if (h < 60.0f) {
        rp = c; gp = x; bp = 0.0f;   //  Rot→Gelb
    }
    else if (h < 120.0f) {
        rp = x; gp = c; bp = 0.0f;    // Gelb→Grün
    }
    else if (h < 180.0f) {
        rp = 0.0f; gp = c; bp = x;   // Grün→Cyan
    }
    else if (h < 240.0f) {
        rp = 0.0f; gp = x; bp = c;   // Cyan→Blau
    }
    else if (h < 300.0f) {
        rp = x; gp = 0.0f; bp = c;   // Blau→Magenta
    }
    else {
        rp = c; gp = 0.0f; bp = x;   // Magenta→Rot
    }

    r = rp + m;
    g = gp + m;
    b = bp + m;
}

void rgbToHsv(float r, float g, float b, float& h, float& s, float& v)
{
    float maxVal = std::max(r, std::max(g, b)); //hellste Farbe
    float minVal = std::min(r, std::min(g, b)); //dunkelste Farbe
    float delta = maxVal - minVal; //Farbstärke 
     
    v = maxVal; //Helligkeit 
    s = (maxVal == 0.0f) ? 0.0f : delta / maxVal; //Sättigung 
      //Farbwinkel 

    if (delta == 0.0f)        h = 0.0f;               // Grau → h egal
    else if (maxVal == r)     h = 60 * fmod((g - b) / delta, 6);  // Rot-Bereich
    else if (maxVal == g)     h = 60 * ((b - r) / delta + 2);     // Grün-Bereich
    else                      h = 60 * ((r - g) / delta + 4);     // Blau-Bereich

    if (h < 0) h += 360;  // negativen Winkel korrigieren
}


// Standard window width
const int WINDOW_WIDTH = 640;
// Standard window height
const int WINDOW_HEIGHT = 480;
// GLUT window id/handle
int glutID = 0;

cg::GLSLProgram program;

glm::mat4x4 view;
glm::mat4x4 projection;

float zNear = 0.1f;
float zFar = 100.0f;

/*
Struct to hold data for object rendering.
*/
class Object
{
public:
    inline Object()
        : vao(0),
        positionBuffer(0),
        colorBuffer(0),
        indexBuffer(0)
    {
    }

    inline ~Object() { // GL context must exist on destruction
        glDeleteVertexArrays(1, &vao);
        glDeleteBuffers(1, &indexBuffer);
        glDeleteBuffers(1, &colorBuffer);
        glDeleteBuffers(1, &positionBuffer);
    }

    GLuint vao;        // vertex-array-object ID  , Vertex ist ein punkt im raum , jede Vertex hat ihre eigene farbe 

    GLuint positionBuffer; // ID of vertex-buffer: position
    GLuint colorBuffer;    // ID of vertex-buffer: color

    GLuint indexBuffer;    // ID of index-buffer

    glm::mat4x4 model; // model matrix
};

Object triangle;
Object quad;
glm::vec3 quadColor(0.5f, 0.5f, 0.5f);
void renderTriangle()
{
    // Create mvp.
    glm::mat4x4 mvp = projection * view * triangle.model; //projection ist 3/2D, view Kamera, Model art der objekt z.b große rotation usw.

    // Bind the shader program and set uniform(s).
    program.use();
    program.setUniform("mvp", mvp);

    // Bind vertex array object so we can render the 1 triangle.
    glBindVertexArray(triangle.vao);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, 0);
    glBindVertexArray(0);
}

void renderQuad()
{
    // Create mvp.
    glm::mat4x4 mvp = projection * view * quad.model;

    // Bind the shader program and set uniform(s).
    program.use();
    program.setUniform("mvp", mvp);

    // Bind vertex array object so we can render the 2 triangles.
    glBindVertexArray(quad.vao);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);//Alles wird mit Dreieck gezeichnet daher kein GL_QUAD mehr. Hier ist der fall ein viereck ist nur 2 Drei
    glBindVertexArray(0);
}

void initTriangle()
{
    // Construct triangle. These vectors can go out of scope after we have send all data to the graphics card.
    const std::vector<glm::vec3> vertices = { glm::vec3(-1.0f, 1.0f, 0.0f), glm::vec3(1.0f, -1.0f, 0.0f), glm::vec3(1.0f, 1.0f, 0.0f) };//Punkte des Dreiecks
    const std::vector<glm::vec3> colors = { glm::vec3(1.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f), glm::vec3(0.0f, 0.0f, 1.0f) }; // Farben der Punkte (Vertex)
    const std::vector<GLushort>  indices = { 0, 1, 2 };//Zeichne ein Dreieck aus Punkt 0, Punkt 1 und Punkt 2

    GLuint programId = program.getHandle();
    GLuint pos;

    //   VAO = merkt sich, welche Daten zu diesem Objekt gehören(Position,Farben,Indizes)
    // Step 0: Create vertex array object.
    glGenVertexArrays(1, &triangle.vao);
    glBindVertexArray(triangle.vao);

    // Step 1: Create vertex buffer object for position attribute and bind it to the associated "shader attribute". Also schickt punkte zu Grafikkarte
    glGenBuffers(1, &triangle.positionBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, triangle.positionBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);

    // Bind it to position.  (Die Daten aus positionBuffer gehören im Shader zur Variable "position")
    pos = glGetAttribLocation(programId, "position");
    glEnableVertexAttribArray(pos);
    glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, 0);

    // Step 2: Create vertex buffer object for color attribute and bind it to... Genau das gleiche nochmal für Color 
    glGenBuffers(1, &triangle.colorBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, triangle.colorBuffer);
    glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_STATIC_DRAW);

    // Bind it to color.
    pos = glGetAttribLocation(programId, "color");
    glEnableVertexAttribArray(pos);
    glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, 0);

    // Step 3: Create vertex buffer object for indices.   (((( No binding needed here.))))
    glGenBuffers(1, &triangle.indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangle.indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), indices.data(), GL_STATIC_DRAW);

    // Unbind vertex array object (back to default). Fertig mit Einrichtung 
    glBindVertexArray(0);

    // Modify model matrix. ((Das verschiebt das Dreieck))
    triangle.model = glm::translate(glm::mat4(1.0f), glm::vec3(-1.25f, 0.0f, 0.0f));
}

void initQuad()
{
    // Construct triangle. These vectors can go out of scope after we have send all data to the graphics card.
    const std::vector<glm::vec3> vertices = { { -1.0f, 1.0f, 0.0f }, { -1.0, -1.0, 0.0 }, { 1.0f, -1.0f, 0.0f }, { 1.0f, 1.0f, 0.0f } };
    const std::vector<glm::vec3> colors = { quadColor,quadColor,quadColor,quadColor };
    const std::vector<GLushort>  indices = { 0, 1, 2, 0, 2, 3 };

    GLuint programId = program.getHandle();
    GLuint pos;

    // Step 0: Create vertex array object.
    glGenVertexArrays(1, &quad.vao);
    glBindVertexArray(quad.vao);

    // Step 1: Create vertex buffer object for position attribute and bind it to the associated "shader attribute".
    glGenBuffers(1, &quad.positionBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, quad.positionBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), vertices.data(), GL_STATIC_DRAW);

    // Bind it to position.
    pos = glGetAttribLocation(programId, "position");
    glEnableVertexAttribArray(pos);
    glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, 0);

    // Step 2: Create vertex buffer object for color attribute and bind it to...
    glGenBuffers(1, &quad.colorBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, quad.colorBuffer);
    glBufferData(GL_ARRAY_BUFFER, colors.size() * sizeof(glm::vec3), colors.data(), GL_STATIC_DRAW);

    // Bind it to color.
    pos = glGetAttribLocation(programId, "color");
    glEnableVertexAttribArray(pos);
    glVertexAttribPointer(pos, 3, GL_FLOAT, GL_FALSE, 0, 0);

    // Step 3: Create vertex buffer object for indices. No binding needed here.
    glGenBuffers(1, &quad.indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, quad.indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLushort), indices.data(), GL_STATIC_DRAW);

    // Unbind vertex array object (back to default).
    glBindVertexArray(0);

    // Modify model matrix.
    quad.model = glm::translate(glm::mat4(1.0f), glm::vec3(1.25f, 0.0f, 0.0f));
}

/*
 Initialization. Should return true if everything is ok and false if something went wrong.
 */
bool init()
{
    // OpenGL: Set "background" color and enable depth testing.
    glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
    glEnable(GL_DEPTH_TEST);

    // Construct view matrix.
    glm::vec3 eye(0.0f, 0.0f, 4.0f);
    glm::vec3 center(0.0f, 0.0f, 0.0f);
    glm::vec3 up(0.0f, 1.0f, 0.0f);

    view = glm::lookAt(eye, center, up);

    // Create a shader program and set light direction.
    if (!program.compileShaderFromFile("shader/simple.vert", cg::GLSLShader::VERTEX)) {
        std::cerr << program.log();
        return false;
    }

    if (!program.compileShaderFromFile("shader/simple.frag", cg::GLSLShader::FRAGMENT)) {
        std::cerr << program.log();
        return false;
    }

    if (!program.link()) {
        std::cerr << program.log();
        return false;
    }

    // Create all objects.
    initTriangle();
    initQuad();

    return true;
}

/*
 Rendering.
 */
void render()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    renderTriangle();
    renderQuad();
}

void glutDisplay()
{
    render();
    glutSwapBuffers();
}

/*
 Resize callback.
 */
void glutResize(int width, int height)
{
    // Division by zero is bad...
    height = height < 1 ? 1 : height;
    glViewport(0, 0, width, height);

    // Construct projection matrix.
    projection = glm::perspective(45.0f, (float)width / height, zNear, zFar);
}

/*
 Callback for char input.
 */
void glutKeyboard(unsigned char keycode, int x, int y)
{
    switch (keycode) {
    case 27: // ESC
        glutDestroyWindow(glutID);
        return;

    case '+':
        // do something
        break;
    case '-':
        // do something
        break;
    case 'x':
        // do something
        break;
    case 'y':
        // do something
        break;
    case 'z':
        // do something
        break;
    }
    glutPostRedisplay();
}

int main(int argc, char** argv)
{
    // GLUT: Initialize freeglut library (window toolkit).
    glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT);
    glutInitWindowPosition(40, 40);
    glutInit(&argc, argv);

    // GLUT: Create a window and opengl context (version 4.3 core profile).
    glutInitContextVersion(4, 3);
    glutInitContextFlags(GLUT_FORWARD_COMPATIBLE | GLUT_DEBUG);
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);

    glutCreateWindow("Aufgabenblatt 01");
    glutID = glutGetWindow();

    // GLEW: Load opengl extensions
    //glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK) {
        return -1;
    }


    ////////// Um den OpenGL-Version raus finden //////
    std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl; 


    float r, g, b;
    float c, m, y;
    float h, s, v;

    std::cout << "\nAufgabe 1: Umrechnung Farbmodelle\n";

    std::cout << "\nCMY eingeben (c m y, Werte 0 bis 1): ";
    std::cin >> c >> m >> y;

    r = 1.0f - c;
    g = 1.0f - m;
    b = 1.0f - y;

    rgbToHsv(r, g, b, h, s, v);

    std::cout << "RGB: " << r << " " << g << " " << b << std::endl;
    std::cout << "HSV: " << h << " " << s << " " << v << std::endl;

    std::cout << "\nHSV eingeben (h s v, h 0 bis <360, s/v 0 bis 1): ";
    std::cin >> h >> s >> v;

    hsvToRgb(h, s, v, r, g, b);

    c = 1.0f - r;
    m = 1.0f - g;
    y = 1.0f - b;

    std::cout << "RGB: " << r << " " << g << " " << b << std::endl;
    std::cout << "CMY: " << c << " " << m << " " << y << std::endl;

    std::cout << "\nAufgabe 2: Viereck einfaerben\n";
    std::cout << "1 = RGB\n";
    std::cout << "2 = CMY\n";
    std::cout << "3 = HSV\n";

    int auswahl;
    std::cout << "Auswahl: ";
    std::cin >> auswahl;

    if (auswahl == 1) {
        std::cout << "RGB eingeben (r g b): ";
        std::cin >> r >> g >> b;
    }
    else if (auswahl == 2) {
        std::cout << "CMY eingeben (c m y): ";
        std::cin >> c >> m >> y;

        r = 1.0f - c;
        g = 1.0f - m;
        b = 1.0f - y;
    }
    else if (auswahl == 3) {
        std::cout << "HSV eingeben (h s v): ";
        std::cin >> h >> s >> v;

        hsvToRgb(h, s, v, r, g, b);
    }
    else {
        std::cout << "Ungueltige Auswahl. Standardfarbe Grau wird verwendet.\n";
        r = 0.5f;
        g = 0.5f;
        b = 0.5f;
    }

    quadColor = glm::vec3(r, g, b);






#if _DEBUG
    if (glDebugMessageCallback) {
        std::cout << "Register OpenGL debug callback " << std::endl;
        glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
        glDebugMessageCallback(cg::glErrorVerboseCallback, nullptr);
        glDebugMessageControl(GL_DONT_CARE,
            GL_DONT_CARE,
            GL_DONT_CARE,
            0,
            nullptr,
            true); // get all debug messages
    }
    else {
        std::cout << "glDebugMessageCallback not available" << std::endl;
    }
#endif

    // GLUT: Set callbacks for events.
    glutReshapeFunc(glutResize);
    glutDisplayFunc(glutDisplay);
    //glutIdleFunc   (glutDisplay); // redisplay when idle
    glutKeyboardFunc(glutKeyboard);



    // init vertex-array-objects.
    bool result = init();
    if (!result) {
        return -2;
    }

    // GLUT: Loop until the user closes the window
    // rendering & event handling
    glutMainLoop();

    // Cleanup in destructors:
    // Objects will be released in ~Object
    // Shader program will be released in ~GLSLProgram

    return 0;
}
Editor is loading...
Leave a Comment