Untitled
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