mirror of
https://github.com/kuhyx/engineer-thesis-WUT.git
synced 2026-07-04 14:43:10 +02:00
254 lines
12 KiB
C++
254 lines
12 KiB
C++
#ifndef DRAW_CPP
|
|
#define DRAW_CPP
|
|
#include <glad/glad.h>
|
|
#include <GLFW/glfw3.h>
|
|
#include <iostream>
|
|
#include <cmath>
|
|
#include <filesystem>
|
|
#include "draw.hpp"
|
|
#include "renderLoop.hpp"
|
|
#include "shaders.hpp"
|
|
#include "constants.hpp"
|
|
#include "misc.hpp"
|
|
#include "shader.hpp"
|
|
#include "textures.hpp"
|
|
#include "stb_image.h"
|
|
|
|
drawFigureReturn drawFigure(const int whatToDraw)
|
|
{
|
|
switch (whatToDraw)
|
|
{
|
|
case 0:
|
|
return drawTriangleClass(constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, constants::VERTEX_SHADER_SOURCE_FILENAME, constants::FRAGMENT_SHADER_SOURCE_FILENAME);
|
|
case 1:
|
|
return drawSquare(constants::SQUARE_VERTICES, constants::SQUARE_VERTICES_SIZE, constants::SQUARE_INDICES, constants::SQUARE_INDICES_SIZE, constants::VERTEX_SHADER_SOURCE, constants::FRAGMENT_SHADER_SOURCE);
|
|
case 2:
|
|
// Try to draw 2 triangles next to each other using glDrawArrays by adding more vertices to your data.
|
|
return drawTriangleClass(constants::TRIANGLES_VERTICES, constants::TRIANGLES_VERTICES_SIZE, constants::VERTEX_SHADER_SOURCE_FILENAME, constants::FRAGMENT_SHADER_SOURCE_FILENAME);
|
|
case 3:
|
|
drawTriangleClass(constants::TRIANGLE_ONE, constants::TRIANGLE_ONE_SIZE, constants::VERTEX_SHADER_SOURCE_FILENAME, constants::FRAGMENT_SHADER_SOURCE_FILENAME);
|
|
// Now create the same 2 triangles using two different VAOs and VBOs for their data
|
|
return drawTriangleClass(constants::TRIANGLE_TWO, constants::TRIANGLE_TWO_SIZE, constants::VERTEX_SHADER_SOURCE_FILENAME, constants::FRAGMENT_SHADER_SOURCE_FILENAME);
|
|
case 4:
|
|
drawTriangleClass(constants::TRIANGLE_ONE, constants::TRIANGLE_ONE_SIZE, constants::VERTEX_SHADER_SOURCE_FILENAME, constants::FRAGMENT_SHADER_SOURCE_FILENAME);
|
|
// Create two shader programs where the second program uses a different fragment shader that outputs the color yellow; draw both triangles again where one outputs the color yellow
|
|
return drawTriangleClass(constants::TRIANGLE_TWO, constants::TRIANGLE_TWO_SIZE, constants::VERTEX_SHADER_SOURCE_FILENAME, constants::FRAGMENT_SHADER_SOURCE_YELLOW_FILENAME);
|
|
case 5:
|
|
// Get color from vertex shader to fragment shader
|
|
return drawTriangleClass(constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, constants::VERTEX_SHADER_COLOR_FILENAME, constants::FRAGMENT_SHADER_COLOR_FROM_VERTEX_FILENAME);
|
|
case 6:
|
|
// set color from opengl code to uniform value in fragment shader
|
|
return drawTriangleClass(constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, constants::VERTEX_SHADER_COLOR_FILENAME, constants::FRAGMENT_SHADER_UNIFORMS_FILENAME);
|
|
case 7:
|
|
// set color from opengl code to uniform value in fragment shader
|
|
return drawTriangleClass(constants::TRIANGLE_COLORS, constants::TRIANGLE_COLORS_SIZE, constants::VERTEX_SHADER_VERTICE_COLOR_FILENAME, constants::FRAGMENT_SHADER_COLOR_FROM_VERTEX_FILENAME, true);
|
|
case 8:
|
|
// upside down triangle
|
|
return drawTriangleClass(constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, constants::VERTEX_SHADER_UPSIDE_DOWN_FILENAME, constants::FRAGMENT_SHADER_SOURCE_FILENAME);
|
|
case 9:
|
|
{
|
|
// offset triangle
|
|
offsetsStruct offsets = offsetsStruct();
|
|
offsets.xOffset = 0.5f;
|
|
return drawTriangleClass(constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, constants::VERTEX_SHADER_OFFSET_FILENAME, constants::FRAGMENT_SHADER_SOURCE_FILENAME, false, false, offsets);
|
|
}
|
|
case 10:
|
|
return drawTriangleClass(constants::TRIANGLE_VERTICES, constants::TRIANGLE_VERTICES_SIZE, constants::VERTEX_SHADER_TASK_THREE_FILENAME, constants::FRAGMENT_SHADER_TASK_THREE_FILENAME);
|
|
case constants::MAX_DRAW_CALL:
|
|
return drawDebilMode(constants::VERTEX_SHADER_TEXTURE_FILENAME, constants::FRAGMENT_SHADER_TEXTURE_FILENAME, constants::TEXTURE_VERTICES, constants::TEXTURE_VERTICES_SIZE, constants::TEXTURE_INDICES, constants::TEXTURE_INDICES_SIZE);
|
|
default:
|
|
throw "No function for this draw call";
|
|
}
|
|
}
|
|
|
|
unsigned int getShaderProgram(const char* vertexShaderSource, const char* fragmentShaderSource)
|
|
{
|
|
const std::pair<unsigned int, unsigned int> shaders = compileShaders(vertexShaderSource, fragmentShaderSource);
|
|
if (shaders.first == 0 || shaders.second == 0)
|
|
return 0;
|
|
|
|
const unsigned int shaderProgram = linkShaderObjectsShaderProgram(shaders.first, shaders.second);
|
|
if (shaderProgram == 0)
|
|
return 0;
|
|
return shaderProgram;
|
|
}
|
|
|
|
void setOffsets(Shader shader, const offsetsStruct offsets) {
|
|
shader.setFloat("xOffset", offsets.xOffset);
|
|
shader.setFloat("yOffset", offsets.yOffset);
|
|
shader.setFloat("zOffset", offsets.zOffset);
|
|
}
|
|
|
|
drawFigureReturn drawTriangleClass(const float triangleVertices[], const size_t triangleVerticesSize, const char* vertexPath, const char* fragmentPath, const bool colorIncluded, const bool textureIncluded, const offsetsStruct offsets)
|
|
{
|
|
// In your CPP file:
|
|
// ======================
|
|
// float offset = 0.5f;
|
|
|
|
Shader ourShader(vertexPath, fragmentPath);
|
|
ourShader.use();
|
|
setOffsets(ourShader, offsets);
|
|
|
|
const unsigned int vertexBufferObject = copyVerticesMemory(triangleVertices, triangleVerticesSize, GL_ARRAY_BUFFER);
|
|
const unsigned int vertexArrayObject = generateBindVAO();
|
|
copyVerticesArray(vertexBufferObject, triangleVertices, triangleVerticesSize, GL_ARRAY_BUFFER);
|
|
// set vertex attribute pointers
|
|
configureVertexAttribute(colorIncluded, textureIncluded);
|
|
doDrawArrays(ourShader.ID, vertexArrayObject, GL_TRIANGLES, 0, triangleVerticesSize);
|
|
drawFigureReturn newReturn;
|
|
newReturn.success = 0;
|
|
newReturn.VAO = vertexArrayObject;
|
|
newReturn.VBO = vertexBufferObject;
|
|
newReturn.EBO = 0;
|
|
return newReturn;
|
|
}
|
|
|
|
drawFigureReturn drawTriangle(const float triangleVertices[], const size_t triangleVerticesSize, const char* vertexShaderSource, const char* fragmentShaderSource, const bool colorIncluded, const bool textureIncluded)
|
|
{
|
|
|
|
const unsigned int shaderProgram = getShaderProgram(vertexShaderSource, fragmentShaderSource);
|
|
drawFigureReturn newReturn;
|
|
if (shaderProgram == 0) {
|
|
newReturn.success = -1;
|
|
return newReturn;
|
|
}
|
|
|
|
const unsigned int vertexBufferObject = copyVerticesMemory(triangleVertices, triangleVerticesSize, GL_ARRAY_BUFFER);
|
|
const unsigned int vertexArrayObject = generateBindVAO();
|
|
copyVerticesArray(vertexBufferObject, triangleVertices, triangleVerticesSize, GL_ARRAY_BUFFER);
|
|
|
|
// set vertex attribute pointers
|
|
configureVertexAttribute(colorIncluded, textureIncluded);
|
|
doDrawArrays(shaderProgram, vertexArrayObject, GL_TRIANGLES, 0, triangleVerticesSize);
|
|
newReturn.success = 0;
|
|
newReturn.VAO = vertexArrayObject;
|
|
newReturn.VBO = vertexBufferObject;
|
|
newReturn.EBO = 0;
|
|
return newReturn;
|
|
}
|
|
|
|
drawFigureReturn drawSquare(const float squareVertices[], const size_t squareVerticesSize, const unsigned int squareIndices[], const size_t squareIndicesSize, const char* vertexShaderSource, const char* fragmentShaderSource, const bool colorIncluded, const bool textureIncluded, const offsetsStruct offsets)
|
|
{
|
|
const unsigned int shaderProgram = getShaderProgram(vertexShaderSource, fragmentShaderSource);
|
|
drawFigureReturn newReturn;
|
|
if (shaderProgram == 0) {
|
|
newReturn.success = -1;
|
|
return newReturn;
|
|
}
|
|
const unsigned int VAO = generateBindVAO();
|
|
copyVerticesMemory(squareVertices, squareVerticesSize, GL_ARRAY_BUFFER);
|
|
copyVerticesMemory(squareIndices, squareIndicesSize, GL_ELEMENT_ARRAY_BUFFER);
|
|
|
|
// set vertex attribute pointers
|
|
configureVertexAttribute(colorIncluded, textureIncluded);
|
|
|
|
doDrawElements(shaderProgram, VAO, GL_TRIANGLES, GL_UNSIGNED_INT, squareIndicesSize);
|
|
newReturn.success = 0;
|
|
newReturn.VAO = VAO;
|
|
newReturn.VBO = 0;
|
|
newReturn.EBO = 0;
|
|
return newReturn;
|
|
}
|
|
|
|
drawFigureReturn drawSquareClass(const char* vertexPath, const char* fragmentPath, const bool colorIncluded, const bool textureIncluded, const offsetsStruct offsets)
|
|
{
|
|
Shader ourShader(vertexPath, fragmentPath);
|
|
ourShader.use();
|
|
const unsigned int vertexBufferObject = copyVerticesMemory(constants::SQUARE_VERTICES, constants::SQUARE_VERTICES_SIZE, GL_ARRAY_BUFFER);
|
|
const unsigned int vertexArrayObject = generateBindVAO();
|
|
copyVerticesArray(vertexBufferObject, constants::SQUARE_VERTICES, constants::SQUARE_VERTICES_SIZE, GL_ARRAY_BUFFER);
|
|
|
|
// set vertex attribute pointers
|
|
configureVertexAttribute(false, false);
|
|
doDrawArrays(ourShader.ID, vertexArrayObject, GL_TRIANGLES, 0, constants::SQUARE_VERTICES_SIZE);
|
|
drawFigureReturn newReturn;
|
|
newReturn.success = 0;
|
|
newReturn.VAO = vertexArrayObject;
|
|
newReturn.VBO = vertexBufferObject;
|
|
newReturn.EBO = 0;
|
|
return newReturn;
|
|
}
|
|
|
|
drawFigureReturn drawDebilMode(const char* vertexPath, const char* fragmentPath, const float vertices[], const size_t verticesSize, const unsigned int indices[], const size_t indicesSize) {
|
|
// https://stackoverflow.com/questions/33883609/opengl-linker-error-linking-with-uncompiled-shader
|
|
Shader ourShader(constants::VERTEX_SHADER_TEXTURE_FILENAME, constants::FRAGMENT_SHADER_TEXTURE_FILENAME);
|
|
|
|
unsigned int VAO = generateBindVAO();
|
|
unsigned int VBO = copyVerticesMemory(vertices, verticesSize, GL_ARRAY_BUFFER);
|
|
unsigned int EBO = copyVerticesMemory(indices, indicesSize, GL_ELEMENT_ARRAY_BUFFER);
|
|
|
|
configureVertexAttribute(true, true);
|
|
|
|
unsigned int texture1 = loadAndCreateTexture("assets/Preview.png", GL_RGBA, true);
|
|
// unsigned int texture2 = loadAndCreateTexture("assets/awesomeface.png", GL_RGBA, false);
|
|
|
|
|
|
activateAndBindTextures(texture1, GL_TEXTURE0);
|
|
// activateAndBindTextures(texture2, GL_TEXTURE1);
|
|
|
|
|
|
ourShader.use(); // don't forget to activate/use the shader before setting uniforms!
|
|
// either set it manually like so:
|
|
glUniform1i(glGetUniformLocation(ourShader.ID, "texture1"), 0);
|
|
// or set it via the texture class
|
|
ourShader.setInt("texture2", 1);
|
|
|
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
|
|
drawFigureReturn newReturn;
|
|
newReturn.success = 0;
|
|
newReturn.VAO = VAO;
|
|
newReturn.VBO = VBO;
|
|
newReturn.EBO = EBO;
|
|
return newReturn;
|
|
}
|
|
|
|
void doDrawElements(const unsigned int shaderProgram, const unsigned int vertexArrayObject, const GLenum drawArrayMode, const GLenum drawType, const int numberOfElementsToDraw)
|
|
{
|
|
glUseProgram(shaderProgram);
|
|
glBindVertexArray(vertexArrayObject);
|
|
glDrawElements(drawArrayMode, numberOfElementsToDraw, drawType, 0);
|
|
glBindVertexArray(0);
|
|
}
|
|
|
|
void updateUniformColor(const unsigned int shaderProgram, const GLchar* uniformName)
|
|
{
|
|
// update the uniform color
|
|
const float timeValue = glfwGetTime(); // retrieve running time
|
|
const float greenValue = sin(timeValue) / 2.0f + 0.5f; // vary the color from 0.0 to 1.0 using sin
|
|
const int vertexColorLocation = glGetUniformLocation(shaderProgram, uniformName); // query the location of our uniform
|
|
if(vertexColorLocation != -1) // if glGetUniformLocation returns -1 it could not find the location
|
|
{
|
|
glUniform4f(vertexColorLocation, 0.0f, greenValue, 0.0f, 1.0f); /* we set the uniform value using glUniform4f
|
|
4f means that it expects 4 floats
|
|
few of possible postfixes:
|
|
f: the function expects a float as its value.
|
|
i: the function expects an int as its value.
|
|
ui: the function expects an unsigned int as its value.
|
|
3f: the function expects 3 floats as its value.
|
|
fv: the function expects a float vector/array as its value.
|
|
*/
|
|
}
|
|
}
|
|
|
|
void doDrawArrays(const unsigned int shaderProgram, const unsigned int vertexArrayObject, const GLenum drawArrayMode, const int firstIndex, const unsigned int numberOfIndicesToBeRendered)
|
|
{
|
|
// use shader program to render an object
|
|
glUseProgram(shaderProgram);
|
|
updateUniformColor(shaderProgram, "ourColor");
|
|
glBindVertexArray(vertexArrayObject);
|
|
// From left:
|
|
// primitive type we want to draw
|
|
// starting index of vertex array
|
|
// how many vertices we want to draw
|
|
glDrawArrays(drawArrayMode, firstIndex, numberOfIndicesToBeRendered);
|
|
}
|
|
|
|
int drawTexture() {
|
|
// we added new vertex attribute and need to inform opengl that we done so
|
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
|
|
glEnableVertexAttribArray(2);
|
|
return -1;
|
|
}
|
|
|
|
#endif |