OpenGL update VBO vertices bufferSubData - c++

I am new to openGL and I've got a code like this learning from the tutorial
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
void framebuffer_size_callback(GLFWwindow *window, int width, int height);
void processInput(GLFWwindow *window);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
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";
int main() {
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
GLFWwindow *window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", nullptr, nullptr);
if (window == nullptr) {
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
glCompileShader(vertexShader);
int success;
char infoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
glCompileShader(fragmentShader);
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(fragmentShader, 512, nullptr, infoLog);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, nullptr, infoLog);
std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
float vertices[] = {
0.5f, 0.5f, 0.0f, // top right
0.5f, -0.5f, 0.0f, // bottom right
-0.5f, 0.5f, 0.0f // top left
};
unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), nullptr);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// render loop
while (!glfwWindowShouldClose(window)) {
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
vertices[0] += 0.1f;
vertices[1] += 0.1f;
vertices[2] += 0.1f;
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), &vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}
void processInput(GLFWwindow *window) {
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
// make sure the viewport matches the new window dimensions; note that width and
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
}
As you noticed in render loop I am trying to change the vertices value e.g. move my drawn triangle, while not creating a new VBO but updating its data...
I've read that glBuferSubData is for updating VBO's sub data without creating a new one, and I've done that like this
while (!glfwWindowShouldClose(window)) {
processInput(window);
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
vertices[0] += 0.1f;
vertices[1] += 0.1f;
vertices[2] += 0.1f;
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), &vertices);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
I think I am doing something wrong as the triangle does not move... How can I solve this?

glBufferSubData updates a subset of a buffer object's data store of the buffer which is currently bound to the GL_ARRAY_BUFFER target. The array buffer binding is a global state. As soon as you call glBindBuffer(GL_ARRAY_BUFFER, 0); the binding of the VBO buffer is lost.
Either skip glBindBuffer(GL_ARRAY_BUFFER, 0); or bind the buffer just before calling glBufferSubData:
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), &vertices);

Related

Why isn't OpenGL rendering my red triangle?

After several tests I still don't see my red triangle, what am I doing wrong? It's funny because it is not the first time for me to work with OpenGL, and I am pretty sure I am not missing any setup step. Here is a code snippet:
GLFWwindow* window;
glfwSetErrorCallback(onError);
if ( !glfwInit() ) {
std::cout << "glfwInit() failed." << std::endl;
return;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow( GetWindowWidth(), GetWindowHeight(), "The Game", NULL, NULL );
if ( !window )
{
std::cout << "couldn't create a proper window, exiting." << std::endl;
glfwTerminate();
return;
}
glfwSetKeyCallback( window, handleKeysEvents );
glfwMakeContextCurrent( window );
gladLoadGL(); // no glfwGetProcAddress required
glfwSwapInterval(1);
/// init opengl things ...
GLuint VAO, VBO, program;
GLuint VertexShader, FragmentShader;
VertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShader, 1, &vertex_shader_text, NULL);
glCompileShader(VertexShader);
GLint isCompiled = 0;
glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(VertexShader, GL_INFO_LOG_LENGTH, &maxLength);
std::cout << "ERROR IN COMPILING VERTEX SHADER." << std::endl;
// The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(VertexShader, maxLength, &maxLength, &errorLog[0]);
for ( int i = 0; i < errorLog.size(); ++i )
std::cout << errorLog[i];
glDeleteShader(VertexShader); // Don't leak the shader.
return;
}
FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShader, 1, &fragment_shader_text, NULL);
glCompileShader(FragmentShader);
isCompiled = 0;
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &isCompiled);
if(isCompiled == GL_FALSE)
{
GLint maxLength = 0;
glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
std::cout << "ERROR IN COMPILING VERTEX SHADER." << std::endl;
// The maxLength includes the NULL character
std::vector<GLchar> errorLog(maxLength);
glGetShaderInfoLog(FragmentShader, maxLength, &maxLength, &errorLog[0]);
for ( int i = 0; i < errorLog.size(); ++i )
std::cout << errorLog[i];
glDeleteShader(FragmentShader); // Don't leak the shader.
return;
}
program = glCreateProgram();
glAttachShader(program, VertexShader);
glAttachShader(program, FragmentShader);
glLinkProgram(program);
// Note the different functions here: glGetProgram* instead of glGetShader*.
GLint isLinked = 0;
glGetProgramiv(program, GL_LINK_STATUS, (int *)&isLinked);
if (isLinked == GL_FALSE)
{
std::cout << "ERROR IN LINKING PROGRAM." << std::endl;
GLint maxLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
// The maxLength includes the NULL character
std::vector<GLchar> infoLog(maxLength);
glGetProgramInfoLog(program, maxLength, &maxLength, &infoLog[0]);
// We don't need the program anymore.
glDeleteProgram(program);
// Don't leak shaders either.
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
// Use the infoLog as you see fit.
for ( int i = 0; i < infoLog.size(); ++i )
std::cout << infoLog[i];
// In this simple program, we'll just leave
return;
}
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_VERTEX_ARRAY, VBO);
glBufferData(GL_VERTEX_ARRAY, sizeof(vertices), reinterpret_cast<const void*>(vertices), GL_STATIC_DRAW);
glBindBuffer(GL_VERTEX_ARRAY, 0);
glBindBuffer(GL_VERTEX_ARRAY, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glBindBuffer(GL_VERTEX_ARRAY, 0);
glBindVertexArray(0);
glEnable(GL_DEPTH_TEST);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
while( !glfwWindowShouldClose(window) )
{
Float wWidth = GetWindowWidth();
Float wHeight = GetWindowHeight();
glViewport(0, 0, (GLsizei)wWidth, (GLsizei)wHeight);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwDestroyWindow(window);
glfwTerminate();
std::cout << "closing the game." << std::endl;
return;
And here are the shaders:
Vertex Shader:
#version 460 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos, 1.0f);
}
And fragment shader:
#version 460 core
out vec4 FragCol;
void main()
{
FragCol = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
OpenGL context is created, in fact clearing the screen with a specific color works just fine. I just don't get to see my triangle on the screen, any suggestions?
GL_VERTEX_ARRAY is not a valid buffer type. GL_VERTEX_ARRAY is a client-side capability (fixed function attribute, legacy OpenGL). The buffer type for vertex attributes is GL_ARRAY_BUFFER:
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), reinterpret_cast<const void*>(vertices), GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

How to draw a circle in Modern OpenGL?

I have encountered this question on stackoverflow but the code shown are mostly legacy. How do I draw a circle in modern OpenGL?
Here's my code,
#include <glad/glad.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <cmath>
#include <vector>
GLfloat pi() { return atan(1) * 4; }
int degToRad(float degree)
{
return (pi() / 180) * degree;
}
int main()
{
if (!glfwInit())
{
return -1;
}
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(800, 600, "OpenGL", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
gladLoadGL();
// clang-format off
std::vector<GLfloat> vertices = {
};
GLfloat radius = 0.5;
for(int i = 0; i < 360; i++) {
GLfloat x = radius * cos(degToRad(i));
GLfloat y = radius * sin(degToRad(i));
vertices.push_back(x);
vertices.push_back(y);
vertices.push_back(0.0f);
}
unsigned int VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), &vertices[0], GL_STATIC_DRAW);
const char *vertexShaderSource =
"#version 410 core\n"
"precision mediump float;\n"
"layout (location = 0) in vec3 position;\n"
"void main() {\n"
" gl_Position = vec4(position, 1.0);\n"
"}";
const char *fragmentShaderSource =
"#version 410 core\n"
"precision mediump float;\n"
"out vec4 color;\n"
"void main() {\n"
" color = vec4(0.0f, 1.0f, 0.0f, 1.0f);\n"
"}";
unsigned int vertexShader;
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);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
}
unsigned int fragmentShader;
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);
std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
}
unsigned int vertexArray;
glGenVertexArrays(1, &vertexArray);
glBindVertexArray(vertexArray);
unsigned int shaderProgram;
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;
}
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
while (!glfwWindowShouldClose(window))
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glDrawArrays(GL_LINES, 0, vertices.size() / 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
It draws these lines,

OpenGL3.3 Mac OSX 11.4

I'm actually learning OpenGL3.3 to create a multiplatform application, which draws some sprites.
Currently, I'm struggling at the compilation of vertexShader and fragShader. The OpenGL shows me information, that my device doesn't support the 3.3 version. When It's clear that it supports it.
main.cpp
#include <iostream>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <string>
#include <fstream>
#include <sstream>
#include <filesystem>
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f};
std::string readFile(const std::string &fileLoc)
{
std::ifstream file;
file.open(fileLoc, std::ios::in);
std::stringstream contex;
if (!file.fail())
{
contex << file.rdbuf();
}
return contex.str();
}
GLuint createandComplieShader(const std::string &fileLoc, GLuint shaderType)
{
GLuint shader = glCreateShader(shaderType);
std::string shaderString = readFile(fileLoc);
const char *ShaderSource = shaderString.c_str();
glShaderSource(shader, 1, &ShaderSource, nullptr);
glCompileShader(shader);
int success;
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
char infoLog[512];
glGetShaderInfoLog(shader, 512, nullptr, infoLog);
std::cerr << "Shader Error :" << infoLog << std::endl;
exit(-1);
}
return shader;
}
GLuint createAndLinkShader()
{
std::string path = std::filesystem::current_path();
std::string VertexShader = "/vertShader.vert" ;
std::string FragmentShader = "/fragShader.vert";
GLuint vertexShader = createandComplieShader(path + VertexShader , GL_VERTEX_SHADER);
GLuint fragmentShader = createandComplieShader(path + FragmentShader , GL_FRAGMENT_SHADER);
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
int succes;
glGetProgramiv(program, GL_LINK_STATUS, &succes);
if (!succes)
{
char infoLog[512];
glGetProgramInfoLog(program, 512, nullptr, infoLog);
std::cerr << "Linking Error: " << infoLog << std::endl;
exit(-2);
}
return program;
}
int main(int argc, char **argv)
{
if (!glfwInit())
{
std::cerr << "GLFW init failed..." << std::endl;
return -1;
}
GLFWwindow *window = glfwCreateWindow(1280, 720, "A-Engine", nullptr, nullptr);
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);
if (window == nullptr)
{
std::cerr << "Window init failed..." << std::endl;
glfwTerminate();
return -2;
}
glfwMakeContextCurrent(window);
// glfwSetKeyCallback (window, HandleKeyInput);
if (glewInit() != GLEW_OK)
{
std::cerr << "Glew init failed..." << std::endl;
glfwDestroyWindow(window);
glfwTerminate();
return -3;
}
glClearColor(0.2f, 0.2f, 0.45f, 1.0f);
GLuint ShaderProgram = createAndLinkShader();
unsigned int VBO, VAO;
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);
int width;
int height;
while (!glfwWindowShouldClose(window))
{
glfwPollEvents();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glfwGetFramebufferSize(window, &width, &height);
glViewport(0, 0, width, height);
glUseProgram(ShaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(ShaderProgram);
glfwDestroyWindow(window);
return EXIT_SUCCESS;
}
fragShader.vert
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
vertShader.vert
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
The main binary file is located under this same folder as vertShader and fragShader
Shader Error :ERROR: 0:1: '' : version '330' is not supported
ERROR: 0:1: '' : syntax error: #version
ERROR: 0:2: 'layout' : syntax error: syntax error
As per the comment, at the very least you should set the glfw window hints before creating the window. So the window creation code in main should probably be...
if (!glfwInit())
{
std::cerr << "GLFW init failed..." << std::endl;
return -1;
}
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);
GLFWwindow *window = glfwCreateWindow(1280, 720, "A-Engine", nullptr, nullptr);
.
.
.
Otherwise the OpenGL version associated with the newly created context can be anything (as far as I'm aware).

Why a black screen with sample code in OpenGL

I have this OpenGL program, a fragment shader, and a vertex shader.
This is the program source
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "ogldev_util.h"
#include "ogldev_math_3d.h"
GLuint VBO;
const char* pVSFileName = "shader.vs";
const char* pFSFileName = "shader.fs";
static void RenderSceneCB()
{
glClear(GL_COLOR_BUFFER_BIT);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
static void InitializeGlutCallbacks()
{
glutDisplayFunc(RenderSceneCB);
}
static void CreateVertexBuffer()
{
Vector3f Vertices[3];
Vertices[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Vertices[1] = Vector3f(1.0f, -1.0f, 0.0f);
Vertices[2] = Vector3f(0.0f, 1.0f, 0.0f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
}
static void AddShader(GLuint ShaderProgram, const char* pShaderText, GLenum ShaderType)
{
GLuint ShaderObj = glCreateShader(ShaderType);
if (ShaderObj == 0) {
fprintf(stderr, "Error creating shader type %d\n", ShaderType);
exit(0);
}
const GLchar* p[1];
p[0] = pShaderText;
GLint Lengths[1];
Lengths[0]= strlen(pShaderText);
glShaderSource(ShaderObj, 1, p, Lengths);
glCompileShader(ShaderObj);
GLint success;
glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success);
if (!success) {
GLchar InfoLog[1024];
glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog);
fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog);
exit(1);
}
glAttachShader(ShaderProgram, ShaderObj);
}
static void CompileShaders()
{
GLuint ShaderProgram = glCreateProgram();
if (ShaderProgram == 0) {
fprintf(stderr, "Error creating shader program\n");
exit(1);
}
string vs, fs;
if (!ReadFile(pVSFileName, vs)) {
exit(1);
};
if (!ReadFile(pFSFileName, fs)) {
exit(1);
};
AddShader(ShaderProgram, vs.c_str(), GL_VERTEX_SHADER);
AddShader(ShaderProgram, fs.c_str(), GL_FRAGMENT_SHADER);
GLint Success = 0;
GLchar ErrorLog[1024] = { 0 };
glLinkProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success);
if (Success == 0) {
glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);
exit(1);
}
glValidateProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success);
if (!Success) {
glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);
fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);
exit(1);
}
glUseProgram(ShaderProgram);
}
int main(int argc, char** argv)
{
glutInitContextVersion(3, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(1024, 768);
glutInitWindowPosition(100, 100);
glutCreateWindow("Tutorial 04");
InitializeGlutCallbacks();
// Must be done after glut is initialized!
GLenum res = glewInit();
if (res != GLEW_OK) {
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
printf("GL version: %s\n", glGetString(GL_VERSION));
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
CreateVertexBuffer();
CompileShaders();
glutMainLoop();
return 0;
}
This vertex shader
#version 330 core
layout (location = 0) in vec3 Position;
void main()
{
gl_Position = vec4(0.5 * Position.x, 0.5 * Position.y, Position.z, 1.0);
}
and this fragment shader
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
The result is a black screen And i wonder why
Is somebody having an hint ?
(I'm using an integrated Intel GPU)
Vertex Array Objects (VAOs) are capital-R Required in Core contexts.
Make sure you create/bind/populate one before attempting to glDraw*().

OpenGL program doesn't show any picture

I've tried to display a simple triangle, but nothing appears on screen.
I can clear the color but, nothing else. (I've put averything in one big file).
I'm using SDL to create the window. Everything else should be just OpenGL.
Here is my code:
int main(){
// Init window
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, 32);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_Window* window = SDL_CreateWindow("Title", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_OPENGL);
SDL_GLContext context = SDL_GL_CreateContext(m_window);
GLenum status = glewInit();
if(status != GLEW_OK){
std::cerr << "Glew failed!" << std::endl;
}
isClosed = false;
// Init everything else
GLuint vaoID;
glGenVertexArrays(1, &vaoID);
glBindVertexArray(vaoID);
GLuint vboID;
glGenBuffers(1, &vboID);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
GLfloat vert2[] = {-1,-1,0, 1,-1,0, 0,0,0};
glBufferData(GL_ARRAY_BUFFER, sizeof(vert2), vert2, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vboID);
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,0,(void*)0);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
GLuint frag = glCreateShader(GL_FRAGMENT_SHADER);
GLuint vert = glCreateShader(GL_VERTEX_SHADER);
std::string sFrag = "#version 130 \n out vec4 out_color; \n void main(void){out_color = vec4(1, 0, 1, 1);}";
std::string sVert = "#version 130 \n in vec3 pos; \n void main(void){gl_Position = vec4(pos, 1);}";
char const* cFrag = sFrag.c_str();
char const* cVert = sVert.c_str();
GLint success = 0;
glShaderSource(frag, 1, &cFrag, NULL);
glCompileShader(frag);
glGetShaderiv(frag, GL_COMPILE_STATUS, &success);
if(success == GL_FALSE) std::cerr << "Möb" << std::endl;
else std::cout << "YES" << std::endl;
glShaderSource(vert, 1, &cVert, NULL);
glCompileShader(vert);
glGetShaderiv(vert, GL_COMPILE_STATUS, &success);
if(success == GL_FALSE) std::cerr << "Möb" << std::endl;
else std::cout << "YES" << std::endl;
GLuint program = glCreateProgram();
glAttachShader(program, vert);
glAttachShader(program, frag);
glBindAttribLocation(program, 0, "pos");
glDeleteShader(vert);
glDeleteShader(frag);
glLinkProgram(program);
//glValidateProgram(program);
while(!isClosed){
glUseProgram(program);
glBindVertexArray(vaoID);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glUseProgram(0);
// Update
SDL_GL_SwapWindow(window);
SDL_Event e;
while(SDL_PollEvent(&e)){
if(e.type == SDL_QUIT){
isClosed = true;
}
}
glClearColor(0, 1, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
return 0;
}
You are calling glClear() before display.update(), which seems to suggest you are clearing the back buffer before swapping it. Granted the other code is correct, if you swap the position of glClear() and display.update(), you may see something.