multiple glut windows but same display function - opengl

I am trying to render the model in two windows in glut. But it is rendered in only one of the windows. Is it possible to render in two windows with different callback functions?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#define WINDOW_TITLE_PREFIX "Chapter 2"
int CurrentWidth = 800,
CurrentHeight = 600,
WindowHandle = 0;
unsigned FrameCount = 0;
GLuint
VertexShaderId,
FragmentShaderId,
ProgramId,
VaoId,
VboId,
ColorBufferId;
const GLchar* VertexShader =
{
"#version 400\n"\
"layout(location=0) in vec4 in_Position;\n"\
"layout(location=1) in vec4 in_Color;\n"\
"out vec4 ex_Color;\n"\
"void main(void)\n"\
"{\n"\
" gl_Position = in_Position;\n"\
" ex_Color = in_Color;\n"\
"}\n"
};
const GLchar* FragmentShader =
{
"#version 400\n"\
"in vec4 ex_Color;\n"\
"out vec4 out_Color;\n"\
"void main(void)\n"\
"{\n"\
" out_Color = ex_Color;\n"\
"}\n"
};
void Initialize(int, char*[]);
void InitWindow(int, char*[]);
void ResizeFunction(int, int);
void ResizeFunction1(int, int);
void RenderFunction(void);
void RenderFunction1(void);
void TimerFunction(int);
void TimerFunction1(int);
void IdleFunction(void);
void IdleFunction1(void);
void Cleanup(void);
void CreateVBO(void);
void DestroyVBO(void);
void CreateShaders(void);
void DestroyShaders(void);
int Wh1;
int main(int argc, char* argv[])
{
Initialize(argc, argv);
glutMainLoop();
exit(EXIT_SUCCESS);
}
void Initialize(int argc, char* argv[])
{
GLenum GlewInitResult;
InitWindow(argc, argv);
glewExperimental = GL_TRUE;
GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult) {
fprintf(
stderr,
"ERROR: %s\n",
glewGetErrorString(GlewInitResult)
);
exit(EXIT_FAILURE);
}
fprintf(
stdout,
"INFO: OpenGL Version: %s\n",
glGetString(GL_VERSION)
);
CreateShaders();
CreateVBO();
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
}
void InitWindow(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitContextVersion(4, 0);
glutInitContextFlags(GLUT_FORWARD_COMPATIBLE);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutSetOption(
GLUT_ACTION_ON_WINDOW_CLOSE,
GLUT_ACTION_GLUTMAINLOOP_RETURNS
);
glutInitWindowSize(CurrentWidth, CurrentHeight);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
WindowHandle = glutCreateWindow(WINDOW_TITLE_PREFIX);
std::cout<<WindowHandle<<std::endl;
if(WindowHandle < 1) {
fprintf(
stderr,
"ERROR: Could not create a new rendering window.\n"
);
exit(EXIT_FAILURE);
}
glutSetWindow(WindowHandle);
glutReshapeFunc(ResizeFunction);
glutDisplayFunc(RenderFunction);
glutTimerFunc(0, TimerFunction, 0);
glutCloseFunc(Cleanup);
#if 1
Wh1 = glutCreateWindow("sasd");
// std::cout<<i<<"s"<<std::endl;
glutReshapeFunc(ResizeFunction1);
glutDisplayFunc(RenderFunction1);
glutTimerFunc(0, TimerFunction1, 0);
glutCloseFunc(Cleanup);
glutSetWindow(Wh1);
#endif
}
void ResizeFunction(int Width, int Height)
{
CurrentWidth = Width;
CurrentHeight = Height;
glViewport(0, 0, CurrentWidth, CurrentHeight);
}
void ResizeFunction1(int Width, int Height)
{
CurrentWidth = Width;
CurrentHeight = Height;
glViewport(0, 0, CurrentWidth, CurrentHeight);
}
void RenderFunction(void)
{
++FrameCount;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glutSwapBuffers();
glutSetWindow(WindowHandle);
glutPostRedisplay();
glutSetWindow(Wh1);
glutPostRedisplay();
}
void RenderFunction1(void)
{
++FrameCount;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glutSwapBuffers();
glutSetWindow(WindowHandle);
glutPostRedisplay();
glutSetWindow(Wh1);
glutPostRedisplay();
}
void IdleFunction(void)
{
glutSetWindow(WindowHandle);
glutPostRedisplay();
glutSetWindow(Wh1);
glutPostRedisplay();
}
void IdleFunction1(void)
{
glutSetWindow(WindowHandle);
glutPostRedisplay();
glutSetWindow(Wh1);
glutPostRedisplay();
}
void TimerFunction(int Value)
{
if (0 != Value) {
char* TempString = (char*)
malloc(512 + strlen(WINDOW_TITLE_PREFIX));
sprintf(
TempString,
"%s: %d Frames Per Second # %d x %d",
WINDOW_TITLE_PREFIX,
FrameCount * 4,
CurrentWidth,
CurrentHeight
);
//glutSetWindowTitle(TempString);
free(TempString);
}
FrameCount = 0;
glutTimerFunc(250, TimerFunction, 1);
}
void TimerFunction1(int Value)
{
if (0 != Value) {
char* TempString = (char*)
malloc(512 + strlen(WINDOW_TITLE_PREFIX));
sprintf(
TempString,
"%s: %d Frames Per Second # %d x %d",
WINDOW_TITLE_PREFIX,
FrameCount * 4,
CurrentWidth,
CurrentHeight
);
//glutSetWindowTitle(TempString);
free(TempString);
}
FrameCount = 0;
glutTimerFunc(250, TimerFunction, 1);
}
void Cleanup(void)
{
DestroyShaders();
DestroyVBO();
}
void CreateVBO(void)
{
GLfloat Vertices[] = {
-0.8f, -0.8f, 0.0f, 1.0f,
0.0f, 0.8f, 0.0f, 1.0f,
0.8f, -0.8f, 0.0f, 1.0f
};
GLfloat Colors[] = {
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f
};
GLenum ErrorCheckValue = glGetError();
glGenVertexArrays(1, &VaoId);
glBindVertexArray(VaoId);
glGenBuffers(1, &VboId);
glBindBuffer(GL_ARRAY_BUFFER, VboId);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glGenBuffers(1, &ColorBufferId);
glBindBuffer(GL_ARRAY_BUFFER, ColorBufferId);
glBufferData(GL_ARRAY_BUFFER, sizeof(Colors), Colors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(1);
ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"ERROR: Could not create a VBO: %s \n",
gluErrorString(ErrorCheckValue)
);
exit(-1);
}
}
void DestroyVBO(void)
{
GLenum ErrorCheckValue = glGetError();
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &ColorBufferId);
glDeleteBuffers(1, &VboId);
glBindVertexArray(0);
glDeleteVertexArrays(1, &VaoId);
ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"ERROR: Could not destroy the VBO: %s \n",
gluErrorString(ErrorCheckValue)
);
exit(-1);
}
}
void CreateShaders(void)
{
GLenum ErrorCheckValue = glGetError();
VertexShaderId = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(VertexShaderId, 1, &VertexShader, NULL);
glCompileShader(VertexShaderId);
FragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(FragmentShaderId, 1, &FragmentShader, NULL);
glCompileShader(FragmentShaderId);
ProgramId = glCreateProgram();
glAttachShader(ProgramId, VertexShaderId);
glAttachShader(ProgramId, FragmentShaderId);
glLinkProgram(ProgramId);
glUseProgram(ProgramId);
ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"ERROR: Could not create the shaders: %s \n",
gluErrorString(ErrorCheckValue)
);
exit(-1);
}
}
void DestroyShaders(void)
{
GLenum ErrorCheckValue = glGetError();
glUseProgram(0);
glDetachShader(ProgramId, VertexShaderId);
glDetachShader(ProgramId, FragmentShaderId);
glDeleteShader(FragmentShaderId);
glDeleteShader(VertexShaderId);
glDeleteProgram(ProgramId);
ErrorCheckValue = glGetError();
if (ErrorCheckValue != GL_NO_ERROR)
{
fprintf(
stderr,
"ERROR: Could not destroy the shaders: %s \n",
gluErrorString(ErrorCheckValue)
);
exit(-1);
}
}

glutDisplayFunc, and all of the other callbacks, set callbacks for whatever window is current at the time the function is called. So if you want to set the display callback for a certain window, call glutDisplayFunc after calling glutSetWindow.
I figured out the problem that gldrawArrays requires to create new vbo to redraw. i dunno why.
That's because each window represents a separate OpenGL context. Unless you explicitly share objects (via a platform-specific call), then each context will have its own, separate objects. You can't use buffers created in one in another, without explicitly sharing (and doing so before creating objects in the new context).

Opengl functions are not thread safe. So gldrawArrays in multiple windows might be running in two threads. SO their behaviour is undefined.

Related

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).

OpenGL update VBO vertices bufferSubData

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);

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 Linker error, linking with uncompiled shader

I was trying to create an OpenGL application which simply draws a triangle, but im getting Linker error: linking with uncompiled shader. from the call to glLinkProgram:
#include <GL/glew.h>
#include <GL/glut.h>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <assert.h>
using namespace std;
GLuint VBO;
void draw();
void CreateVBO();
GLuint MakeShader(const string& shaderFile);
GLuint CreateProgram();
string GetCode(const string& path);
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowSize(768, 512);
glutInitWindowPosition(0, 0);
glutCreateWindow("Test");
glutDisplayFunc(draw);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GLenum var = glewInit();
if(var != GLEW_OK){
cerr << "Couldn't initialize glew" << endl;
return -1;
}
CreateVBO();
glutMainLoop();
return 0;
}
void draw(){
glClear(GL_COLOR_BUFFER_BIT);
static GLuint program = CreateProgram();
glUseProgram(program);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
GLuint CreateProgram(){
GLuint program = glCreateProgram();
vector<GLuint> shaders;
shaders.push_back(MakeShader("shade.frag"));
shaders.push_back(MakeShader("shader.vert"));
for(size_t i = 0; i!= shaders.size(); ++i){
glAttachShader(program, shaders[i]);
}
glLinkProgram(program);
GLint linked;
glGetProgramiv(program, GL_LINK_STATUS, &linked);
if(linked == GL_FALSE){
GLint infoLogLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
GLchar* strInfoLog = new GLchar[infoLogLength+1];
glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
printf("Linker failure: %s \n", strInfoLog);
delete strInfoLog;
}
return program;
}
string GetCode(const string &path){
ifstream file(path);
string ret = "";
string line;
if(file.is_open()){
while(getline(file, line)){
ret += line + '\n';
}
}
return ret;
}
GLuint MakeShader(const string& shaderFile){
string extension = shaderFile.substr(shaderFile.length()-4, 4);
GLenum type;
string shaderType;
if(extension == "vert")
{
type = GL_VERTEX_SHADER;
shaderType = "Vertex";
}
else if(extension == "frag")
{
type = GL_FRAGMENT_SHADER;
shaderType = "Fragment";
}
const char* code = (GetCode(shaderFile)).c_str();
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &code, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if(status != GLEW_OK){
GLint logSize;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logSize);
GLchar* errorLog = new GLchar[logSize+1];
glGetShaderInfoLog(shader, logSize, NULL, errorLog);
printf("Compile failed in %s shader: %s \n", shaderType.c_str(), errorLog);
delete errorLog;
}
return shader;
}
void CreateVBO(){
float Vertices[12]= {
0.0f, 0.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f
};
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
}
I'm sorry if my question is noobish, but i'm sort of struggling with OpenGL
You are incorrectly checking for shader compilation success. You compare GL_COMPILE_STATUS against GLEW_OK (which is 0 and has nothing to do with OpenGL), while you should compare with GL_TRUE (which is 1). Also the code does not do anything besides reporting the failure to stdout (i.e. there is no way for the caller to know if it failed or succeeded).

OpenGL error compiling shader [duplicate]

This question already has an answer here:
Linking with uncompiled shader in Ubuntu
(1 answer)
Closed 8 years ago.
I've only recently started learning OpenGL and i can't figure out what is wrong with the following code. The error that I am getting is: "Error compiling shader type 35633: '0(1) : error C0000: syntax error, unexpected, '.', expecting "::" at token "."
#include <iostream>
#include <stdio.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#pragma comment(lib, "glew32.lib")
using namespace std;
struct Vector3f
{
float x;
float y;
float z;
Vector3f()
{
}
Vector3f(float _x, float _y, float _z)
{
x = _x;
y = _y;
z = _z;
}
};
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;
cout << "p[0] :" << pShaderText << endl;
GLint Lengths[1];
Lengths[0] = strlen(pShaderText);
cout << "Lengths[0] :" << Lengths[0] << endl;
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);
}
const char* vs = "shader.vs";
const char* fs = "shader.fs";
AddShader(ShaderProgram, vs, GL_VERTEX_SHADER);
AddShader(ShaderProgram, fs, 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)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(1024, 768);
glutInitWindowPosition(100, 100);
glutCreateWindow("Tutorial 04");
InitializeGlutCallbacks();
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;
}
The shaders are the following:
#version 330
layout (location = 0) in vec3 Position;
void main()
{
gl_Position = vec4(0.5 * Position.x, 0.5 * Position.y, Position.z, 1.0);
}
and
#version 330
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Thanks in advance!
You aren't actually loading the contents of the shaders. Instead, you're passing vs and fs, which are the names of the shader files, to AddShader. This tries to compile the names as though they were shader programs.
You need to load the contents of the shader files first and then pass that to AddShader (or do the loading inside AddShader, but then pShaderText should be named pShaderFileName).