I've started a tutorial on OpenGL and this lesson is about translation of a triangle using glm. However, whenever I compile the program the following errors come up
0(9) : error C1068: too much data in type constructor
(0) : error C2003: incompatible options for link`.
Again I am new to OpenGL and
this tutorial is with Version 3.6 and I am on 4.6 so I don't know if that might be a problem, here's the code hope you could help me out (all on one page btw).
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
//Window dimensions
const GLint SCREEN_WIDTH = 1280, SCREEN_HEIGHT = 900;
GLuint VAO, VBO, shader, uniformModel;
bool isMovingLeft = true;
float triOffset = 0.f;
float triMaxOffset = 0.7;
float triIncrement = 0.005;
//Vertex shader
static const char* vShader = "\n\
#version 460 \n\
\n\
layout(location = 0) in vec3 pos; \n\
\n\
uniform mat4 model; \n\
\n\
void main() { \n\
gl_Position = vec4(0.4 * pos.x + model, 0.4 * pos.y, pos.z, 1.0); \n\
}; \n\
";
//Fragment shader
static const char* fShader = "\n\
#version 460 \n\
\n\
out vec4 color; \n\
\n\
void main() { \n\
color = vec4(0.f, 1.f, 0.f, 1.f); \n\
}; \n\
";
void createTriangle() {
//Vertices of the triangle
GLfloat vertices[] = {
-1.f, -1.f, 0.f,
1.f, -1.f, 0.f,
0.f, 1.f, 0.f
};
//Binding it
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//Information
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
//Unbinding
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void addShader(GLuint theProgram, const char* shaderCode, GLenum shaderType) {
GLuint theShader = glCreateShader(shaderType);
const GLchar* theCode[1];
theCode[0] = shaderCode;
GLint codeLength[1];
codeLength[0] = strlen(shaderCode);
glShaderSource(theShader, 1, theCode, codeLength);
glCompileShader(theShader);
//Getting error information for linking
GLint result = 0;
GLchar eLog[1024] = { 0 };
glGetProgramiv(theShader, GL_COMPILE_STATUS, &result);
if (result != GL_FALSE) {
glGetShaderInfoLog(theShader, sizeof(eLog), NULL, eLog);
std::cout << "Error compiling the " << shaderType << ' ' << eLog << '\n';
}
glAttachShader(theProgram, theShader);
}
void compileShaders() {
shader = glCreateProgram();
if (shader != GL_TRUE) {
std::cout << "Shader program error!\n";
}
//Adding shaders
addShader(shader, vShader, GL_VERTEX_SHADER);
addShader(shader, fShader, GL_FRAGMENT_SHADER);
//Getting error information for linking
GLint result = 0;
GLchar eLog[1024] = { 0 };
//Linking shader
glLinkProgram(shader);
//Shader linking status
glGetProgramiv(shader, GL_LINK_STATUS, &result);
if (result != GL_TRUE) {
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
std::cout << "Error linking program! " << eLog << '\n';
}
//Gets shader ID and then combines `uniformModel` with `model`
uniformModel = glGetUniformLocation(shader, "model");
}
int main() {
//Initialize GLFW
if (glfwInit() != GLFW_TRUE) {
std::cout << "GLFW init failed\n";
glfwTerminate();
}
//Setup GLFW window properties
//OpenGL version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); //Large version
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); //Small version
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //Detects any old OpenGL code, this will throw an error
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //Allows forward compatibility (between differnt OS)
//Creating window
GLFWwindow* window;
window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "OpenGL Test Window", NULL, NULL);
glfwSetWindowPos(window, 250, 100);
if (window == NULL) {
std::cout << "GLFW window creation failed!\n";
glfwTerminate();
}
//Get buffer size information
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(window, &bufferWidth, &bufferHeight);
//Set context for GLEW to use (can change between which window)
glfwMakeContextCurrent(window);
//Allow modern extension features
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::cout << "Glew init failed!\n";
glfwDestroyWindow(window);
glfwTerminate();
}
//Setup viewport size
glViewport(0, 0, bufferWidth, bufferHeight);
createTriangle();
compileShaders();
//Main game loop
while (!glfwWindowShouldClose(window)) {
//Get + Handle user input events
glfwPollEvents();
if (isMovingLeft) {
triOffset += triIncrement;
}
else {
triOffset -= triIncrement;
}
if (abs(triOffset) >= triMaxOffset) {
isMovingLeft = !isMovingLeft;
}
//Clear window
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader);
//Matrix 4x4
glm::mat4 model;
model = glm::translate(model, glm::vec3(triOffset, triOffset, 0.f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
glUseProgram(0);
glfwSwapBuffers(window);
}
}
The uniform model is of type mat4. You've to transform the vertex coordinate by the matrix in the vertex shader:
gl_Position = vec4(0.4 * pos.x + model, 0.4 * pos.y, pos.z, 1.0);`
gl_Position = model * vec4(0.4 * pos.x, 0.4 * pos.y, pos.z, 1.0);
You didn't get the error, because there is an issue in addShader. The compile errors of a shader object can be get by glGetShaderiv rather than glGetProgramiv. If the shader is compiled successfully, then the result is GL_TRUE rather than GL_FALSE:
glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
if (result != GL_TRUE) {
glGetShaderInfoLog(theShader, sizeof(eLog), NULL, eLog);
std::cout << "Error compiling the " << shaderType << ' ' << eLog << '\n';
}
Furthermore glm::mat4 model; gives an uninitialized matrix. To get an Identity matrix you've to pass a single scalar (1.0) to the matrix constructor:
glm::mat4 model(1.0f);
Related
If I remove the uniform variable and the following lines:
//in CompileShaders function:
uniformModel = glGetUniformLocation(shader,"model");
...
//defined in the main draw loop after glfwPollEvents():
//and the shader has compiled, linked and activated at this point
glm::mat4 modelMatrix;
modelMatrix = glm::translate(modelMatrix, glm::vec3(triOffset, 0.0f, 0.0f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE,glm::value_ptr(modelMatrix));
the Program displays fine, but once I add the uniform variable and use the matrix to translate the triangle I can't find why I get a red screen, for ease of reference the shader is :
static const char* vShader =
"#version 330\n"
"layout (location = 0) in vec3 pos;\n"
"uniform mat4 model;\n"
"void main(){\n"
" gl_Position = model * vec4(pos, 1.0);\n"
"}\n";
// fragment shader
static const char* fShader = ""
"#version 330\n"
"out vec4 color;\n"
"void main(){\n"
" color = vec4(1.0, 1.0, 0.0, 1.0);\n"
"}\n";
The entire source code is:
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <cmath>
#include <string.h>
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
// Window Dimensions
const GLint WIDTH=800, HEIGHT=600;
GLuint VAO, VBO, shader;
GLint uniformModel {};
GLfloat triOffset {};
GLfloat triMaxOffset {5.0f};
bool direction = true;
// vertex shader
static const char* vShader =
"#version 330\n"
"layout (location = 0) in vec3 pos;\n"
"uniform mat4 model;\n"
"void main(){\n"
" gl_Position = model * vec4(pos, 1.0);\n"
"}\n";
// fragment shader
static const char* fShader = ""
"#version 330\n"
"out vec4 color;\n"
"void main(){\n"
" color = vec4(1.0, 1.0, 0.0, 1.0);\n"
"}\n";
void AddShader(GLuint theProgram, const char* ShaderCode, GLenum shaderType, std::string info){
std::cerr <<"DEBUG: Adding "<<info<<" Shader"<<std::endl;
GLuint theShader = glCreateShader(shaderType);
const GLchar* theCode[1];
theCode[0] = ShaderCode;
GLint codeLength[1];
codeLength[0] = strlen(ShaderCode);
glShaderSource(theShader, 1, theCode, codeLength);
glCompileShader(theShader);
GLint result =0;
GLchar eLog[1024] ={0};
glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
if(!result){
glGetShaderInfoLog(shader, sizeof(eLog), NULL, eLog);
std::cerr<<"Error compiling program"<<std::endl;
return;
}
glAttachShader(theProgram, theShader);
}
void CompileShader(){
shader = glCreateProgram();
if(!shader){
std::cerr<<"Error creating shader"<<std::endl;
return;
}
AddShader(shader, vShader, GL_VERTEX_SHADER, "vertex");
AddShader(shader, fShader, GL_FRAGMENT_SHADER, "fragment");
GLint result =0;
GLchar eLog[1024] ={0};
glLinkProgram(shader);
glGetProgramiv(shader, GL_LINK_STATUS, &result);
if(!result){
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
std::cerr<<"Error linking program"<<std::endl;
return;
}
glValidateProgram(shader);
glGetProgramiv(shader, GL_VALIDATE_STATUS, &result);
if(!result){
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
std::cerr<<"Error Validating program"<<std::endl;
return;
}
uniformModel = glGetUniformLocation(shader,"model");
}
void CreateTriangles(){
GLfloat vertices[]={
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9,vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
int main(){
//initialize GLFW
if(!glfwInit()){
std::cerr << "GLFW initialization failed!" << std::endl;
glfwTerminate();
return 1;
}
//Setup GLFW window properties
//openGL version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// core profile = no backward compatibility
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//allow forward compatibility
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
GLFWwindow *mainWindow = glfwCreateWindow(WIDTH, HEIGHT, "TEST WINDOW", NULL, NULL);
if(!mainWindow){
std::cerr << "GLFW Window creation failed" << std::endl;
glfwTerminate();
return 1;
}
// get Buffer size information
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(mainWindow, &bufferWidth, &bufferHeight);
// set context for GLEW to use
glfwMakeContextCurrent(mainWindow);
// allow modern extension features
if(glewInit()!=GLEW_OK){
std::cerr << "GLEW initialization failed" << std::endl;
glfwDestroyWindow(mainWindow);
glfwTerminate();
return 1;
}
// setup viewport size
glViewport(0, 0, bufferWidth, bufferHeight);
CreateTriangles();
CompileShader();
while(!glfwWindowShouldClose(mainWindow)){
// get and handle user input events
glfwPollEvents();
glClearColor(1.0f, 0.0f, 0.0f, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
if(direction){
triOffset += 0.0005f;
}else{
triOffset -= 0.0005f;
triOffset = abs(triOffset);
}
if(direction<=0.0 || direction> triMaxOffset){
direction = !direction;
}
glUseProgram(shader);
glm::mat4 modelMatrix;
modelMatrix = glm::translate(modelMatrix, glm::vec3(triOffset, 0.0f, 0.0f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE,glm::value_ptr(modelMatrix));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES,0,3);
glBindVertexArray(0);
glUseProgram(0);
// swap buffers
glfwSwapBuffers(mainWindow);
}
return 0;
}
How can I determine what the problem is?
The model matrix variable glm::mat4 modelMatrix has to be initialized by the Identity matrix.
The glm API documentation refers to The OpenGL Shading Language specification.
5.4.2 Vector and Matrix Constructors
If there is a single scalar parameter to a vector constructor, it is used to initialize all components of the constructed vector to that scalar’s value. If there is a single scalar parameter to a matrix constructor, it is used to initialize all the components on the matrix’s diagonal, with the remaining
components initialized to 0.0.
An Identity matrix can be initialized by the single parameter 1.0:
glm::mat4 modelMatrix(1.0f);
i have installed OpenGL 4.6 and i'am using visual studio 2019.
i had decided to do a project in C++ with opengl but since i have no previous experience with them i decided to follow this tutorial but now my shaders aren't compiling and i have no idea why.
my main code:
#include <fstream>
#include <string>
#include <glad/glad.h>
#include <GLFW\glfw3.h>
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow* window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
float vertex[] = {
0.0f, 0.5f, 0.0f, 0.2f, 0.4f, 0.6f, // top center
0.5f, -0.5f, 0.0f, 0.2f, 0.4f, 0.6f, // bottom right
-0.5f, -0.5f, 0.0f, 0.2f, 0.4f, 0.6f, // bottom left
0.0f, 0.0f, -0.5f, 0.2f, 0.4f, 0.6f // top left
};
unsigned int indices[] = { // note that we start from 0!
0, 1, 2
};
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
std::cout << glfwGetVersionString();
GLFWwindow* window = glfwCreateWindow(800, 600, "Demo", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
GLuint VBO, VAO, EBO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
std::string ContentVert;
std::ifstream infileVert;
infileVert.open("vertex.glsl");
if (infileVert.is_open())
{
while (getline(infileVert, ContentVert))
{
std::cout << ContentVert << '\n';
}
infileVert.close();
}
const GLchar* const vertexShadersrc = { ContentVert.c_str() };
glShaderSource(vertexShader, 1, &vertexShadersrc, NULL);
glCompileShader(vertexShader);
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
std::string ContentFrag;
std::ifstream infileFrag;
infileFrag.open("demo.glsl");
if (infileFrag.is_open())
{
while (getline(infileFrag, ContentFrag))
{
std::cout << ContentFrag << '\n';
}
infileFrag.close();
}
const GLchar* const fragShaderSrc = { ContentFrag.c_str() };
glShaderSource(fragmentShader, 1, &fragShaderSrc, NULL);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
unsigned int shaderProgram;
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glUseProgram(shaderProgram);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
while (!glfwWindowShouldClose(window))
{
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glfwTerminate();
return 0;
}
console output:
#version 330
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
out vec3 ourColor;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
ourColor = aColor;
}
ERROR::SHADER::VERTEX::COMPILATION_FAILED
WARNING: 0:1: '' : #version directive missing
ERROR: 0:1: '}' : syntax error syntax error
#version 330
out vec4 FragColor;
in vec3 ourColor;
void main() {
FragColor = vec4(ourColor, 1.0);
}
ERROR::SHADER::FRAGMENT::COMPILATION_FAILED
WARNING: 0:1: '' : #version directive missing
ERROR: 0:1: '}' : syntax error syntax error
ERROR::SHADER::PROGRAM::LINKING_FAILED
Attached vertex shader is not compiled
vertex shader:
#version 330
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
out vec3 ourColor;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
ourColor = aColor;
}
fragment shader:
#version 330
out vec4 FragColor;
in vec3 ourColor;
void main() {
FragColor = vec4(ourColor, 1.0);
}
The issue is the way how you try to read the file
while (getline(infileVert, ContentVert))
getline reads a single line from the file and stores it to ContentVert. I does not append to ContentVert.
At the end, just the last line of the shader is stored in ContentVert. The content of the last line is "}". That explains the error message:
WARNING: 0:1: '' : #version directive missing
ERROR: 0:1: '}' : syntax error syntax error
I recommend to use std::istreambuf_iterator to read the entire file, from its begin to its end:
std::ifstream infileVert("vertex.glsl", std::fstream::in);
std::string ContentVert;
if ( sourceFile.is_open() )
ContentVert = std::string(std::istreambuf_iterator<char>(infileVert),
std::istreambuf_iterator<char>());
I'm trying to create a Mesh class that can generate a model for me and then calling that model in the createTriangle function. However, whenever I try creating the meshObj1 and meshObj2 and then pushing it to the meshVector, it does not want to render? Why is this happening?
Mesh.h
#ifndef MESH_H
#define MESH_H
#include "GL/glew.h"
class Mesh {
public:
Mesh();
~Mesh();
void createMesh(GLfloat *vertices, unsigned int *indices, unsigned int numOfVertices, unsigned int numOfIndices);
void renderMesh();
void clearMesh();
private:
GLuint VAO, VBO, IBO;
GLsizei indexCount;
};
#endif
Mesh.cpp
#include "Mesh.h"
Mesh::Mesh() {
VAO = 0;
VBO = 0;
IBO = 0;
indexCount = 0;
}
Mesh::~Mesh() {
clearMesh();
}
void Mesh::createMesh(GLfloat* vertices, unsigned int* indices, unsigned int numOfVertices, unsigned int numOfIndices) {
indexCount = numOfIndices;
//Binding
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
//Information
//VBO Information
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0] * numOfVertices), vertices, GL_STATIC_DRAW);
//IBO Information
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * numOfIndices, indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
//Unbinding
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void Mesh::renderMesh() {
//Binding
glBindVertexArray(VAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
//Rendering
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, 0);
//Unbinding
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void Mesh::clearMesh() {
if (VAO != 0) {
glDeleteVertexArrays(1, &VAO);
VAO = 0;
}
if (VBO != 0) {
glDeleteBuffers(1, &VBO);
VBO = 0;
}
if (IBO != 0) {
glDeleteBuffers(1, &IBO);
IBO = 0;
}
indexCount = 0;
}
Main.cpp
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#include "glm/glm.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"
#include <iostream>
#include <vector>
#include <memory>
#include "Mesh.h"
//Window dimensions
const GLint SCREEN_WIDTH = 1280, SCREEN_HEIGHT = 900;
GLuint shader, uniformModel, uniformProjection;
bool isMovingLeft = true;
float triOffset = 0.f;
float triMaxOffset = 0.7;
float triIncrement = 0.005;
std::vector<Mesh*> meshVector;
//Vertex shader
static const char* vShader = " \n\
#version 460 \n\
\n\
layout(location = 0) in vec3 pos; \n\
\n\
out vec4 vColor; \n\
\n\
uniform mat4 model; \n\
uniform mat4 projection; \n\
\n\
void main() { \n\
gl_Position = projection * model * vec4(pos, 1.0); \n\
vColor = vec4(clamp(pos, 0.f, 1.f), 1.f); \n\
}; \n\
";
//Fragment shader
static const char* fShader = " \n\
#version 460 \n\
\n\
in vec4 vColor; \n\
\n\
out vec4 color; \n\
\n\
void main() { \n\
color = vColor; \n\
}; \n\
";
void createTriangle() {
unsigned int indices[] = {
0, 3, 1,
1, 3, 2,
2, 3, 0,
0, 1, 2
};
//Points of the triangle
GLfloat vertices[] = {
-1.f, -1.f, 0.f,
0.f, -1.f, 1.f,
1.f, -1.f, 0.f,
0.f, 1.f, 0.f
};
Mesh* meshObj1 = new Mesh();
meshObj1->createMesh(vertices, indices, 12, 12);
meshVector.push_back(meshObj1);
Mesh* meshObj2 = new Mesh();
meshObj2->createMesh(vertices, indices, 12, 12);
meshVector.push_back(meshObj2);
}
void addShader(GLuint theProgram, const char* shaderCode, GLenum shaderType) {
GLuint theShader = glCreateShader(shaderType);
const GLchar* theCode[1];
theCode[0] = shaderCode;
GLint codeLength[1];
codeLength[0] = strlen(shaderCode);
glShaderSource(theShader, 1, theCode, codeLength);
glCompileShader(theShader);
//Getting error information for linking
GLint result = 0;
GLchar eLog[1024] = { 0 };
glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
if (result != GL_TRUE) {
glGetShaderInfoLog(theShader, sizeof(eLog), NULL, eLog);
std::cout << "Error compiling the " << shaderType << ' ' << eLog << '\n';
}
glAttachShader(theProgram, theShader);
}
void compileShaders() {
shader = glCreateProgram();
if (shader != GL_TRUE) {
std::cout << "Shader program error!\n";
}
//Adding shaders
addShader(shader, vShader, GL_VERTEX_SHADER);
addShader(shader, fShader, GL_FRAGMENT_SHADER);
//Getting error information for linking
GLint result = 0;
GLchar eLog[1024] = { 0 };
//Linking shader
glLinkProgram(shader);
//Shader linking status
glGetProgramiv(shader, GL_LINK_STATUS, &result);
if (result != GL_TRUE) {
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
std::cout << "Error linking program! " << eLog << '\n';
}
//Gets shader ID and then binds it with the variable inside shader
uniformModel = glGetUniformLocation(shader, "model");
uniformProjection = glGetUniformLocation(shader, "projection");
}
int main() {
//Initialize GLFW
if (glfwInit() != GLFW_TRUE) {
std::cout << "GLFW init failed\n";
glfwTerminate();
}
//Setup GLFW window properties
//OpenGL version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); //Large version
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 4); //Small version
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //Detects any old OpenGL code, this will throw an error
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //Allows forward compatibility (between differnt OS)
//Creating window
GLFWwindow* window;
window = glfwCreateWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "OpenGL Test Window", NULL, NULL);
glfwSetWindowPos(window, 250, 100);
if (window == NULL) {
std::cout << "GLFW window creation failed!\n";
glfwTerminate();
}
//Get buffer size information
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(window, &bufferWidth, &bufferHeight);
//Set context for GLEW to use (can change between which window)
glfwMakeContextCurrent(window);
//Allow modern extension features
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
std::cout << "Glew init failed!\n";
glfwDestroyWindow(window);
glfwTerminate();
}
glEnable(GL_DEPTH_TEST);
//Setup viewport size
glViewport(0, 0, bufferWidth, bufferHeight);
createTriangle();
compileShaders();
glm::mat4 projection = glm::perspective(45.f, (GLfloat)bufferWidth / (GLfloat)bufferHeight, 0.1f, 100.f);
//Main game loop
while (!glfwWindowShouldClose(window)) {
//Get + Handle user input events
glfwPollEvents();
//Left-Right
if (isMovingLeft) {
triOffset += triIncrement;
}
else {
triOffset -= triIncrement;
}
if (abs(triOffset) >= triMaxOffset) {
isMovingLeft = !isMovingLeft;
}
//Clear window
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader);
//Matrix 4x4
glm::mat4 model(1.f);
model = glm::translate(model, glm::vec3(triOffset, 0.f, -2.5f));
model = glm::scale(model, glm::vec3(0.4f, 0.4f, 1.f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(uniformProjection, 1, GL_FALSE, glm::value_ptr(projection));
meshVector[0]->renderMesh();
model = glm::mat4(1.f);
model = glm::translate(model, glm::vec3(-triOffset, 1.f, -2.5f));
model = glm::scale(model, glm::vec3(0.4f, 0.4, 1.f));
meshVector[1]->renderMesh();
glUseProgram(0);
glfwSwapBuffers(window);
}
}
I expect two pyramids to form with color.
The GL_ELEMENT_ARRAY_BUFFER target binding is stored in the Vertex Array Object. See Index buffers.
This means, that the instruction
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
breaks the former binding of IBO to the vertex array object VAO. Remove this instruction from your code, to solve the issue.
Note, GL_ARRAY_BUFFER and the GL_ELEMENT_ARRAY_BUFFER behave differently. The current GL_ARRAY_BUFFER binding is a global state, but the GL_ELEMENT_ARRAY_BUFFER binding is stated in the current Vertex Array Object.
Also the GL_ARRAY_BUFFER is stated in the state vector of the VAO, but this happens when glVertexAttribPointer is called. When glVertexAttribPointer is called, then the buffer which is currently bound to the target GL_ARRAY_BUFFER is associated to the vertex attribute with the specified index.
That causes the difference in the behavior of GL_ELEMENT_ARRAY_BUFFER and GL_ARRAY_BUFFER. A VAO can only refer to 1 index (element) buffer, but it can refer to multiple array buffers. Each attribute (index) can be associated to a different buffer.
Before you render the 2nd mesh, you've the set the corresponding model matrix to the default uniform block of the installed program:
glUseProgram(shader);
glUniformMatrix4fv(uniformProjection, 1, GL_FALSE, glm::value_ptr(projection));
glm::mat4 model(1.f);
model = glm::translate(model, glm::vec3(triOffset, 0.f, -2.5f));
model = glm::scale(model, glm::vec3(0.4f, 0.4f, 1.f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));
meshVector[0]->renderMesh();
model = glm::mat4(1.f);
model = glm::translate(model, glm::vec3(-triOffset, 1.f, -2.5f));
model = glm::scale(model, glm::vec3(0.4f, 0.4, 1.f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model)); // <---
meshVector[1]->renderMesh();
This OpenGL code is supposed to render a triangle moving back and forth on the X-axis:
#include <stdio.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <string.h>
#include <cmath>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
// Window dimensions
const GLint WIDTH = 800, HEIGHT = 600;
GLuint VAO, VBO, shader, uniformModel;
bool direction = true;
float triOffest = 0.0f;
float triMaxOffset = 0.7f;
float triIncrement = 0.0005f;
// Vertex Shader
static const char* vShader = " \n\
#version 330 \n\
\n\
layout (location = 0) in vec3 pos; \n\
\n\
uniform mat4 model; \n\
\n\
void main() \n\
{ \n\
gl_Position = model * vec4(0.4 * pos.x, 0.4 * pos.y, pos.z, 1.0); \n\
}";
// Fragment Shader
static const char* fShader = " \n\
#version 330 \n\
\n\
out vec4 colour; \n\
\n\
void main() \n\
{ \n\
colour = vec4(1.0, 0.0, 0.0, 1.0); \n\
}";
void CreateTriangle()
{
GLfloat vertices[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f
};
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
void AddShader(GLuint theProgram, const char* shaderCode, GLenum shaderType)
{
GLuint theShader = glCreateShader(shaderType);
const GLchar* theCode[1];
theCode[0] = shaderCode;
GLint codeLength[1];
codeLength[0] = strlen(shaderCode);
glShaderSource(theShader, 1, theCode, codeLength);
glCompileShader(theShader);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glGetShaderiv(theShader, GL_COMPILE_STATUS, &result);
if (!result)
{
glGetShaderInfoLog(theShader, sizeof(eLog), NULL, eLog);
printf("Error compiling %d shader: '%s'\n", shaderType, eLog);
return;
}
glAttachShader(theProgram, theShader);
}
void CompileShaders()
{
shader = glCreateProgram();
if (!shader)
{
printf("Error creating shader program!\n");
return;
}
AddShader(shader, vShader, GL_VERTEX_SHADER);
AddShader(shader, fShader, GL_FRAGMENT_SHADER);
GLint result = 0;
GLchar eLog[1024] = { 0 };
glLinkProgram(shader);
glGetProgramiv(shader, GL_LINK_STATUS, &result);
if (!result)
{
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
printf("Error linking program: '%s'\n", eLog);
return;
}
glValidateProgram(shader);
glGetProgramiv(shader, GL_VALIDATE_STATUS, &result);
if (!result)
{
glGetProgramInfoLog(shader, sizeof(eLog), NULL, eLog);
printf("Error validating program: '%s'\n", eLog);
return;
}
uniformModel = glGetUniformLocation(shader, "model");
}
int main()
{
// Initialise GLFW
if (!glfwInit())
{
printf("GLFW initialisation failed!");
glfwTerminate();
return 1;
}
// Setup GLFW window properties
// OpenGL version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// core profile = No backwards Compatibility
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
GLFWwindow* mainWindow = glfwCreateWindow(WIDTH, HEIGHT, "Test Window", NULL, NULL);
if (!mainWindow)
{
printf("GLFW window creation failed!");
glfwTerminate();
return 1;
}
// Get buffer size information
int bufferWidth, bufferHeight;
glfwGetFramebufferSize(mainWindow, &bufferWidth, &bufferHeight);
// Set context for GLEW to use
glfwMakeContextCurrent(mainWindow);
// Allow modern extension features
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK)
{
printf("GLEW initialisation failed!");
glfwDestroyWindow(mainWindow);
glfwTerminate();
return 1;
}
// Setup viewport size
glViewport(0, 0, bufferWidth, bufferHeight);
CreateTriangle();
CompileShaders();
// Loop unitil window closed
while (!glfwWindowShouldClose(mainWindow))
{
// Get + Handle user input events
glfwPollEvents();
if (direction)
{
triOffest += triIncrement;
}
else
{
triOffest -= triIncrement;
}
if (abs(triOffest) >= triMaxOffset)
{
direction = !direction;
}
// Clear window
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader);
glm::mat4 model;
model = glm::translate(model, glm::vec3(triOffest, 0.0f, 0.0f));
glUniformMatrix4fv(uniformModel, 1, GL_FALSE, glm::value_ptr(model));
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
glfwSwapBuffers(mainWindow);
}
return 0;
}
However, after I run the code I just see a blank screen.(The triangle did render, before multiplying the translation transformation matrix with the vertex position in the vertex shader). The triangle seems to disappear after I apply the transformation model.
Could anyone help me figure out what's wrong?
As #Botje advised, I just had to initiallize the mat4 model as glm::mat4 model(1.0);
inside the main() and done.. problem solved.
I've looked for an answer to my problem for two days. Maybe I'm just terrible at searching but there doesn't seem to be an answer already out there.
I am trying to draw lines on the screen using OpenGL's glDrawArrays(GL_LINES, ..., ...). This is the current code for my fragment shader:
#version 330 core
in vec4 vertexColor;
out vec4 color;
void main( )
{
//color = vec3(0.5f, 1.0f, 1.0f);
color = vec4(0.5f, 1.0f, 1.0f, 0.5f);
//color = vertexColor;
}
Originally the color=vertexColor line was supposed to work, but nothing appeared on the screen. I thought maybe something was wrong with the data being sent from the vertex shader so I tried setting the output manually in the fragment shader. I accidentally made it a vec3 instead of a vec4 and I got an error in my console window telling me compilation of the shader had failed. But the lines appeared! They showed up in the right spot as white/gray lines of static. When I corrected the mistake and set the output to a vec4, like shown, the lines were invisible again and I had no compilation error.
What am I doing wrong that makes my lines invisible?
Edit:
Here is my first go at a "minimal, complete, and verifiable example". If you link a project with these files to GLEW, GLFW and GLM, this should run on your system. If I'm not supposed to upload a whole program, I apologize. This seems a bit big, but I don't know how else it could be "complete".
Instead of making two white static lines, this one is making only one solid black line when the fragment shader fails to compile. It still renders nothing when compilation is successful.
Main.cpp
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include "ShaderMaker.h"
#include "TargetBox.h"
const GLint WIDTH = 800, HEIGHT = 600;
//Camera
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 0.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
GLfloat yaw = -90.0f;
GLfloat pitch = 0.0f;
// Delta time
GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;
int main() {
cameraFront.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
cameraFront.y = sin(glm::radians(pitch));
cameraFront.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
cameraFront = glm::normalize(cameraFront);
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
GLFWwindow *window = glfwCreateWindow(WIDTH, HEIGHT, "Debugger", nullptr, nullptr);
int screenWidth, screenHeight;
glfwGetFramebufferSize(window, &screenWidth, &screenHeight);
if (window == nullptr) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return EXIT_FAILURE;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
if (GLEW_OK != glewInit()) {
std::cout << "Failed to initialize GLEW" << std::endl;
return EXIT_FAILURE;
}
glViewport(0, 0, screenWidth, screenHeight);
glEnable(GL_DEPTH_TEST);
TargetBox tb;
GLuint modelLoc = tb.getUniform("model");
GLuint viewLoc = tb.getUniform("view");
GLuint projectionLoc = tb.getUniform("projection");
glm::mat4 projection;
projection = glm::perspective(glm::radians(45.0f), (float)screenWidth / screenHeight, 0.1f, 100.0f);
while (!glfwWindowShouldClose(window)) {
GLfloat currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
glfwPollEvents();
glClearColor(0.5f, 0.7f, 0.9f, 1.0f); // Unnecessary, but adds some color to an otherwise blank window
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 view;
view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
tb.useShader();
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
glBindVertexArray(tb.getVAO());
glm::vec3 posMod = tb.getPos();
glm::mat4 model;
model = glm::translate(model, glm::vec3(posMod.x, posMod.y, posMod.z));
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glDrawArrays(GL_LINES, 0, 4);
glBindVertexArray(0);
glfwSwapBuffers(window);
}
glfwTerminate();
return EXIT_SUCCESS;
}
ShaderMaker.h
#pragma once
#ifndef SHADERMAKER_H
#define SHADERMAKER_H
#include<string>
#include<fstream>
#include<sstream>
#include<iostream>
#include<GL/glew.h>
class ShaderMaker {
public:
// The program ID
GLuint Program;
// Constructor reads and builds the shader
ShaderMaker(const GLchar* vertexPath, const GLchar* fragmentPath) {
// 1. Retrieve the vertex/fragment source code from filePath
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
// ensures ifstream objects can throw exceptions:
vShaderFile.exceptions(std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::badbit);
try {
// Open files
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
// Read file's buffer contents into streams
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
// close file handlers
vShaderFile.close();
fShaderFile.close();
// Convert stream into GLchar array
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
}
catch (std::ifstream::failure e) {
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ" << std::endl;
}
const GLchar* vShaderCode = vertexCode.c_str();
const GLchar* fShaderCode = fragmentCode.c_str();
// 2. Compile shaders
GLuint fragment;
GLint success;
GLchar infoLog[512];
// Vertex shader
GLuint vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
// Print compile errors if any
glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertex, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Similar for fragment shader
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
// Print compile errors if any
glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragment, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Shader program
this->Program = glCreateProgram();
glAttachShader(this->Program, vertex);
glAttachShader(this->Program, fragment);
glLinkProgram(this->Program);
// Print linking errors if any
glGetShaderiv(this->Program, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
// Delete the shaders as they're linked into our program now and no longer necessary
glDeleteShader(vertex);
glDeleteShader(fragment);
}
// Use the program
void Use() { glUseProgram(this->Program); }
// Get a uniform
GLint getUniform(const GLchar * name) {
return glGetUniformLocation(this->Program, name);
}
};
#endif
TargetBox.h
#pragma once
#ifndef TARGETBOX_H
#define TARGETBOX_H
#define GLEW_STATIC
#include <GL/glew.h>
#include<glm/glm.hpp>
#include <GLFW/glfw3.h>
#include "ShaderMaker.h"
class TargetBox
{
public:
TargetBox();
~TargetBox();
void useShader();
GLuint getVAO();
glm::vec3 getPos();
void setPos(glm::vec3 p);
GLuint getUniform(GLchar * u);
private:
glm::vec3 pos;
GLuint VAO, VBO;
const GLchar *vertexShaderPath = ".\\VShaderLine.txt";
const GLchar *fragmentShaderPath = ".\\FShaderLine.txt";
ShaderMaker shader = ShaderMaker(vertexShaderPath, fragmentShaderPath);
};
#endif
TargetBox.cpp
#include "TargetBox.h"
TargetBox::TargetBox()
{
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
GLfloat vertices[] = {
-2, 0, -5, 1.0f, 1.0f, 1.0f,
2, 0, 5, 1.0f, 1.0f, 1.0f,
2, 0, 5, 1.0f, 0.0f, 0.0f,
2, 10, 5, 0.0f, 1.0f, 0.0f
};
size_t data_len = sizeof(vertices);
glBufferData(GL_ARRAY_BUFFER, data_len, vertices, GL_STATIC_DRAW);
// Position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid *)0);
glEnableVertexAttribArray(0);
//Color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
TargetBox::~TargetBox()
{
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
}
void TargetBox::useShader() { shader.Use(); }
GLuint TargetBox::getVAO() { return VAO; }
glm::vec3 TargetBox::getPos() { return pos; }
void TargetBox::setPos(glm::vec3 p) { pos = p; }
GLuint TargetBox::getUniform(GLchar * u) { return shader.getUniform(u); }
VShaderLine.txt
#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 color;
out vec4 vertexColor;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main( )
{
// The order of multiplication is important?
gl_Position = projection * view * model * vec4( position, 1.0 );
vertexColor = vec4(color.xyz, 1.0f);
}
FShaderLine.txt
#version 330 core
in vec4 vertexColor;
out vec4 color;
void main( )
{
color = vec3(0.5f, 1.0f, 1.0f);
//color = vec4(0.5f, 1.0f, 1.0f, 0.5f);
//color = vertexColor;
}