triangle dont appear in opengl? [closed] - c++

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I can get Opengl triangle to appear.
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
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";
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); }
}
int main()
{
glewExperimental = GL_TRUE;
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window{ glfwCreateWindow(800,600,"Opengl",NULL,NULL) };
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwMakeContextCurrent(window);
GLenum err = glewInit();
if (glewInit() != GLEW_OK) { std::cout << glewGetErrorString(err); return -1; }
int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader,1,&fragmentShaderSource,NULL);
glCompileShader(fragmentShader);
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram,vertexShader);
glAttachShader(shaderProgram,fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
float triangle[]{ -0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0,
0.0f,-0.5f,0.0f };
unsigned int VAO,buffer;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangle), triangle, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
if (window == NULL) {
std::cout << "Window is null";
glfwTerminate();
return -1;
}
while (!glfwWindowShouldClose(window))
{
processInput(window);
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES,0,3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}

All your triangle vertices are colinear, resulting in a degenerate triangle
Bumping the y-coordinate of the 3rd point up to 0.5 works for me:
float triangle[]
{
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
};
All together:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
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";
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 );
}
}
int main()
{
glewExperimental = GL_TRUE;
glfwInit();
glfwWindowHint( GLFW_CONTEXT_VERSION_MAJOR, 3 );
glfwWindowHint( GLFW_CONTEXT_VERSION_MINOR, 3 );
glfwWindowHint( GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE );
GLFWwindow* window{ glfwCreateWindow( 800, 600, "Opengl", NULL, NULL ) };
glfwSetFramebufferSizeCallback( window, framebuffer_size_callback );
glfwMakeContextCurrent( window );
GLenum err = glewInit();
if( glewInit() != GLEW_OK )
{
std::cout << glewGetErrorString( err );
return -1;
}
int vertexShader;
vertexShader = glCreateShader( GL_VERTEX_SHADER );
glShaderSource( vertexShader, 1, &vertexShaderSource, NULL );
glCompileShader( vertexShader );
int fragmentShader;
fragmentShader = glCreateShader( GL_FRAGMENT_SHADER );
glShaderSource( fragmentShader, 1, &fragmentShaderSource, NULL );
glCompileShader( fragmentShader );
int shaderProgram = glCreateProgram();
glAttachShader( shaderProgram, vertexShader );
glAttachShader( shaderProgram, fragmentShader );
glLinkProgram( shaderProgram );
glDeleteShader( vertexShader );
glDeleteShader( fragmentShader );
float triangle[]{
-0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f,
};
unsigned int VAO, buffer;
glGenVertexArrays( 1, &VAO );
glBindVertexArray( VAO );
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
glBufferData(
GL_ARRAY_BUFFER, sizeof( triangle ), triangle, GL_STATIC_DRAW );
glVertexAttribPointer(
0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof( float ), (void*)0 );
glEnableVertexAttribArray( 0 );
glBindBuffer( GL_ARRAY_BUFFER, 0 );
glBindVertexArray( 0 );
if( window == NULL )
{
std::cout << "Window is null";
glfwTerminate();
return -1;
}
while( !glfwWindowShouldClose( window ) )
{
processInput( window );
glClearColor( 0.2f, 0.2f, 0.2f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT );
glUseProgram( shaderProgram );
glBindVertexArray( VAO );
glDrawArrays( GL_TRIANGLES, 0, 3 );
glfwSwapBuffers( window );
glfwPollEvents();
}
glfwTerminate();
return 0;
}

Related

OpenGL: glGenVertexArrays() gives EXC_BAD_ACCESS

When I use OpenGL and run my code to make a triangle the function glGenVertexArrays() gives me EXE_BAD_ACCESS
Error
Code:
#include <iostream>
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <cmath>
// Window specs
const int HEIGHT = 800;
const int WIDTH = 600;
// Shader source code
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(0.8f, 0.3f, 0.02f, 1.0f);\n"
"}\n\0";
int main(void)
{
if (!glfwInit())
{
std::cout<<"GLFW failed to Initialize!"<<std::endl;
return -1;
}
GLfloat vertices[] =
{
-0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,
0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,
0.0f, 0.5f * float(sqrt(3)) * 2 / 3, 0.0f
};
GLFWwindow* window = glfwCreateWindow(WIDTH, HEIGHT, "Open GL", NULL, NULL);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
glfwMakeContextCurrent(window);
if(!window)
{
std::cout<<"Something went Wrong when Creating a Window!\nShutting down ..."<<std::endl;
glfwTerminate();
return -1;
}
//
gladLoadGL();
glViewport(0, 0, WIDTH, HEIGHT);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
//
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
GLuint VAO;
GLuint VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
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);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while(!glfwWindowShouldClose(window))
{
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
I used glad to write the code. Does anybody have any idea how to fix this or what I did wrong.
To recreate it use Xcode 13.2.1 then link Glad using Opengl 4.1 and GLFW and make it look something like this
File Layout
Then paste the code into main and run.
A few things:
glfwWindowHint() only affects the next glfwCreateWindow() call so make sure to call them before you create a window. The default hint settings will generally give you a version 2.1 Compatibility context on macOS which won't be able to handle #version 330 core GLSL code.
GLFW_CONTEXT_VERSION_MAJOR was used twice; you need a GLFW_CONTEXT_VERSION_MINOR too.
macOS needs GLFW_OPENGL_FORWARD_COMPAT set to GLFW_TRUE for Core contexts.
Check for shader compilation/link errors.
Your GLAD might have been out of sync for the GL version you were targeting; see the generator link in the comments for the settings I used.
GLFW has a perfectly usable GLADloadproc in glfwGetProcAddress(); might as well switch from gladLoadGL() to gladLoadGLLoader().
Supplying a glfwSetErrorCallback() can get you some early/immediate error reporting from GLFW. It's how I discovered the missing GLFW_CONTEXT_VERSION_MINOR hint. No reason not to use it.
All together:
// g++ -Iinclude main.cpp src/glad.c `pkg-config --cflags --libs glfw3`
// Commandline:
// --profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --no-loader --extensions=""
// Online:
// https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&api=gl%3D3.3
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cmath>
void CheckStatus( GLuint obj, bool isShader )
{
GLint status = GL_FALSE, log[ 1 << 11 ] = { 0 };
( isShader ? glGetShaderiv : glGetProgramiv )( obj, isShader ? GL_COMPILE_STATUS : GL_LINK_STATUS, &status );
if( status == GL_TRUE ) return;
( isShader ? glGetShaderInfoLog : glGetProgramInfoLog )( obj, sizeof( log ), NULL, (GLchar*)log );
std::cerr << (GLchar*)log << "\n";
std::exit( EXIT_FAILURE );
}
void AttachShader( GLuint program, GLenum type, const char* src )
{
GLuint shader = glCreateShader( type );
glShaderSource( shader, 1, &src, NULL );
glCompileShader( shader );
CheckStatus( shader, true );
glAttachShader( program, shader );
glDeleteShader( shader );
}
const char* const vert = 1 + R"GLSL(
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
};
)GLSL";
const char* const frag = 1 + R"GLSL(
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(0.8f, 0.3f, 0.02f, 1.0f);
}
)GLSL";
int main(void)
{
glfwSetErrorCallback( []( int, const char* desc )
{
std::cerr << desc << "\n";
std::exit( EXIT_FAILURE );
} );
if (!glfwInit())
{
std::cout<<"GLFW failed to Initialize!"<<std::endl;
return -1;
}
GLfloat vertices[] =
{
-0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,
0.5f, -0.5f * float(sqrt(3)) / 3, 0.0f,
0.0f, 0.5f * float(sqrt(3)) * 2 / 3, 0.0f
};
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, GLFW_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_FALSE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Open GL", NULL, NULL);
if(!window)
{
std::cout<<"Something went Wrong when Creating a Window!\nShutting down ..."<<std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
gladLoadGLLoader( (GLADloadproc)glfwGetProcAddress );
glViewport(0, 0, 800, 600);
GLuint prog = glCreateProgram();
AttachShader( prog, GL_VERTEX_SHADER, vert );
AttachShader( prog, GL_FRAGMENT_SHADER, frag );
glLinkProgram( prog );
CheckStatus( prog, false );
glUseProgram( prog );
GLuint VAO;
GLuint VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
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);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while(!glfwWindowShouldClose(window))
{
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(prog);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(prog);
glfwDestroyWindow(window);
glfwTerminate();
return 0;
}
Note that with a 3.3 core profile on MacOS you may also need to call glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
by GM at comment Section and genpfault

Don't get OpenGL output when using glVertexAttribFormat

I'm trying to use glVertexAttribFormat and glVertexAttribBinding to create two triangles, but it doesn't work. I followed the description of how to do this in the question here (Render one VAO containing two VBOs). I don't really knnow what to try. I am new to OpenGL and all descriptions of glVertexAttribFormat appear to assume you already know OpenGL.
This is my code:
#include <glad/glad.h>
#include <glfw/glfw3.h>
#include <iostream>
void adjustViewportToWindowSize(GLFWwindow* window, int width, int height);
void checkEsc(GLFWwindow* window);
int main(void)
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "Tab name", 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); //size of GL rendering window.
glfwSetFramebufferSizeCallback(window, adjustViewportToWindowSize);
const char* vertexShaderSource = "#version 430 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 430 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\0";
unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
unsigned int shaderProgram;
shaderProgram = glCreateProgram();
//Attaching shaders to program
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
//Can delete shader objects after they are linked
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
float triangleVertices1[] = {
-0.50f, 0.0f, 0.0f,
-0.25f, 0.5f, 0.0f,
0.00f, 0.0f, 0.0f
};
float triangleVertices2[] = {
0.0f, 0.0f, 0.0f,
0.25f, 0.5f, 0.0f,
0.5f, 0.0f, 0.0f
};
unsigned int aVBO[2], VAO2;
glGenVertexArrays(1, &VAO2);
glBindVertexArray(VAO2);
glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0); //format setup without a buffer
glVertexAttribBinding(0, 0);
glBindVertexArray(0);
//Bind Buffers to data next
glGenBuffers(2, aVBO);
glBindBuffer(GL_ARRAY_BUFFER, aVBO[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices1), triangleVertices1, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, aVBO[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices2), triangleVertices2, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
while (!glfwWindowShouldClose(window))
{
checkEsc(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO2);
glBindVertexBuffer(0, aVBO[0], 0, 3*sizeof(float));
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexBuffer(0, aVBO[1], 0, 3*sizeof(float));
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
//Clear up
glDeleteVertexArrays(1, &VAO2);
glDeleteBuffers(1, aVBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}
void adjustViewportToWindowSize(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
void checkEsc(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
Can also be accessed on github: https://github.com/Ritzerk/OpenGLSelfStudy
In addition to setting up the buffer bindings, you also have to enable the vertex attribute in the shader. To do so, you have to call glEnableVertexAttribArray during VAO setup:
glBindVertexArray(VAO2);
glVertexAttribFormat(0, 3, GL_FLOAT, GL_FALSE, 0);
glVertexAttribBinding(0, 0);
//Enable input in shader
glEnableVertexAttribArray(0);
glBindVertexArray(0);

Trying to Draw a point cloud, just a single point in the center in opengl

Trying to create a random point cloud in 2D. However, I've got this in the end for now : The background color + 1 single 'grey' point in the center. What might have gone wrong here?
I try writing my own simple shader.
Trying to compile shader by myself.
All are supposed to be baby steps.
Also what would be some tips of debugging these issues?
#include <vector>
#include <algorithm>
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow* window;
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/norm.hpp>
/* SHADERS */
/* Vertex Shader */
const char *VertexShaderSource="#version 330 core\n"
"layout(location=0) in vec2 pos;\n"
"//layout(location=1) in vec2 da;//distance and angle \n"
"//layout(location=2) in vec4 color;\n"
"\n"
"out vec4 particle_color\n"
"uniform mat4 mvp;\n"
"int main(){\n"
"gl_Position = mvp*vec4(pos, 0.0,1.0));\n"
"//particle_color =;\n"
"}\n";
/* Fragment Shader*/
const char *FragmentShaderSource="#version 330 core\n"
"//in vec4 particle_color;\n"
"out vec4 color;\n"
"//layout(location=2) in vec4 color;\n"
"void main(){\n"
"color = vec4(1.0f,0.0f,0.0f,1.0f);\n"
"}\n";
/* SHADERS END */
// Particle
struct Point{
glm::vec2 pos;
// Create random color in GPU
// unsigned char r,g,b,a;
float distance;
float angle;
};
static const int max_point_number=1000;
Point PointContainer[max_point_number];
int main()
{
// Start GLFW
if(!glfwInit())
{
std::cout<<"Failed to start GLWF\n";
getchar();
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
//glfwWindowHint(GLFW_RESIZABLE,GL,FALSE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(800, 600, "Rotating Points", NULL, NULL);
if(window == NULL)
{
std::cout<<"Initialization of the window failed\n";
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Start GLEW;
glewExperimental = true;
if(glewInit() != GLEW_OK)
{
std::cout<<"Failed to start GLEW\n";
getchar();
return -1;
}
glfwPollEvents();
glClearColor(.0f,0.5f,0.5f,0.0f); // Black is the new orange
// Camera
glm::mat4 Projection = glm::ortho(0.0f,800.0f, 0.0f,600.0f,-5.0f,5.0f); // In world coordinates
glm::mat4 View = glm::lookAt(
glm::vec3(0,0,-1), // Camera is at (0,0,-1), in World Space
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 mvp = Projection * View * Model; // Remember, matrix multiplication is the other way around
// No need to have depth test
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Build and compile shaders
// Vertex Shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &VertexShaderSource, NULL);
glCompileShader(vertexShader);
// Fragment Shader
int fragmentShader=glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &FragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// Link Shaders
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
// Delete Shaders after Linking
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
for(auto &p:PointContainer)
{
p.pos.x =rand() % 800;
p.pos.y =rand() % 600;
std::cout<<p.pos.x<<" "<<p.pos.y<<"\n";
}
// Vertex Shader
GLuint tPM = glGetUniformLocation(shaderProgram, "mvp");//mvp
glUniformMatrix4fv(tPM, 1, GL_FALSE, &mvp[0][0]);
GLuint pointsVertexBuffer;
glGenBuffers(1, &pointsVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pointsVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(PointContainer), PointContainer, GL_STREAM_DRAW); // Start with NULL, update with frames;
do
{
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
//glDrawArraysInstanced(GL_POINTS, 0, 2, max_point_number);
glBindBuffer( GL_ARRAY_BUFFER, pointsVertexBuffer );
glEnableClientState( GL_VERTEX_ARRAY );
//glEnableClientState( GL_COLOR_ARRAY );
glVertexPointer( 4, GL_FLOAT, sizeof( Point ), (void*)offsetof( Point, pos ) );
//glColorPointer( 4, GL_FLOAT, sizeof( Vertex ), (void*)offsetof( Vertex, color ) );
glDrawArrays( GL_POINTS, 0, max_point_number);
glDisableClientState( GL_VERTEX_ARRAY );
//glDisableClientState( GL_COLOR_ARRAY );
glBindBuffer( GL_ARRAY_BUFFER, 0 ); // Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwWindowShouldClose(window) == 0 );
return 0;
}
Edit:
I edited the code, still gives the same result.
#include <vector>
#include <algorithm>
#include <iostream>`
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow* window;
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtx/norm.hpp>
/* SHADERS */
/* Vertex Shader */
const char *VertexShaderSource=R"(
#version 330 core
layout(location=0) in vec2 pos;
uniform mat4 mvp;
int main(){
gl_Position = mvp*vec4(pos, 0.0,1.0);
}
)";
/* Fragment Shader*/
const char *FragmentShaderSource = R"(
#version 330 core
out vec4 color;
void main(){
color = vec4(1.0f);
}
)";
/* SHADERS END */
// Particle
struct Point{
glm::vec2 pos;
// Create random color in GPU
// unsigned char r,g,b,a;
float distance;
float angle;
};
static const int max_point_number=1000;
Point PointContainer[max_point_number];
int main()
{
// Start GLFW
if(!glfwInit())
{
std::cout<<"Failed to start GLWF\n";
getchar();
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
//glfwWindowHint(GLFW_RESIZABLE,GL,FALSE);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3);
glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(800, 600, "Rotating Points", NULL, NULL);
if(window == NULL)
{
std::cout<<"Initialization of the window failed\n";
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Start GLEW;
glewExperimental = true;
if(glewInit() != GLEW_OK)
{
std::cout<<"Failed to start GLEW\n";
getchar();
return -1;
}
glfwPollEvents();
glClearColor(.0f,0.0f,0.0f,0.0f); // Black is the new orange
// Camera
glm::mat4 Projection = glm::ortho(0.0f,800.0f, 0.0f,600.0f,-5.0f,5.0f); // In world coordinates
glm::mat4 View = glm::lookAt(
glm::vec3(0,0,1), // Camera is at (0,0,-1), in World Space
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 mvp = Projection * View * Model; // Remember, matrix multiplication is the other way around
// No need to have depth test
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Build and compile shaders
// Vertex Shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &VertexShaderSource, NULL);
glCompileShader(vertexShader);
// Fragment Shader
int fragmentShader=glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &FragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// Link Shaders
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
// Delete Shaders after Linking
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
for(auto &p:PointContainer)
{
p.pos.x =(rand() % 800)*-1;
p.pos.y =rand() % 600;
std::cout<<p.pos.x<<" "<<p.pos.y<<"\n";
}
// Vertex Shader
GLuint tPM = glGetUniformLocation(shaderProgram, "mvp");//mvp
glUniformMatrix4fv(tPM, 1, GL_FALSE, &mvp[0][0]);
GLuint pointsVertexBuffer;
glGenBuffers(1, &pointsVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pointsVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(PointContainer), PointContainer, GL_STREAM_DRAW); // Start with NULL, update with frames;
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0 );
glEnableVertexAttribArray( 0 );
do
{
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDrawArrays( GL_POINTS, 0, max_point_number);
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwWindowShouldClose(window) == 0 );
return 0;
}
The vertex shader doesn't even compile. A ;is missing affter out vec4 particle_color, the return type of main has to be void and at the end of gl_Position = mvp*vec4(pos, 0.0,1.0)); there is one ) to many.
I recommend to use a Raw string literal:
const char *VertexShaderSource = R"(
#version 330 core
layout(location=0) in vec2 pos;
uniform mat4 mvp;
void main(){
gl_Position = mvp*vec4(pos, 0.0,1.0);
}
)";
Since you use a core profile Context you've to use a Vertex Array Object. e.g.:
GLuint pointsVertexBuffer;
glGenBuffers(1, &pointsVertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, pointsVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(PointContainer), PointContainer, GL_STREAM_DRAW); // Start with NULL, update with frames;
GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 4*sizeof(float), 0 );
glEnableVertexAttribArray( 0 );
do
{
// Clear the screen
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDrawArrays( GL_POINTS, 0, max_point_number);
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwWindowShouldClose(window) == 0 );
You've an orthographic projection from (0, 0) to (600, 800), so the view matrix has to be
glm::mat4 View = glm::lookAt(
glm::vec3(0,0,1), // Camera is at (0,0,-1), in World Space
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
Note, with your view matrix the points are drawn at the left of the viewport, so you can't see them. The point would be drawn in in the rectangle from (0, 0) to (-800, 600).
Change the color of the points in the fragment shader. The red color is hardly to see on the green ground:
const char *FragmentShaderSource = R"(
#version 330 core
out vec4 color;
void main(){
color = vec4(1.0f);
}
)";
I recommend to verify if the shader succeeded to compile by glGetShaderiv. e.g.:
glGetShaderiv( vertexShader, GL_COMPILE_STATUS, &status );
if ( status == GL_FALSE )
{
GLint logLen;
glGetShaderiv( vertexShader, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetShaderInfoLog( vertexShader, logLen, &written, log.data() );
std::cout << "compile error:" << std::endl << log.data() << std::endl;
}
and the program succeeded to link by glGetProgramiv. e.g.:
glGetProgramiv( shaderProgram, GL_LINK_STATUS, &status );
if ( status == GL_FALSE )
{
GLint logLen;
glGetProgramiv( shaderProgram, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetProgramInfoLog( shaderProgram, logLen, &written, log.data() );
std::cout << "link error:" << std::endl << log.data() << std::endl;
}

printing a red triangle in openGL

I have the following code and am trying to print a red triangle using opengl glew ect. The program builds and shows a triangle, however it only shows a triangle when I drag the window, and the triangle shows up white not red. Not sure how to fix this issue. Below is a copy of my code (I am running in xcode).
#include <iostream>
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
// GLFW
#include <GLFW/glfw3.h>
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;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
std::cout << "Error!" << 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, 2 * sizeof(float), 0);
std::string vertexShader =
"#version 330 core\n"
"\n"
"layout(location = 0) in vec4 position;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = position;\n"
"}\n";
std::string fragmentShader =
"#version 330 core\n"
"\n"
"layout(location = 0) out vec4 color;\n"
"\n"
"void main()\n"
"{\n"
" color = vec4(1.0, 0.0, 0.0, 1.0);\n"
"}\n";
unsigned int shader = CreateShader(vertexShader, fragmentShader);
glUseProgram(shader);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glDeleteProgram(shader);
glfwTerminate();
return 0;
}
I am using xCode and am having 2 issues:
1. the triangle is printing out white
2. the triangle only shows up when i drag the window
I have tried debugging but am not able to figure these issues out.
You need to go whole-hog on Core contexts on macOS if you want anything past GL 2.1:
Request a versioned Core context via GLFW_OPENGL_PROFILE, GLFW_CONTEXT_VERSION_MAJOR, and GLFW_CONTEXT_VERSION_MINOR; it should meet or exceed the #version you're specifying in your shaders
For macOS in particular you need a forward-compatbile context; set GLFW_OPENGL_FORWARD_COMPAT to GL_TRUE
Core contexts require a vertex array object (VAO) to draw anything; for simple stuff you can get away with creating a single one and leaving it bound
All together:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <vector>
#include <iostream>
#include <cstdarg>
struct Program
{
static GLuint Load( const char* shader, ... )
{
GLuint prog = glCreateProgram();
va_list args;
va_start( args, shader );
while( shader )
{
const GLenum type = va_arg( args, GLenum );
AttachShader( prog, type, shader );
shader = va_arg( args, const char* );
}
va_end( args );
glLinkProgram( prog );
CheckStatus( prog );
return prog;
}
private:
static void CheckStatus( GLuint obj )
{
GLint status = GL_FALSE;
if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
if( status == GL_TRUE ) return;
GLchar log[ 1 << 15 ] = { 0 };
if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
std::cerr << log << std::endl;
std::exit( EXIT_FAILURE );
}
static void AttachShader( GLuint program, GLenum type, const char* src )
{
GLuint shader = glCreateShader( type );
glShaderSource( shader, 1, &src, NULL );
glCompileShader( shader );
CheckStatus( shader );
glAttachShader( program, shader );
glDeleteShader( shader );
}
};
const char* vert = 1 + R"GLSL(
#version 330 core
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
};
)GLSL";
const char* frag = 1 + R"GLSL(
#version 330 core
layout(location = 0) out vec4 color;
void main()
{
color = vec4(1.0, 0.0, 0.0, 1.0);
}
)GLSL";
int main(void)
{
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
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 );
GLFWwindow* window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
std::cout << "Error!" << std::endl;
GLuint vao = 0;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );
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, 2 * sizeof(float), 0);
GLuint shader = Program::Load( vert, GL_VERTEX_SHADER, frag, GL_FRAGMENT_SHADER, NULL );
glUseProgram(shader);
glBindBuffer(GL_ARRAY_BUFFER, 0);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glDeleteProgram(shader);
glfwTerminate();
return 0;
}
Your problem may be in vertex shader because in vertex shader "layout(location = 0) in vec4 position;\n"
here you define vec4 but in you are sending vec2 from glVertexAttribPointer() function.
Try to send vec4 or try this in vertex shader
std::string vertexShader =
"#version 330 core\n"
"\n"
"layout(location = 0) in vec2 position;\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = vec4(position, 0, 1);\n"
"}\n";

OpenGL, a very basic shader not working

I am learning OpenGL through TheCherno Project.
The code below is from there and I faithfully reproduce it for my learning purpose. I have also added both vertex and fragment shaders as well.
My issue here is in my square output I don't see the color at all and I am guessing it is using the default shader.
int main(void)
{
GLFWwindow* window;
/* Initialize the library */
if (!glfwInit())
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
std::cout << "ERROR GLEW" << std::endl;
std::cout << glGetString(GL_VERSION) << std::endl;
float positions[] = {
-0.5f,-0.5f, //0
0.5f, -0.5f, //1
0.5f, 0.5f, //2
-0.5f, 0.5f //3
};
unsigned int indices[] = {
0, 1, 2,
2, 3, 0
};
unsigned int buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, 6 * 2 * sizeof(float), positions, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);
glEnableVertexAttribArray(0);
unsigned int ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), indices, GL_STATIC_DRAW);
ShaderSourceProgram shader = ParseShader("res/shaders/Basic.shader");
//std::cout << "VERTEX" << std::endl;
//std::cout << shader.VertexShader << std::endl;
unsigned int shaderProgram = CreateShader(shader.VertexShader, shader.FragmentShader);
glUseProgram(shaderProgram);
/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
glClear(GL_COLOR_BUFFER_BIT);
//glDrawArrays(GL_TRIANGLES, 0, 6);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}
The shaders:
#shader vertex
#version 330 core
layout(location = 0)in vec4 position;
void main()
{
gl_Position = position;
};
#shader fragment
#version 330 core
out vec4 color;
void main()
{
color = vec4(0.0,1.0,0.0,1.0);
};
EDIT: Please click here for the entire project (github)
As #Ripi2 pointed out your glBufferData() calls, while not exactly wrong (they overrequest buffer space), aren't exactly correct either. Since you're using raw arrays you can use a straight sizeof(<arrayname>) for the size parameter:
glBufferData( GL_ARRAY_BUFFER, sizeof( positions ), positions, GL_STATIC_DRAW );
...
glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( indices ), indices, GL_STATIC_DRAW );
I suspect your (unknown) shader loader might be wonky since my personal one worked fine.
All together:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <iostream>
#include <cstdarg>
struct Program
{
static GLuint Load( const char* shader, ... )
{
GLuint prog = glCreateProgram();
va_list args;
va_start( args, shader );
while( shader )
{
const GLenum type = va_arg( args, GLenum );
AttachShader( prog, type, shader );
shader = va_arg( args, const char* );
}
va_end( args );
glLinkProgram( prog );
CheckStatus( prog );
return prog;
}
private:
static void CheckStatus( GLuint obj )
{
GLint status = GL_FALSE;
if( glIsShader(obj) ) glGetShaderiv( obj, GL_COMPILE_STATUS, &status );
if( glIsProgram(obj) ) glGetProgramiv( obj, GL_LINK_STATUS, &status );
if( status == GL_TRUE ) return;
GLchar log[ 1 << 15 ] = { 0 };
if( glIsShader(obj) ) glGetShaderInfoLog( obj, sizeof(log), NULL, log );
if( glIsProgram(obj) ) glGetProgramInfoLog( obj, sizeof(log), NULL, log );
std::cerr << log << std::endl;
exit( EXIT_FAILURE );
}
static void AttachShader( GLuint program, GLenum type, const char* src )
{
GLuint shader = glCreateShader( type );
glShaderSource( shader, 1, &src, NULL );
glCompileShader( shader );
CheckStatus( shader );
glAttachShader( program, shader );
glDeleteShader( shader );
}
};
#define GLSL(version, shader) "#version " #version "\n" #shader
int main( void )
{
GLFWwindow* window;
/* Initialize the library */
if( !glfwInit() )
return -1;
/* Create a windowed mode window and its OpenGL context */
window = glfwCreateWindow( 640, 480, "Hello World", NULL, NULL );
if( !window )
{
glfwTerminate();
return -1;
}
/* Make the window's context current */
glfwMakeContextCurrent( window );
if( glewInit() != GLEW_OK )
std::cout << "ERROR GLEW" << std::endl;
std::cout << glGetString( GL_VERSION ) << std::endl;
float positions[] = {
-0.5f,-0.5f, //0
0.5f, -0.5f, //1
0.5f, 0.5f, //2
-0.5f, 0.5f //3
};
unsigned int indices[] = {
0, 1, 2,
2, 3, 0
};
unsigned int buffer;
glGenBuffers( 1, &buffer );
glBindBuffer( GL_ARRAY_BUFFER, buffer );
glBufferData( GL_ARRAY_BUFFER, 6 * 2 * sizeof( float ), positions, GL_STATIC_DRAW );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, sizeof( float ) * 2, 0 );
glEnableVertexAttribArray( 0 );
unsigned int ibo;
glGenBuffers( 1, &ibo );
glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo );
glBufferData( GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof( unsigned int ), indices, GL_STATIC_DRAW );
const char* vert = GLSL
(
330 core,
layout(location = 0)in vec4 position;
void main()
{
gl_Position = position;
};
);
const char* frag = GLSL
(
330 core,
out vec4 color;
void main()
{
color = vec4(0.0,1.0,0.0,1.0);
};
);
unsigned int shaderProgram = Program::Load
(
vert, GL_VERTEX_SHADER,
frag, GL_FRAGMENT_SHADER,
NULL
);
glUseProgram( shaderProgram );
/* Loop until the user closes the window */
while( !glfwWindowShouldClose( window ) )
{
/* Render here */
glClear( GL_COLOR_BUFFER_BIT );
//glDrawArrays(GL_TRIANGLES, 0, 6);
glDrawElements( GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr );
/* Swap front and back buffers */
glfwSwapBuffers( window );
/* Poll for and process events */
glfwPollEvents();
}
glDeleteProgram( shaderProgram );
glfwTerminate();
return 0;
}
glUseProgram() needs to be called after shaders are compiled and linked. Here's a piece of a sample code:
int main()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLAD
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
cout << "Failed to initialize GLAD" << endl;
return -1;
}
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, 800, 600);
float TriangleVertices[] = {
-0.3f, -0.3f, 0.0f,
0.0f, 0.3f, 0.0f,
0.3f, -0.3f, 0.0f
};
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
//BindVertexArray for modifying it
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(TriangleVertices), TriangleVertices, GL_STATIC_DRAW);
glBindVertexArray(VAO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
const char* vertexShaderSource = "\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos, 1.0);\n"
"}\0";
unsigned int vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
const char* fragmentShaderSource = "\n"
"out vec4 FragColor; \n"
"void main()\n"
"{\n"
"FragColor = vec4(1.0f, 0.7f, 0.5f, 1.0f); \n"
"} \n";
unsigned int fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
unsigned int shaderProgram;
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
while (!glfwWindowShouldClose(window))
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
//// draw triangle using the data from the VAO
//glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
// -------------------------------------------------------------------------------
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}