Opengl two different triangles with two shader programs - c++

I want to create 2 triangles with different colors that they change to wireframe mode when I press "Tab" my problem is that I have two VBO and two shaders programs but it only compile one triangle
#include <GL\glew.h>
#include <GLFW\glfw3.h>
#include <iostream>
bool flag;
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
const char* vertex_shader =
"#version 110 \n"
"attribute vec3 in_position; \n"
"void main() \n"
"{ \n"
" gl_Position = vec4(in_position.x, in_position.y, in_position.z, 1.0);\n"
"} \n";
const char* fragment_shader =
"#version 110 \n"
"void main (void) \n"
"{ \n"
" gl_FragColor = vec4(0.7,0.3,0.3, 1.0); \n"
"} \n";
const char* vertex_shader1 =
"#version 110 \n"
"attribute vec3 in_position; \n"
"void main() \n"
"{ \n"
" gl_Position1 = vec4(in_position.x, in_position.y, in_position.z, 1.0);\n"
"} \n";
const char* fragment_shader1 =
"#version 110 \n"
"void main (void) \n"
"{ \n"
" gl_FragColor1 = vec4(0.4,0.7,0.3, 1.0); \n"
"} \n";
int main()
{
//Initialize GLFW
if (!glfwInit()) //if GLFW is not initialized correctly, exit
{
std::cout << "Failed to initialize GLFW" << std::endl;
return -1;
}
//Create the window
GLFWwindow* window = glfwCreateWindow(800, 600, "LearnOpenGL", NULL, NULL);
if (window == NULL) //if the window was not created correctly, exit
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
//Specify OpenGL version
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
//Make the context that was created the current one
glfwMakeContextCurrent(window);
//Initialize GLEW
if (glewInit() != GLEW_OK) //if GLEW was not initialized correctly, exit
{
std::cout << "Failed to initialize GLEW" << std::endl;
glfwTerminate();
return -1;
}
//Set the viewport size changing function
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
//Rectangle vertices, to uncomment select the area and press Ctr+K,Ctr+U
float vertices[] =
{
// first triangle
0.55f, 0.5f, 0.0f, // top right
0.55f, -0.5f, 0.0f, // bottom right
-0.45f, 0.5f, 0.0f, // top left
};
float vertices1[] =
{
// second triangle
0.45f, -0.5f, 0.0f, // bottom right
-0.55f, -0.5f, 0.0f, // bottom left
-0.55f, 0.5f, 0.0f // top left
};
//Create the triangle VBO
GLuint triangle_vbo;
glGenBuffers(1, &triangle_vbo); //generate a unique buffer ID
glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo); //bind the VBO to the context
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//copy user-defined data into the currently bound buffer
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind the VBO
//Create a vertex shader object
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER); //ID of the shader object
glShaderSource(vertexShader, 1, &vertex_shader, NULL); //attach the shader source code to the shader object
glCompileShader(vertexShader);//compile the shader
//Create a fragment shader object
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragment_shader, NULL);
glCompileShader(fragmentShader);
//Create a shader program object
GLuint shaderProgram;
shaderProgram = glCreateProgram(); //create the program ID
glAttachShader(shaderProgram, vertexShader); //attach the shaders to the program
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram); // link the program
//Delete the vertex andd fragment shader objects
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
//Create the triangle VBO
GLuint triangle_vbo1;
glGenBuffers(1, &triangle_vbo1); //generate a unique buffer ID
glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo1); //bind the VBO to the context
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);//copy user-defined data into the currently bound buffer
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind the VBO
//Create a vertex shader object
GLuint vertexShader1;
vertexShader1 = glCreateShader(GL_VERTEX_SHADER); //ID of the shader object
glShaderSource(vertexShader1, 1, &vertex_shader1, NULL); //attach the shader source code to the shader object
glCompileShader(vertexShader1);//compile the shader
//Create a fragment shader object
GLuint fragmentShader1;
fragmentShader1 = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader1, 1, &fragment_shader1, NULL);
glCompileShader(fragmentShader1);
//Create a shader program object
GLuint shaderProgram1;
shaderProgram1 = glCreateProgram(); //create the program ID
glAttachShader(shaderProgram1, vertexShader1); //attach the shaders to the program
glAttachShader(shaderProgram1, fragmentShader1);
glLinkProgram(shaderProgram1); // link the program
//Delete the vertex andd fragment shader objects
glDeleteShader(vertexShader1);
glDeleteShader(fragmentShader1);
//Rendering loop
while(!glfwWindowShouldClose(window))
{
//Process input
processInput(window);
//Clear the buffers
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); //dark green
//glClearColor(0.5f, 0.0f, 0.0f, 1.0f); //maroon
glClear(GL_COLOR_BUFFER_BIT);
if(flag==true)
{
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
}
else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//Render objects...
glUseProgram(shaderProgram); //use a shader program
glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo); //bind the VBO
//tell OpenGL how to read and assign the VBO to the attribute
GLint in_pos = glGetAttribLocation(shaderProgram, "in_position");
glVertexAttribPointer(in_pos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(in_pos);
glUseProgram(shaderProgram);
glUseProgram(shaderProgram1);
glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo1);
GLint in_pos1 = glGetAttribLocation(shaderProgram1, "in_position");
glVertexAttribPointer(in_pos1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(in_pos1);
glDrawArrays(GL_TRIANGLES, 0, 6); //draw the triangle
//Swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
glfwSwapBuffers(window);
glfwPollEvents();
}
//Terminate GLFW before exit
glfwTerminate();
return 0;
}
//Viewport size changing function
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
//Input
void processInput(GLFWwindow *window)
{
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
if(glfwGetKey(window, GLFW_KEY_TAB) == GLFW_PRESS)
flag=true;
else flag=false;
}
The Tab switch changes to wireframe mode as I long keep pressing the "Tab". I want to change only with one click and when click again to change to default

The 2nd vertex shader and fragment shader won't compile, because gl_Position1 and gl_FragColor1 are not valid output variables. You have to use gl_Position and gl_FragColor. See Vertex Shader and Fragment Shader
const char* vertex_shader1 =
"#version 110 \n"
"attribute vec3 in_position; \n"
"void main() \n"
"{ \n"
" gl_Position = vec4(in_position.x, in_position.y, in_position.z, 1.0);\n"
"} \n";
const char* fragment_shader1 =
"#version 110 \n"
"void main (void) \n"
"{ \n"
" gl_FragColor = vec4(0.4,0.7,0.3, 1.0); \n"
"} \n";
I recommend to use glGetShaderiv to verify if the shader code was compiled successfully.
e.g.
GLint status;
glGetShaderiv(vertex_shader1, GL_COMPILE_STATUS, &status);
Use glGetProgramiv with the GL_LINK_STATUS parameter to check if the program was linked successfully.
You have 2 vertex buffers with each 3 vertices, so you have to call glDrawArrays(GL_TRIANGLES, 0, 3); twice and not one time glDrawArrays(GL_TRIANGLES, 0, 6);.
Bind the buffer, define and enable the array of generic vertex attribute data and then draw the triangle:
glUseProgram(shaderProgram);
glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo); //bind the VBO
GLint in_pos = glGetAttribLocation(shaderProgram, "in_position");
glVertexAttribPointer(in_pos, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(in_pos);
glDrawArrays(GL_TRIANGLES, 0, 3); //draw the 1st triangle
glUseProgram(shaderProgram1);
glBindBuffer(GL_ARRAY_BUFFER, triangle_vbo1);
GLint in_pos1 = glGetAttribLocation(shaderProgram1, "in_position");
glVertexAttribPointer(in_pos1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GL_FLOAT), (void*)0);
glEnableVertexAttribArray(in_pos1);
glDrawArrays(GL_TRIANGLES, 0, 3); //draw the 2nd triangle
See the preview:

Related

Why is OpenGL giving me the error: ERROR: 0:1: '' : version '330' is not supported?

I am on mac and I am using Xcode 10.1 as I can't get a new version as my mac is on 10.13.6. I am new to C++ and OpenGL so I followed a tutorial on how to do this, but it is on Windows 10 so maybe that is the problem? It is using GLFW and GLEW both installed with Homebrew.
Here is my code:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
static unsigned int CompileShader(unsigned int type, const std::string& source)
{
unsigned int id = glCreateShader(type);
const char* src = source.c_str();
glShaderSource(id, 1, &src, nullptr);
glCompileShader(id);
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
if(result == GL_FALSE)
{
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
char* message = (char*)alloca(length * sizeof(char));
glGetShaderInfoLog(id, length, &length, message);
std::cout << "Failed to compile " << (type == GL_VERTEX_SHADER ? "vertex" : "fragment") << " shader!" << std::endl;
std::cout << message << std::endl;
glDeleteShader(id);
return 0;
}
return id;
}
static unsigned int CreateShader(const std::string& vertexShader, const std::string& fragmentShader)
{
unsigned int program = glCreateProgram();
unsigned int vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
unsigned int fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glValidateProgram(program);
glDeleteShader(vs);
glDeleteShader(fs);
return program;
}
int main(void)
{
GLFWwindow* window;
if (!glfwInit())
return -1;
window = glfwCreateWindow(640, 480, "Window", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
if(glewInit() != GLEW_OK)
std::cout << "Error!" << std::endl;
std::cout << glGetString(GL_VERSION) << std::endl;
float positions[6] = {
-0.5f, -0.5f,
0.0f, 0.5f,
0.5f, -0.5f
};
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
std::string vertexShader =
"#version 330 core\n"
"\n"
"layout(location = 0) in vec4 position;\n"
"\n"
"void main()\n"
"{\n"
" glPosition = position;\n"
"}\n";
std::string fragmentShader =
"#version 450 core\n"
"\n"
"layout(location = 0) out vec4 colour;\n"
"\n"
"void main()\n"
"{\n"
" colour = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
unsigned int shader = CreateShader(vertexShader, fragmentShader);
glUseProgram(shader);
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
When I run this code the console writes this:
2.1 NVIDIA-10.4.14 310.90.30.05b27
Failed to compile vertex shader!
ERROR: 0:1: '' : version '330' is not supported
ERROR: 0:1: '' : syntax error: #version
ERROR: 0:3: 'layout' : syntax error: syntax error
Failed to compile fragment shader!
ERROR: 0:1: '' : version '450' is not supported
ERROR: 0:1: '' : syntax error: #version
ERROR: 0:3: 'layout' : syntax error: syntax error
Program ended with exit code: 0
How can I fix this?
I'm macos 10.13.6, following the cherno's lesson, meet your trouble too.
I finish by doing 2 step:
add these line of code in front of glCreateWindow
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
cout << "I'm apple machine" << endl;
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
add VAO as #Ali ASkari memtion above
finally:
GLFWwindow *window;
if (!glfwInit()) {
cout << "glfw init err" << endl;
return -1;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
cout << "I'm apple machine" << endl;
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
unsigned int width = 800;
unsigned int height = 600;
window = glfwCreateWindow(width, height, "Learngl", NULL, NULL);
if (!window) {
cout << " can't create window!!!" << endl;
glfwTerminate();
return -1;
}
unsigned int major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR);
unsigned int minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR);
cout << "oepngl shader version: " << major << "." << minor << endl;
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK) {
cout << "Error ! " << endl;
}
cout << glGetString(GL_VERSION) << endl;
float positions[6] = {
-0.5f, -0.5f,
0.0f, 0.5f,
0.5f, -0.5f,
};
unsigned int VBO, VAO;
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, 6*sizeof(float), positions, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2, 0);
string vertexShader = "#version 330 core\n"
"layout (location = 0) in vec4 position;\n"
"void main()\n"
"{\n"
" gl_Position = position;\n"
"}\0";
string fragmentShader = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.0, 0.0, 0.5f);\n"
"}\n\0";
unsigned int shader = CreateShader(vertexShader, fragmentShader);
glUseProgram(shader);
while (!glfwWindowShouldClose(window)) {
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shader);
glfwTerminate();
Your c++ code style is the same as the older version of opengl(3.2 and older) and is not compatible with your shaders. You have two options. One is to downgrade your shaders to the old version. Another way is to update the C++ codes. a correct example of opengl 3.30 is like this:
#include <iostream>
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
// Window dimensions
const GLuint WIDTH = 800, HEIGHT = 600;
// Shaders
const GLchar* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);\n"
"}\0";
const GLchar* fragmentShaderSource = "#version 330 core\n"
"out vec4 color;\n"
"void main()\n"
"{\n"
"color = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
// The MAIN function, from here we start the application and run the game loop
int main()
{
std::cout << "Starting GLFW context, OpenGL 3.3" << std::endl;
// Init GLFW
glfwInit();
// Set all the required options for GLFW
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
// Create a GLFWwindow object that we can use for GLFW's functions
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "LearnOpenGL", nullptr, nullptr);
glfwMakeContextCurrent(window);
// Set the required callback functions
glfwSetKeyCallback(window, key_callback);
// Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
glewExperimental = GL_TRUE;
// Initialize GLEW to setup the OpenGL Function pointers
glewInit();
// Define the viewport dimensions
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
// Build and compile our shader program
// Vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// Check for compile time errors
GLint success;
GLchar 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;
}
// Fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// Check for compile time errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
// Link shaders
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// Check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
// Set up vertex data (and buffer(s)) and attribute pointers
//GLfloat vertices[] = {
// // First triangle
// 0.5f, 0.5f, // Top Right
// 0.5f, -0.5f, // Bottom Right
// -0.5f, 0.5f, // Top Left
// // Second triangle
// 0.5f, -0.5f, // Bottom Right
// -0.5f, -0.5f, // Bottom Left
// -0.5f, 0.5f // Top Left
//};
GLfloat vertices[] = {
0.5f, 0.5f, 0.0f, // Top Right
0.5f, -0.5f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, // Bottom Left
-0.5f, 0.5f, 0.0f // Top Left
};
GLuint indices[] = { // Note that we start from 0!
0, 1, 3, // First Triangle
1, 2, 3 // Second Triangle
};
GLuint VBO, VAO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
// Bind the Vertex Array Object first, then bind and set vertex buffer(s) and attribute pointer(s).
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0); // Note that this is allowed, the call to glVertexAttribPointer registered VBO as the currently bound vertex buffer object so afterwards we can safely unbind
glBindVertexArray(0); // Unbind VAO (it's always a good thing to unbind any buffer/array to prevent strange bugs), remember: do NOT unbind the EBO, keep it bound to this VAO
// Uncommenting this call will result in wireframe polygons.
//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
// Game loop
while (!glfwWindowShouldClose(window))
{
// Check if any events have been activiated (key pressed, mouse moved etc.) and call corresponding response functions
glfwPollEvents();
// Render
// Clear the colorbuffer
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw our first triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
//glDrawArrays(GL_TRIANGLES, 0, 6);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
// Swap the screen buffers
glfwSwapBuffers(window);
}
// Properly de-allocate all resources once they've outlived their purpose
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
// Terminate GLFW, clearing any resources allocated by GLFW.
glfwTerminate();
return 0;
}
// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
A big difference between the old version and the new versions is the need to use VAO in the new version.
I ran into this same problem when trying to run my code on MacOs after developing on my Windows machine. I added the following logic to make it run on MacOs.
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

opengl and GLFW3 simple triangle draw , cant see triangle

i try to paint simple triangle but i somehow can see the triangle
Here is my files
the window do created but no triangals in it dont know why
#include <iostream>
#include "GLFWManager.h"
#include <stdio.h>
#include <stdlib.h>
int main()
{
std::cout << "Hello World!\n";
GLFWManager gLFWManager;
gLFWManager.Init();
GLuint vbo;
GLuint vao;
GLfloat vertices[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f,
// second triangle
0.0f, -0.5f, 0.0f, // left
0.9f, -0.5f, 0.0f, // right
0.45f, 0.5f, 0.0f // top
};
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, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
// glBindBuffer(GL_ARRAY_BUFFER, 0);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
// glBindVertexArray(0);
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
int shaderProgram = gLFWManager.createShader();
// Set the clear color
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
while (!glfwWindowShouldClose(gLFWManager.window))
{
glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
// draw our first triangle
glUseProgram(shaderProgram);
glBindVertexArray(vao); // seeing as we only have a single VAO there's no need to bind it every time, but we'll do so to keep things a bit more organized
glDrawArrays(GL_TRIANGLES, 0,6); // set the count to 3 since we're drawing 3 vertices
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(gLFWManager.window);
glfwPollEvents();
}
// optional: de-allocate all resources once they've outlived their purpose:
// ------------------------------------------------------------------------
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
}
and this one :
#include "GLFWManager.h"
#include "stdio.h"
#include "stdlib.h"
int GLFWManager::windowHight = 300;
int GLFWManager::windowWidth = 300;
void GLFWManager::errorCallback(int error, const char* description)
{
fprintf(stderr, "Error: %s\n", description);
}
void GLFWManager::windowSizeCallbackcallback(GLFWwindow* window, int width, int height)
{
if (width > 0 && height > 0) {
windowHight = height;
windowWidth = width;
}
}
static void KeyCallback(GLFWwindow* window, int key, int, int action, int mods)
{
switch (key)
{
case GLFW_KEY_ESCAPE:
{
if (action == GLFW_RELEASE)
{
glfwSetWindowShouldClose(window, GLFW_PRESS);
}
}
}
}
GLFWManager::GLFWManager()
{
window = nullptr;
}
GLFWManager::~GLFWManager()
{
}
void GLFWManager::Init()
{
glfwSetErrorCallback(GLFWManager::errorCallback);
if (!glfwInit())
{
exit(EXIT_FAILURE);
}
setWindowsHints();
createWindow();
glfwSetKeyCallback(window, KeyCallback);
glfwSetWindowSizeCallback(window, GLFWManager::windowSizeCallbackcallback);
const GLFWvidmode *vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(window, (vidmode->width - windowWidth) /2 , (vidmode->height - windowHight) /2);
glfwGetFramebufferSize(window, &windowWidth, &windowHight);
glfwMakeContextCurrent(window);
glfwSwapInterval(1);
glfwShowWindow(window);
loadGlad();
}
void GLFWManager::setWindowsHints()
{
glfwDefaultWindowHints();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
}
void GLFWManager::createWindow()
{
window = glfwCreateWindow(windowWidth,windowHight, "Test", NULL, NULL);
if (!window)
{
exit(EXIT_FAILURE);
}
}
void GLFWManager::loadGlad()
{
// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
fprintf(stderr, "Failed to initialize GLAD");
exit(EXIT_FAILURE);
}
// get version info
const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
const GLubyte* version = glGetString(GL_VERSION); // version as a string
printf("Renderer: %s\n", renderer);
printf("OpenGL version supported %s\n", version);
}
int GLFWManager::createShader()
{
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\n\0";
// build and compile our shader program
// ------------------------------------
// vertex shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// check for shader compile errors
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
printf("ERROR::SHADER::VERTEX::COMPILATION_FAILED\n %s\n ",infoLog);
}
// fragment shader
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// check for shader compile errors
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
printf("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n %s \n",infoLog);
}
// link shaders
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
// check for linking errors
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
printf("ERROR::SHADER::PROGRAM::LINKING_FAILED\n %s \n",infoLog);
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
return shaderProgram;
}
glVertexAttribPointer and glEnableVertexAttribArray specify and enable an array of vertex attribute data and sets states in the state vector of the currently bound Vertex Array Object.
You have to bind the vertex array object (glBindVertexArray) before you can specify the vertex arrays:
// Create vertex buffer object
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Create Vertex array object
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// specify array of generic vertex array data
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
Note, before you call glVertexAttribPointer, the Vertex Array Object and the Vertex Buffer Object have to be bound, because glVertexAttribPointer associates the buffer which is currently bound to the ARRAY_BUFFER target, to the attribute with the specified index, in the state vector of the currently bound VAO.

Shader converting nonzero uint to 255

I am trying to implement polygon selection through clicking by first drawing triangle IDs to an off-screen framebuffer and then reading back pixel values at clicked positions via glReadPixels. I am passing ID as unsigned integer to each vertex (and I confirmed that the buffer is correct from apitrace) and outputting it as uvec4 in fragment shader. I set up the framebuffer as RGBA8UI texture (also confirmed units to be correct from apitrace). There is no opengl error and also checked that framebuffer is complete.
The problem is that the output image where the IDs should be always has a value of 255. The area covered by the triangles are modified from the glClear value but they are not (id, 0, 0, 0) but always (255, 0, 0, 0). The exception is those with ID of 0. It seems like somewhere in the shader, the ID is converted to 255 if the ID is not 0. Is this the expected behavior from the code below? Am I doing something wrong?
Vertex buffer:
x (float), y (float), z (float), tx (float), ty (float), id (unsigned int)
Vertex shader:
#version 330 core
// Input
layout(location = 0) in vec3 position;
layout(location = 1) in vec2 texCoord;
layout(location = 2) in uint id;
// Output (Varying)
out vec2 v_texCoord;
flat out uint v_id;
// Uniform
uniform mat4 u_model;
uniform mat4 u_view;
uniform mat4 u_projection;
void main()
{
v_texCoord = texCoord;
v_id = id;
gl_Position = u_projection * u_view * u_model * vec4(position, 1.0);
}
Fragment shader:
#version 330 core
// Input (Varying)
in vec2 v_texCoord;
flat in uint v_id;
// Output
layout(location = 0) out uvec4 color;
void main()
{
color = uvec4(v_id, 0, 0, 0);
}
GL_VERSION is 3.3.0 NVIDIA 419.35 and I have updated the driver yesterday.
-- Edit --
I was down-voted for lack of information so I created a separate project that just shows my point above with the rest of the code below:
#include <glad/glad.h> // Must be included before GLFW header
#include <GLFW/glfw3.h>
#include <iostream>
#include <vector>
const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 800;
int main()
{
// glfw: initialize and configure
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// glfw window creation
GLFWwindow* window = glfwCreateWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// glad: load all OpenGL function pointers
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
std::cout << glGetString(GL_VERSION) << std::endl;
// Vertex and fragment shaders
GLuint shader = glCreateProgram();
{
GLint isSuccess = false;
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
// Vertex shader
{
const GLchar* vertexShaderSource =
"#version 330 core\n"
"layout(location = 0) in vec2 position;\n"
"layout(location = 1) in uint id;\n"
"flat out uint v_id;\n"
"void main() {v_id = id; gl_Position = vec4(position.x, position.y, 0.0, 1.0);}\n";
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
glCompileShader(vertexShader);
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &isSuccess);
std::cout << "Vertex shader compile status: " << isSuccess << std::endl;
}
// Fragment shader
{
const GLchar* fragmentShaderSource =
"#version 330 core\n"
"layout(location = 0) out uvec4 color;\n"
"flat in uint v_id;\n"
"void main() {color = uvec4(v_id, 0, 0, 0);}\n";
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &isSuccess);
std::cout << "Fragment shader compile status: " << isSuccess << std::endl;
}
glAttachShader(shader, vertexShader);
glAttachShader(shader, fragmentShader);
glLinkProgram(shader);
glGetProgramiv(shader, GL_LINK_STATUS, &isSuccess);
std::cout << "Shader link status: " << isSuccess << std::endl;
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
}
// Vertex Buffer
GLuint vertexBuffer;
{
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
GLfloat data[] = {
// x y id
-1.0f, 0.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
0.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f
};
GLuint* data2 = ((GLuint *)data);
data2[2] = 0;
data2[5] = 0;
data2[8] = 0;
data2[11] = 1;
data2[14] = 1;
data2[17] = 1;
std::cout << "Size of GLuint: " << sizeof(GLuint) << std::endl;
std::cout << "Size of GLfloat: " << sizeof(GLfloat) << std::endl;
std::cout << "Size of vertex buffer: " << sizeof(data) << std::endl;
glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
// Vertex Array
GLuint vertexArray;
{
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 1, GL_UNSIGNED_INT, GL_FALSE, 3 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
// Texture for framebuffer
GLuint texture;
glGenTextures(1, &texture);
{
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, WINDOW_WIDTH, WINDOW_HEIGHT, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, nullptr);
glBindTexture(GL_TEXTURE_2D, 0);
}
// Framebuffer
GLuint framebuffer;
{
GLenum completenessStatus;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
std::cout << "Framebuffer status: " << (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
// Clear
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
GLenum error = glGetError();
std::cout << "No error: " << (error == GL_NO_ERROR) << std::endl;
// Draw
while (!glfwWindowShouldClose(window))
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
glClear(GL_COLOR_BUFFER_BIT);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
{
glDisable(GL_DITHER);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader);
glBindVertexArray(vertexArray);
glActiveTexture(GL_TEXTURE0);
glDrawArrays(GL_TRIANGLES, 0, 6);
glEnable(GL_DITHER);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteProgram(shader);
glDeleteBuffers(1, &vertexBuffer);
glDeleteVertexArrays(1, &vertexArray);
glDeleteFramebuffers(1, &framebuffer);
glDeleteTextures(1, &texture);
return 0;
}
Output:
3.3.0 NVIDIA 419.35
Vertex shader compile status: 1
Fragment shader compile status: 1
Shader link status: 1
Size of GLuint: 4
Size of GLfloat: 4
Size of vertex buffer: 72
Framebuffer status: 1
No error: 1
Framebuffer is RGBA8UI:
Vertices are correct:
Triangle with ID of 0 is colored as (0, 0, 0, 0) as expected:
Area outside triangle is (255, 255, 255, 255) as expected (glClearColor is white):
Triangle with ID of 1 is colored as (255, 0, 0, 0). It should be (1, 0, 0, 0):
The same issue occurs for ID > 1. Why is this the case? How can I make it so that the color is (ID, 0, 0, 0) as shown in the fragment shader?
You have to use glVertexAttribIPointer (focus on I), when defining the array of generic vertex attribute data, for the vertex attribute in uint id;.
When vertex attribute data are defined by glVertexAttribPointer, then they will be converted to floating point values.
See OpenGL 4.6 API Core Profile Specification; 10.2. CURRENT VERTEX ATTRIBUTE VALUES; page 344
The VertexAttribI* commands specify signed or unsigned fixed-point values
that are stored as signed or unsigned integers, respectively. Such values are referred to as pure integers.
...
All other VertexAttrib* commands specify values that are converted directly to the internal floating-point representation.

OpenGL - Hello triangle not showing up

I have my OpenGL - Hello Triangle demo here but I cant make it work. Does anybody know where the problem can be? I am able to compile and run the code but triangle does not show up. It only opens window with grey background.
#include <glew/glew.h>
#include <glfw/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
if (!glfwInit()) {
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
GLFWwindow* window = glfwCreateWindow(800, 800, "Anton Tutorials - Hello Triangle", NULL, NULL);
if (window == NULL) {
fprintf(stderr, "Failed to open GLFW window.\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE; // Needed in core profile
const GLenum err = glewInit();
if (err != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
return -1;
}
// Enable depth-testing
glEnable(GL_DEPTH_TEST);
// Depth-testing interprets a smaller value as "closer"
glDepthFunc(GL_LESS);
//Defining vertices for triangle
GLfloat points[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
//Vertex buffer object creation
GLuint vbo = 0;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
//Vertex attribute object creation
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
//Loading shaders - Vertex shader
const char* vertex_shader =
"#version 410\n"
"in vec3 vp; "
"void main() {"
" gl_Position = vec4 (vp, 1.0);"
" }";
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
//Loading shaders - Fragment shader
const char* fragment_shader =
"#version 410\n"
"out vec4 frag_colour; "
"void main() {"
" frag_colour = vec4 (0.5, 0.0, 0.5, 1.0);"
" }";
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
//Attach shaders
GLuint shader_programme = glCreateProgram();
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme);
//RenderLoop
while (!glfwWindowShouldClose(window))
{
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader_programme);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
You need to enable the 'vp' attribute.
Earlier in your code, you say this:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
If the layout location of your vp shader variable changes, this might now longer be valid.
It would be better to do this:
GLint vpAttr = glGetAttribLocation(shader_programme, "vp");
glVertexAttribPointer(vpAttr, 3, GL_FLOAT, GL_FALSE, 0, NULL);
Then enable the attribute:
glEnableVertexAttribArray(vpAttr);
Otherwise, you should explicitly set the layout location of vp in vertex shader, so you can confidently use 0:
"layout (location=0) in vec3 vp;"

Triangles not being drawn on screen openGL even when no error is occurred

I have written a simple openGL program to draw a triangle on the screen. I have done debugging with glGetError() and now there is no error in the code but when I try to run it only a black screen comes up.
here is my code. I am using GLFW for window creation.
#include<glew.h>
#include<glfw3.h>
#include<stdio.h>
int main(int argc, char ** argv)
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
float vertices[] = {
0.0f, 0.5f,
0.5f, -0.5f,
-0.5f, -0.5f
};
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
const GLchar * vs =
"#version 150\n"
"in vec2 position;\n"
"void main() {\n"
"vec4 gl_Position = vec4( position , 0.0 , 1.0 );\n"
"}";
const GLchar * fs =
"#version 150\n"
"out vec4 out_color; \n"
"void main() { \n"
"out_color = vec4(1.0, 1.0, 1.0, 1.0);\n"
"}";
GLuint vsh = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vsh, 1, &vs, NULL);
glCompileShader(vsh);
GLint status;
glGetShaderiv(vsh, GL_COMPILE_STATUS, &status);
if (status == GL_TRUE) printf("Vertex Shader Compiled success\n");
GLuint fsh = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fsh, 1, &fs, NULL);
glCompileShader(fsh);
glGetShaderiv(fsh, GL_COMPILE_STATUS, &status);
if (status == GL_TRUE) printf("Fragment Shader Compiled success\n");
GLuint sp = glCreateProgram();
glAttachShader(sp, vsh);
glAttachShader(sp, fsh);
glBindFragDataLocation(sp, 0, "out_color");
glBindAttribLocation(sp,1,"position");
glLinkProgram(sp);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
glUseProgram(sp);
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
Update
I have narrowed down the issue to just one line of code
GLint pos = glGetAttribLocation(sp, "position") //sp is shader program
The problem is it is returning -1. I have read in tutorials that if you don't use a variable it will be optimized out by the compiler.I have used the position in the code then why it is getting thrown away. Below is my vertex shader.
const GLchar * vs =
"#version 150\n"
"in vec2 position;\n"
"void main() {\n"
"vec4 gl_Position = vec4( position , 0.0 , 1.0 );\n"
"}";
just add these lines after
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
I mean use location 0 instead of 1
hope this helps