mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-12 02:40:00 +01:00
Redefine shading classes: glsl program is now separate from shader
class, which are derived to manage uniform variables.
This commit is contained in:
@@ -184,6 +184,21 @@ message(STATUS "Compiling 'TinyFileDialog' from https://github.com/native-toolki
|
|||||||
# Application
|
# Application
|
||||||
#
|
#
|
||||||
|
|
||||||
|
#
|
||||||
|
# SCENE GRAPH
|
||||||
|
#
|
||||||
|
set(SSG_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/ext/ssg)
|
||||||
|
set(SSG_SRCS
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/ext/ssg/ssg.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/ext/ssg/Texture.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/ext/ssg/TextureLoader.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/ext/ssg/ObjLoader.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/ext/ssg/InitShader.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/ext/ssg/FrameBufferObject.cpp
|
||||||
|
)
|
||||||
|
add_library(SSG "${SSG_SRCS}")
|
||||||
|
|
||||||
|
|
||||||
# Setup the environment
|
# Setup the environment
|
||||||
include_directories(
|
include_directories(
|
||||||
${GSTREAMER_INCLUDE_DIR}
|
${GSTREAMER_INCLUDE_DIR}
|
||||||
@@ -203,6 +218,7 @@ include_directories(
|
|||||||
${TINYFD_INCLUDE_DIR}
|
${TINYFD_INCLUDE_DIR}
|
||||||
${STB_INCLUDE_DIR}
|
${STB_INCLUDE_DIR}
|
||||||
${DIRENT_INCLUDE_DIR}
|
${DIRENT_INCLUDE_DIR}
|
||||||
|
${SSG_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -211,6 +227,7 @@ set(VMIX_SRCS
|
|||||||
main.cpp
|
main.cpp
|
||||||
Log.cpp
|
Log.cpp
|
||||||
Shader.cpp
|
Shader.cpp
|
||||||
|
ImageShader.cpp
|
||||||
Settings.cpp
|
Settings.cpp
|
||||||
Resource.cpp
|
Resource.cpp
|
||||||
FileDialog.cpp
|
FileDialog.cpp
|
||||||
@@ -271,6 +288,7 @@ target_link_libraries(${VMIX_BINARY} LINK_PRIVATE
|
|||||||
TINYXML2
|
TINYXML2
|
||||||
TINYFD
|
TINYFD
|
||||||
IMGUI
|
IMGUI
|
||||||
|
SSG
|
||||||
vmix::rc
|
vmix::rc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
43
ImageShader.cpp
Normal file
43
ImageShader.cpp
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#include "defines.h"
|
||||||
|
#include "ImageShader.h"
|
||||||
|
|
||||||
|
|
||||||
|
ImageShader::ImageShader()
|
||||||
|
{
|
||||||
|
vertex_file = "shaders/texture-shader.vs";
|
||||||
|
fragment_file = "shaders/texture-shader.fs";
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageShader::use()
|
||||||
|
{
|
||||||
|
Shader::use();
|
||||||
|
|
||||||
|
// set image uniforms
|
||||||
|
if (imageshader_changed) {
|
||||||
|
program_.setUniform("brightness", brightness);
|
||||||
|
program_.setUniform("contrast", contrast);
|
||||||
|
imageshader_changed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ImageShader::reset()
|
||||||
|
{
|
||||||
|
Shader::reset();
|
||||||
|
|
||||||
|
brightness = 0.f;
|
||||||
|
contrast = 0.f;
|
||||||
|
imageshader_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageShader::setBrightness(float v)
|
||||||
|
{
|
||||||
|
brightness = CLAMP(v, -1.f, 1.f);
|
||||||
|
imageshader_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImageShader::setContrast(float v)
|
||||||
|
{
|
||||||
|
contrast = CLAMP(v, -1.f, 1.f);
|
||||||
|
imageshader_changed = true;
|
||||||
|
}
|
||||||
25
ImageShader.h
Normal file
25
ImageShader.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#ifndef IMAGESHADER_H
|
||||||
|
#define IMAGESHADER_H
|
||||||
|
|
||||||
|
#include "Shader.h"
|
||||||
|
|
||||||
|
class ImageShader : public Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
ImageShader();
|
||||||
|
virtual ~ImageShader() {}
|
||||||
|
|
||||||
|
virtual void use();
|
||||||
|
virtual void reset();
|
||||||
|
|
||||||
|
void setBrightness(float v);
|
||||||
|
void setContrast(float v);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float brightness;
|
||||||
|
float contrast;
|
||||||
|
bool imageshader_changed;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IMAGESHADER_H
|
||||||
114
Scene.h
Normal file
114
Scene.h
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#ifndef SCENE_H
|
||||||
|
#define SCENE_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/matrix_access.hpp>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "Shader.h"
|
||||||
|
|
||||||
|
class Visitor;
|
||||||
|
|
||||||
|
|
||||||
|
// Base virtual class for all Node types
|
||||||
|
class Node {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Node() : parent_(), visible_(true), count_(0), localToWorld_(glm::mat4()), worldToLocal_(glm::mat4()) {}
|
||||||
|
virtual ~ModelNode() {}
|
||||||
|
|
||||||
|
virtual void init() = 0;
|
||||||
|
virtual void update( float dt ) = 0;
|
||||||
|
virtual void draw ( glm::mat4 modelview, glm::mat4 projection) = 0;
|
||||||
|
virtual void Accept(Visitor& dispatcher) = 0;
|
||||||
|
|
||||||
|
virtual glm::mat4 getWorldToLocalMatrix() {return worldToLocal_;}
|
||||||
|
virtual glm::mat4 getLocalToWorldMatrix() {return localToWorld_;}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Node* parent_;
|
||||||
|
bool visible_;
|
||||||
|
glm::mat4 worldToLocal_;
|
||||||
|
glm::mat4 localToWorld_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Forward declare different kind of Node
|
||||||
|
class Primitive;
|
||||||
|
class Group;
|
||||||
|
|
||||||
|
// Declares the interface for the visitors
|
||||||
|
class Visitor {
|
||||||
|
public:
|
||||||
|
// Declare overloads for each kind of Node to visit
|
||||||
|
virtual void Visit(Primitive& file) = 0;
|
||||||
|
virtual void Visit(Group& file) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Primitive : public Node {
|
||||||
|
|
||||||
|
public:
|
||||||
|
Primitive() : Node(), effect(nullptr), vao_(0), arrayBuffer_(0), elementBuffer_(0), drawingPrimitive_(0) {}
|
||||||
|
virtual ~Primitive();
|
||||||
|
|
||||||
|
virtual void init ();
|
||||||
|
virtual void update ( float dt );
|
||||||
|
virtual void draw ( glm::mat4 modelview, glm::mat4 projection);
|
||||||
|
virtual void Accept(Visitor& dispatcher) override {
|
||||||
|
dispatcher.Visit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual glm::mat4 getWorldToLocalMatrix();
|
||||||
|
virtual glm::mat4 getLocalToWorldMatrix();
|
||||||
|
|
||||||
|
virtual void setEffect( Effect* e );
|
||||||
|
virtual void setDrawingPrimitive ( GLuint prim );
|
||||||
|
virtual void generateAndLoadArrayBuffer();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Effect* effect_;
|
||||||
|
unsigned int vao_;
|
||||||
|
unsigned int arrayBuffer_;
|
||||||
|
unsigned int elementBuffer_;
|
||||||
|
unsigned int drawingPrimitive_;
|
||||||
|
std::vector<glm::vec3> points_;
|
||||||
|
std::vector<glm::vec3> normals_;
|
||||||
|
std::vector<unsigned int> indices_;
|
||||||
|
std::vector<glm::vec2> texCoords_;
|
||||||
|
std::vector<glm::vec3> colors_;
|
||||||
|
void deleteGLBuffers_();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Group : public Node {
|
||||||
|
|
||||||
|
public:
|
||||||
|
Group() : Node() {}
|
||||||
|
virtual ~Group();
|
||||||
|
|
||||||
|
virtual void init ();
|
||||||
|
virtual void update ( float dt );
|
||||||
|
virtual void draw ( glm::mat4 modelview, glm::mat4 projection);
|
||||||
|
virtual void Accept(Visitor& dispatcher)override {
|
||||||
|
dispatcher.Visit(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual glm::mat4 getWorldToLocalMatrix();
|
||||||
|
virtual glm::mat4 getLocalToWorldMatrix();
|
||||||
|
|
||||||
|
virtual void addChild ( Node *child );
|
||||||
|
virtual Node* getChild ( int i );
|
||||||
|
virtual int numChildren();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector< Node* > children_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // SCENE_H
|
||||||
138
Shader.cpp
138
Shader.cpp
@@ -1,5 +1,7 @@
|
|||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
#include "Resource.h"
|
#include "Resource.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "RenderingManager.h"
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -7,27 +9,38 @@
|
|||||||
|
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/ext/vector_float4.hpp>
|
||||||
|
#include <glm/ext/matrix_float4x4.hpp>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#define GLM_ENABLE_EXPERIMENTAL
|
#define GLM_ENABLE_EXPERIMENTAL
|
||||||
#include <glm/gtx/string_cast.hpp>
|
#include <glm/gtx/string_cast.hpp>
|
||||||
|
|
||||||
Shader::Shader() {
|
// Globals
|
||||||
|
ShadingProgram *ShadingProgram::_currentProgram = nullptr;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ShadingProgram::ShadingProgram() : vertex_id_(0), fragment_id_(0), id_(0)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::load(const std::string& vertex_file, const std::string& fragment_file) {
|
void ShadingProgram::init(const std::string& vertex_code, const std::string& fragment_code)
|
||||||
|
{
|
||||||
init(Resource::getText(vertex_file), Resource::getText(fragment_file));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shader::init(const std::string& vertex_code, const std::string& fragment_code) {
|
|
||||||
vertex_code_ = vertex_code;
|
vertex_code_ = vertex_code;
|
||||||
fragment_code_ = fragment_code;
|
fragment_code_ = fragment_code;
|
||||||
compile();
|
compile();
|
||||||
link();
|
link();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::compile() {
|
bool ShadingProgram::initialized()
|
||||||
|
{
|
||||||
|
return (id_ != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShadingProgram::compile()
|
||||||
|
{
|
||||||
const char* vcode = vertex_code_.c_str();
|
const char* vcode = vertex_code_.c_str();
|
||||||
vertex_id_ = glCreateShader(GL_VERTEX_SHADER);
|
vertex_id_ = glCreateShader(GL_VERTEX_SHADER);
|
||||||
glShaderSource(vertex_id_, 1, &vcode, NULL);
|
glShaderSource(vertex_id_, 1, &vcode, NULL);
|
||||||
@@ -37,10 +50,12 @@ void Shader::compile() {
|
|||||||
fragment_id_ = glCreateShader(GL_FRAGMENT_SHADER);
|
fragment_id_ = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
glShaderSource(fragment_id_, 1, &fcode, NULL);
|
glShaderSource(fragment_id_, 1, &fcode, NULL);
|
||||||
glCompileShader(fragment_id_);
|
glCompileShader(fragment_id_);
|
||||||
|
|
||||||
checkCompileErr();
|
checkCompileErr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::link() {
|
void ShadingProgram::link()
|
||||||
|
{
|
||||||
id_ = glCreateProgram();
|
id_ = glCreateProgram();
|
||||||
glAttachShader(id_, vertex_id_);
|
glAttachShader(id_, vertex_id_);
|
||||||
glAttachShader(id_, fragment_id_);
|
glAttachShader(id_, fragment_id_);
|
||||||
@@ -50,74 +65,135 @@ void Shader::link() {
|
|||||||
glDeleteShader(fragment_id_);
|
glDeleteShader(fragment_id_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::use() {
|
bool ShadingProgram::use()
|
||||||
|
{
|
||||||
|
if (_currentProgram == nullptr || _currentProgram != this) {
|
||||||
|
_currentProgram = this;
|
||||||
glUseProgram(id_);
|
glUseProgram(id_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::enduse() {
|
void ShadingProgram::enduse()
|
||||||
|
{
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
|
_currentProgram = nullptr ;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Shader::setUniform<int>(const std::string& name, int val) {
|
void ShadingProgram::setUniform<int>(const std::string& name, int val) {
|
||||||
glUniform1i(glGetUniformLocation(id_, name.c_str()), val);
|
glUniform1i(glGetUniformLocation(id_, name.c_str()), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Shader::setUniform<bool>(const std::string& name, bool val) {
|
void ShadingProgram::setUniform<bool>(const std::string& name, bool val) {
|
||||||
glUniform1i(glGetUniformLocation(id_, name.c_str()), val);
|
glUniform1i(glGetUniformLocation(id_, name.c_str()), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Shader::setUniform<float>(const std::string& name, float val) {
|
void ShadingProgram::setUniform<float>(const std::string& name, float val) {
|
||||||
glUniform1f(glGetUniformLocation(id_, name.c_str()), val);
|
glUniform1f(glGetUniformLocation(id_, name.c_str()), val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Shader::setUniform<glm::mat4>(const std::string& name, glm::mat4 val) {
|
void ShadingProgram::setUniform<float>(const std::string& name, float val1, float val2) {
|
||||||
glm::mat4 m(val);
|
|
||||||
// std::cout << glm::to_string(m) << std::endl;
|
|
||||||
glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, glm::value_ptr(m));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<>
|
|
||||||
void Shader::setUniform<float>(const std::string& name, float val1, float val2) {
|
|
||||||
glUniform2f(glGetUniformLocation(id_, name.c_str()), val1, val2);
|
glUniform2f(glGetUniformLocation(id_, name.c_str()), val1, val2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void Shader::setUniform<float>(const std::string& name, float val1, float val2, float val3) {
|
void ShadingProgram::setUniform<float>(const std::string& name, float val1, float val2, float val3) {
|
||||||
glUniform3f(glGetUniformLocation(id_, name.c_str()), val1, val2, val3);
|
glUniform3f(glGetUniformLocation(id_, name.c_str()), val1, val2, val3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void ShadingProgram::setUniform<glm::vec4>(const std::string& name, glm::vec4 val) {
|
||||||
|
glm::vec4 v(val);
|
||||||
|
glUniform4fv(glGetUniformLocation(id_, name.c_str()), 1, glm::value_ptr(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<>
|
||||||
|
void ShadingProgram::setUniform<glm::mat4>(const std::string& name, glm::mat4 val) {
|
||||||
|
glm::mat4 m(val);
|
||||||
|
glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, glm::value_ptr(m));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// template<>
|
// template<>
|
||||||
// void Shader::setUniform<float*>(const std::string& name, float* val) {
|
// void ShadingProgram::setUniform<float*>(const std::string& name, float* val) {
|
||||||
// glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, val);
|
// glUniformMatrix4fv(glGetUniformLocation(id_, name.c_str()), 1, GL_FALSE, val);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
void Shader::checkCompileErr() {
|
void ShadingProgram::checkCompileErr()
|
||||||
|
{
|
||||||
int success;
|
int success;
|
||||||
char infoLog[1024];
|
char infoLog[1024];
|
||||||
glGetShaderiv(vertex_id_, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(vertex_id_, GL_COMPILE_STATUS, &success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
glGetShaderInfoLog(vertex_id_, 1024, NULL, infoLog);
|
glGetShaderInfoLog(vertex_id_, 1024, NULL, infoLog);
|
||||||
std::cout << "Error compiling Vertex Shader:\n" << infoLog << std::endl;
|
Log::Warning("Error compiling Vertex ShadingProgram:\n%s \n%s", infoLog, vertex_code_);
|
||||||
std::cout << vertex_code_ << std::endl;
|
|
||||||
}
|
}
|
||||||
glGetShaderiv(fragment_id_, GL_COMPILE_STATUS, &success);
|
glGetShaderiv(fragment_id_, GL_COMPILE_STATUS, &success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
glGetShaderInfoLog(fragment_id_, 1024, NULL, infoLog);
|
glGetShaderInfoLog(fragment_id_, 1024, NULL, infoLog);
|
||||||
std::cout << "Error compiling Fragment Shader:\n" << infoLog << std::endl;
|
Log::Warning("Error compiling Fragment ShadingProgram:\n%s \n%s", infoLog, vertex_code_);
|
||||||
std::cout << fragment_code_ << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shader::checkLinkingErr() {
|
void ShadingProgram::checkLinkingErr()
|
||||||
|
{
|
||||||
int success;
|
int success;
|
||||||
char infoLog[1024];
|
char infoLog[1024];
|
||||||
glGetProgramiv(id_, GL_LINK_STATUS, &success);
|
glGetProgramiv(id_, GL_LINK_STATUS, &success);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
glGetProgramInfoLog(id_, 1024, NULL, infoLog);
|
glGetProgramInfoLog(id_, 1024, NULL, infoLog);
|
||||||
std::cout << "Error Linking Shader Program:\n" << infoLog << std::endl;
|
Log::Warning("Error linking ShadingProgram Program:\n%s \n%s", infoLog);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Shader::Shader()
|
||||||
|
{
|
||||||
|
vertex_file = "shaders/simple-shader.vs";
|
||||||
|
fragment_file = "shaders/simple-shader.fs";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::use()
|
||||||
|
{
|
||||||
|
// initialization on first use
|
||||||
|
if (!program_.initialized()) {
|
||||||
|
program_.init(Resource::getText(vertex_file), Resource::getText(fragment_file));
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use program and set uniforms
|
||||||
|
// - if the program was changed, we should set the uniforms
|
||||||
|
// - or if the shader values were changed, we should set the uniforms
|
||||||
|
if (program_.use() || shader_changed) {
|
||||||
|
program_.setUniform("projection", Rendering::manager().Projection());
|
||||||
|
program_.setUniform("modelview", modelview);
|
||||||
|
program_.setUniform("color", color);
|
||||||
|
shader_changed = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Shader::reset()
|
||||||
|
{
|
||||||
|
modelview = glm::identity<glm::mat4>();
|
||||||
|
color = glm::vec4(1.f, 1.f, 1.f, 1.f);
|
||||||
|
shader_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Shader::setModelview(glm::mat4 m)
|
||||||
|
{
|
||||||
|
modelview = m;
|
||||||
|
shader_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shader::setColor(glm::vec4 c)
|
||||||
|
{
|
||||||
|
color = c;
|
||||||
|
shader_changed = true;
|
||||||
|
}
|
||||||
|
|||||||
32
Shader.h
32
Shader.h
@@ -3,14 +3,15 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
class Shader
|
class ShadingProgram
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Shader();
|
ShadingProgram();
|
||||||
void load(const std::string& vertex_rsc, const std::string& fragment_rsc);
|
|
||||||
void init(const std::string& vertex_code, const std::string& fragment_code);
|
void init(const std::string& vertex_code, const std::string& fragment_code);
|
||||||
void use();
|
bool initialized();
|
||||||
|
bool use();
|
||||||
template<typename T> void setUniform(const std::string& name, T val);
|
template<typename T> void setUniform(const std::string& name, T val);
|
||||||
template<typename T> void setUniform(const std::string& name, T val1, T val2);
|
template<typename T> void setUniform(const std::string& name, T val1, T val2);
|
||||||
template<typename T> void setUniform(const std::string& name, T val1, T val2, T val3);
|
template<typename T> void setUniform(const std::string& name, T val1, T val2, T val3);
|
||||||
@@ -26,6 +27,29 @@ private:
|
|||||||
std::string vertex_code_;
|
std::string vertex_code_;
|
||||||
std::string fragment_code_;
|
std::string fragment_code_;
|
||||||
|
|
||||||
|
static ShadingProgram *_currentProgram;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Shader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Shader();
|
||||||
|
virtual ~Shader() {}
|
||||||
|
|
||||||
|
virtual void use();
|
||||||
|
virtual void reset();
|
||||||
|
|
||||||
|
void setModelview(glm::mat4 m);
|
||||||
|
void setColor(glm::vec4 c);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
glm::mat4 modelview;
|
||||||
|
glm::vec4 color;
|
||||||
|
|
||||||
|
bool shader_changed;
|
||||||
|
ShadingProgram program_;
|
||||||
|
std::string vertex_file;
|
||||||
|
std::string fragment_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* __SHADER_H_ */
|
#endif /* __SHADER_H_ */
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#define ABS_DIFF(a, b) ( (a) < (b) ? (b - a) : (a - b) )
|
#define ABS_DIFF(a, b) ( (a) < (b) ? (b - a) : (a - b) )
|
||||||
#define SIGN(a) (((a) < 0) ? -1.0 : 1.0)
|
#define SIGN(a) (((a) < 0) ? -1.0 : 1.0)
|
||||||
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
||||||
#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
|
|
||||||
#define EPSILON 0.00001
|
#define EPSILON 0.00001
|
||||||
#define LOG100(val) (50.0/log(10.0)*log((float)val + 1.0))
|
#define LOG100(val) (50.0/log(10.0)*log((float)val + 1.0))
|
||||||
#define EXP100(val) (exp(log(10.0)/50.0*(float)(val))-1.0)
|
#define EXP100(val) (exp(log(10.0)/50.0*(float)(val))-1.0)
|
||||||
|
|||||||
120
main.cpp
120
main.cpp
@@ -8,6 +8,10 @@
|
|||||||
// Opengl
|
// Opengl
|
||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
#include <glm/glm.hpp>
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/ext/vector_float3.hpp>
|
||||||
|
#include <glm/ext/vector_float4.hpp>
|
||||||
|
#include <glm/ext/matrix_float4x4.hpp>
|
||||||
|
#include <glm/ext/matrix_transform.hpp>
|
||||||
|
|
||||||
// GStreamer
|
// GStreamer
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
@@ -16,7 +20,7 @@
|
|||||||
|
|
||||||
// vmix
|
// vmix
|
||||||
#include "defines.h"
|
#include "defines.h"
|
||||||
#include "Shader.h"
|
#include "ImageShader.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
#include "Resource.h"
|
#include "Resource.h"
|
||||||
#include "RenderingManager.h"
|
#include "RenderingManager.h"
|
||||||
@@ -31,38 +35,51 @@
|
|||||||
|
|
||||||
MediaPlayer testmedia;
|
MediaPlayer testmedia;
|
||||||
MediaPlayer testmedia2("testmedia2");
|
MediaPlayer testmedia2("testmedia2");
|
||||||
Shader rendering_shader;
|
ImageShader rendering_shader;
|
||||||
unsigned int vbo, vao, ebo;
|
unsigned int vbo, vao, ebo;
|
||||||
float texturear = 1.0;
|
float texturear = 1.0;
|
||||||
GLuint textureimagepng = 0;
|
GLuint textureimagepng = 0;
|
||||||
|
|
||||||
void create_square(unsigned int &vbo, unsigned int &vao, unsigned int &ebo)
|
void create_square(unsigned int &vbo, unsigned int &vao, unsigned int &ebo)
|
||||||
{
|
{
|
||||||
|
// create the triangles
|
||||||
// create the triangle
|
|
||||||
float _vertices[] = {
|
float _vertices[] = {
|
||||||
-1.f, -1.f, 0.0f, // position vertex 3
|
-1.f, -1.f, 0.f, // position vertex 3
|
||||||
0.0f, 1.0f, 0.0f, // uv vertex 3
|
1.f, 0.f, 1.f, // color vertex 3
|
||||||
-1.f, 1.f, 0.0f, // position vertex 0
|
0.f, 1.f, 0.f, // uv vertex 3
|
||||||
0.0f, 0.0f, 0.0f, // uv vertex 0
|
-1.f, 1.f, 0.f, // position vertex 0
|
||||||
1.f, -1.f, 0.0f, // position vertex 2
|
1.f, 1.f, 0.f, // color vertex 0
|
||||||
1.0f, 1.0f, 0.0f, // uv vertex 2
|
0.f, 0.f, 0.f, // uv vertex 0
|
||||||
1.f, 1.f, 0.0f, // position vertex 1
|
1.f, -1.f, 0.f, // position vertex 2
|
||||||
1.0f, 0.0f, 0.0f, // uv vertex 1
|
1.f, 1.f, 1.f, // color vertex 2
|
||||||
|
1.f, 1.f, 0.f, // uv vertex 2
|
||||||
|
1.f, 1.f, 0.f, // position vertex 1
|
||||||
|
0.f, 1.f, 1.f, // color vertex 1
|
||||||
|
1.f, 0.f, 0.f, // uv vertex 1
|
||||||
};
|
};
|
||||||
unsigned int _indices[] = { 0, 1, 2, 3 };
|
unsigned int _indices[] = { 0, 1, 2, 3 };
|
||||||
|
|
||||||
|
// create the opengl objects
|
||||||
glGenVertexArrays(1, &vao);
|
glGenVertexArrays(1, &vao);
|
||||||
glGenBuffers(1, &vbo);
|
glGenBuffers(1, &vbo);
|
||||||
glGenBuffers(1, &ebo);
|
glGenBuffers(1, &ebo);
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
|
|
||||||
|
// bind vertext array and its buffer
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_indices), _indices, GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(_indices), _indices, GL_STATIC_DRAW);
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0);
|
|
||||||
|
// explain how to read attributes 1, 2 and 3
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void *)0);
|
||||||
glEnableVertexAttribArray(0);
|
glEnableVertexAttribArray(0);
|
||||||
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)(3 * sizeof(float)));
|
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void *)(3 * sizeof(float)));
|
||||||
glEnableVertexAttribArray(1);
|
glEnableVertexAttribArray(1);
|
||||||
|
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void *)(6 * sizeof(float)));
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
|
// done
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
@@ -106,23 +123,23 @@ void drawMediaBackgound()
|
|||||||
if ( !testmedia2.isOpen() )
|
if ( !testmedia2.isOpen() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// rendering TRIANGLE geometries
|
//
|
||||||
|
// RENDER SOURCE
|
||||||
|
//
|
||||||
|
// use the shader
|
||||||
rendering_shader.use();
|
rendering_shader.use();
|
||||||
rendering_shader.setUniform("render_projection", Rendering::manager().Projection());
|
// use the media
|
||||||
|
|
||||||
testmedia2.Update();
|
testmedia2.Update();
|
||||||
testmedia2.Bind();
|
testmedia2.Bind();
|
||||||
|
// draw the vertex array
|
||||||
// rendering_shader.setUniform("aspectratio", texturear);
|
|
||||||
// glBindTexture(GL_TEXTURE_2D, textureimagepng);
|
|
||||||
|
|
||||||
glBindVertexArray(vao);
|
glBindVertexArray(vao);
|
||||||
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
|
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_INT, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
// render TRIANGLE GUI
|
//
|
||||||
|
// GUI to control SOURCE
|
||||||
|
//
|
||||||
{
|
{
|
||||||
ImGui::Begin("Image properties");
|
ImGui::Begin("Image properties");
|
||||||
|
|
||||||
@@ -146,6 +163,13 @@ void drawMediaBackgound()
|
|||||||
ImGui::SameLine(0, 10);
|
ImGui::SameLine(0, 10);
|
||||||
ImGui::SliderFloat("scale", &scale, 0.1f, 10.f, "%.3f", 3.f);
|
ImGui::SliderFloat("scale", &scale, 0.1f, 10.f, "%.3f", 3.f);
|
||||||
|
|
||||||
|
glm::mat4 modelview;
|
||||||
|
glm::mat4 View = glm::translate(glm::identity<glm::mat4>(), glm::vec3(translation[0], translation[1], 0.f));
|
||||||
|
View = glm::rotate(View, rotation, glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
|
glm::mat4 Model = glm::scale(glm::identity<glm::mat4>(), glm::vec3(scale * testmedia2.AspectRatio(), scale, scale));
|
||||||
|
modelview = View * Model;
|
||||||
|
rendering_shader.setModelview(modelview);
|
||||||
|
|
||||||
// color picker
|
// color picker
|
||||||
static float color[4] = { 1.0f,1.0f,1.0f,1.0f };
|
static float color[4] = { 1.0f,1.0f,1.0f,1.0f };
|
||||||
if (ImGuiToolkit::ButtonIcon(16, 8)) {
|
if (ImGuiToolkit::ButtonIcon(16, 8)) {
|
||||||
@@ -153,48 +177,34 @@ void drawMediaBackgound()
|
|||||||
color[1] = 1.f;
|
color[1] = 1.f;
|
||||||
color[2] = 1.f;
|
color[2] = 1.f;
|
||||||
color[3] = 1.f;
|
color[3] = 1.f;
|
||||||
|
rendering_shader.setColor( glm::vec4(color[0], color[1], color[2], color[3]) ) ;
|
||||||
}
|
}
|
||||||
ImGui::SameLine(0, 10);
|
ImGui::SameLine(0, 10);
|
||||||
ImGui::ColorEdit3("color", color);
|
if ( ImGui::ColorEdit3("color", color) ) {
|
||||||
|
rendering_shader.setColor( glm::vec4(color[0], color[1], color[2], color[3]) ) ;
|
||||||
|
}
|
||||||
|
|
||||||
static float brightness = 0.0;
|
static float brightness = 0.0;
|
||||||
if (ImGuiToolkit::ButtonIcon(4, 1))
|
if (ImGuiToolkit::ButtonIcon(4, 1)) {
|
||||||
brightness = 0.f;
|
brightness = 0.f;
|
||||||
|
rendering_shader.setBrightness(brightness);
|
||||||
|
}
|
||||||
ImGui::SameLine(0, 10);
|
ImGui::SameLine(0, 10);
|
||||||
ImGui::SliderFloat("brightness", &brightness, -1.0, 1.0, "%.3f", 2.f);
|
if ( ImGui::SliderFloat("brightness", &brightness, -1.0, 1.0, "%.3f", 2.f) )
|
||||||
|
rendering_shader.setBrightness(brightness);
|
||||||
|
|
||||||
static float contrast = 0.0;
|
static float contrast = 0.0;
|
||||||
if (ImGuiToolkit::ButtonIcon(2, 1))
|
if (ImGuiToolkit::ButtonIcon(2, 1)) {
|
||||||
contrast = 0.f;
|
contrast = 0.f;
|
||||||
|
rendering_shader.setContrast(contrast);
|
||||||
|
}
|
||||||
ImGui::SameLine(0, 10);
|
ImGui::SameLine(0, 10);
|
||||||
ImGui::SliderFloat("contrast", &contrast, -1.0, 1.0, "%.3f", 2.f);
|
if (ImGui::SliderFloat("contrast", &contrast, -1.0, 1.0, "%.3f", 2.f) )
|
||||||
|
rendering_shader.setContrast(contrast);
|
||||||
// pass the parameters to the shader
|
|
||||||
rendering_shader.setUniform("scale", scale);
|
|
||||||
rendering_shader.setUniform("rotation", rotation);
|
|
||||||
rendering_shader.setUniform("translation", translation[0], translation[1]);
|
|
||||||
rendering_shader.setUniform("color", color[0], color[1], color[2]);
|
|
||||||
rendering_shader.setUniform("brightness", brightness);
|
|
||||||
rendering_shader.setUniform("contrast", contrast);
|
|
||||||
rendering_shader.setUniform("aspectratio", testmedia2.AspectRatio());
|
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
// // add gui elements to vmix main window
|
|
||||||
// ImGui::Begin("v-mix");
|
|
||||||
// static float zoom = 0.3f;
|
|
||||||
// if (ImGuiToolkit::ButtonIcon(5, 7))
|
|
||||||
// zoom = 0.3f;
|
|
||||||
// ImGui::SameLine(0, 10);
|
|
||||||
// if (ImGui::SliderFloat("zoom", &zoom, 0.1f, 10.f, "%.4f", 3.f))
|
|
||||||
// UserInterface::Log("Zoom %f", zoom);
|
|
||||||
// rendering_shader.setUniform("render_zoom", zoom);
|
|
||||||
// ImGui::End();
|
|
||||||
|
|
||||||
|
|
||||||
Shader::enduse();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawMediaPlayer()
|
void drawMediaPlayer()
|
||||||
@@ -381,9 +391,10 @@ int main(int, char**)
|
|||||||
// 2
|
// 2
|
||||||
// testmedia2.Open("file:///home/bhbn/Images/Butterfly.gif");
|
// testmedia2.Open("file:///home/bhbn/Images/Butterfly.gif");
|
||||||
// testmedia2.Open("file:///home/bhbn/Images/Scan-090614-0022.jpg");
|
// testmedia2.Open("file:///home/bhbn/Images/Scan-090614-0022.jpg");
|
||||||
testmedia2.Open("file:///home/bhbn/Images/svg/abstract.svg");
|
// testmedia2.Open("file:///home/bhbn/Images/svg/abstract.svg");
|
||||||
|
testmedia2.Open("file:///home/bhbn/Videos/iss.mov");
|
||||||
// testmedia2.Open("file:///home/bhbn/Images/4k/colors-3840x2160-splash-4k-18458.jpg");
|
// testmedia2.Open("file:///home/bhbn/Images/4k/colors-3840x2160-splash-4k-18458.jpg");
|
||||||
// testmedia2.Open("file:///home/bhbn/Videos/Upgrade.2018.720p.AMZN.WEB-DL.DDP5.1.H.264-NTG.m4v");
|
// testmedia2.Open("file:///home/bhbn/Videos/Upgrade.2018.720p.AMZN.WEB-DL.DDP5.1.H.264-NTG.m4v");
|
||||||
testmedia2.Play(true);
|
testmedia2.Play(true);
|
||||||
// create our geometries
|
// create our geometries
|
||||||
create_square(vbo, vao, ebo);
|
create_square(vbo, vao, ebo);
|
||||||
@@ -393,9 +404,6 @@ int main(int, char**)
|
|||||||
// // load an image
|
// // load an image
|
||||||
// textureimagepng = loadPNG("/home/bhbn/Videos/iss_snap.png", &texturear);
|
// textureimagepng = loadPNG("/home/bhbn/Videos/iss_snap.png", &texturear);
|
||||||
|
|
||||||
// init shader
|
|
||||||
rendering_shader.load("shaders/texture-shader.vs", "shaders/texture-shader.fs");
|
|
||||||
|
|
||||||
UserInterface::manager().OpenTextEditor( Resource::getText("shaders/texture-shader.fs") );
|
UserInterface::manager().OpenTextEditor( Resource::getText("shaders/texture-shader.fs") );
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -3,9 +3,10 @@
|
|||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
in vec3 vertexColor;
|
in vec3 vertexColor;
|
||||||
uniform vec3 color;
|
|
||||||
|
uniform vec4 color;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
FragColor = vec4(color*vertexColor,1.0);
|
FragColor = color * vec4(vertexColor,1.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,20 +5,14 @@ layout (location = 1) in vec3 color;
|
|||||||
|
|
||||||
out vec3 vertexColor;
|
out vec3 vertexColor;
|
||||||
|
|
||||||
uniform float rotation;
|
uniform mat4 modelview;
|
||||||
uniform vec2 translation;
|
uniform mat4 projection;
|
||||||
uniform float aspectratio;
|
|
||||||
uniform float zoom;
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
mat4 projection = mat4( zoom, 0.0, 0.0, 0.0,
|
vec4 pos = modelview * vec4(position.xyz, 1.0);
|
||||||
0.0, zoom * aspectratio, 0.0, 0.0,
|
|
||||||
0.0, 0.0, -1.0, 0.0,
|
// output
|
||||||
0.0, 0.0, 0.0, 1.0);
|
gl_Position = projection * pos;
|
||||||
vec2 rotated_pos;
|
|
||||||
rotated_pos.x = translation.x + position.x*cos(rotation) - position.y*sin(rotation);
|
|
||||||
rotated_pos.y = translation.y + position.x*sin(rotation) + position.y*cos(rotation);
|
|
||||||
gl_Position = projection * vec4(rotated_pos.x, rotated_pos.y, position.z, 1.0);
|
|
||||||
vertexColor = color;
|
vertexColor = color;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
out vec4 FragColor;
|
out vec4 FragColor;
|
||||||
|
|
||||||
uniform sampler2D sourceTexture;
|
|
||||||
in vec3 vertexUV;
|
in vec3 vertexUV;
|
||||||
|
in vec3 vertexColor;
|
||||||
|
|
||||||
uniform vec3 color;
|
uniform sampler2D sourceTexture;
|
||||||
|
uniform vec4 color;
|
||||||
uniform float contrast;
|
uniform float contrast;
|
||||||
uniform float brightness;
|
uniform float brightness;
|
||||||
|
|
||||||
@@ -13,7 +14,7 @@ void main()
|
|||||||
{
|
{
|
||||||
vec4 texturecolor = texture(sourceTexture, vertexUV.xy);
|
vec4 texturecolor = texture(sourceTexture, vertexUV.xy);
|
||||||
vec3 transformedRGB = mix(vec3(0.62), texturecolor.rgb, contrast + 1.0) + brightness;
|
vec3 transformedRGB = mix(vec3(0.62), texturecolor.rgb, contrast + 1.0) + brightness;
|
||||||
transformedRGB *= color;
|
transformedRGB *= vertexColor;
|
||||||
|
|
||||||
FragColor = vec4(transformedRGB, texturecolor.a);
|
FragColor = color * vec4(transformedRGB, texturecolor.a);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,21 @@
|
|||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
layout (location = 0) in vec3 position;
|
layout (location = 0) in vec3 position;
|
||||||
layout (location = 1) in vec3 texCoord;
|
layout (location = 1) in vec3 color;
|
||||||
|
layout (location = 2) in vec3 texCoord;
|
||||||
|
|
||||||
|
out vec3 vertexColor;
|
||||||
out vec3 vertexUV;
|
out vec3 vertexUV;
|
||||||
|
|
||||||
uniform float rotation;
|
uniform mat4 modelview;
|
||||||
uniform float scale;
|
uniform mat4 projection;
|
||||||
uniform vec2 translation;
|
|
||||||
uniform float aspectratio;
|
|
||||||
|
|
||||||
uniform mat4 render_projection;
|
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
// geometry
|
vec4 pos = modelview * vec4(position.xyz, 1.0);
|
||||||
vec2 pos = vec2(position.x * aspectratio, position.y);
|
|
||||||
pos *= scale;
|
|
||||||
vec2 rotated_pos;
|
|
||||||
rotated_pos.x = translation.x + pos.x*cos(rotation) - pos.y*sin(rotation);
|
|
||||||
rotated_pos.y = translation.y + pos.x*sin(rotation) + pos.y*cos(rotation);
|
|
||||||
|
|
||||||
// output
|
// output
|
||||||
gl_Position = render_projection * vec4(rotated_pos.x, rotated_pos.y, position.z, 1.0);
|
gl_Position = projection * pos;
|
||||||
|
vertexColor = color;
|
||||||
vertexUV = texCoord;
|
vertexUV = texCoord;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user