OpenGL not drawing triangle in C++ - c++

I am learning openGL in C++ and I got to the point where I could draw a triangle.
I decided to put the creation of the triangle into a class so that all the code wasn't just in one file and now when I execute the draw function nothing happens. I've been looking through this code for a while now I can't figure out why this happens.
The program dosen't crash it just draws a black background. Also OpenGL does not return any errors.
Here is my main function:
int main(int argc, char* args[]){
GLrenderer renderer;
setRendererSettings(&renderer);
renderer.init();
//triangle tri = createTriangle();
//compileShaders();
glslShader triangle("VertexShader.glsl", "FragShader.glsl");
std::vector<GLfloat> vertices = {
-1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, -1.0f, 0.0f
};
triangle.createShape(vertices);
triangle.compileShaders();
while(renderer.shouldRun()){
input(&renderer);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
triangle.draw();
renderer.swapBuffers();
}
renderer.destroy();
return 0;
}
Here is my GLrenderer header
class GLrenderer {
private:
SDL_Window* window;
SDL_GLContext GLcontext;
bool isRunning = false;
bool initSDL();
bool initGL();
public:
GLrenderer();
int width = 1, height = 1;
int winX = 0, winY = 0;
int versionMajor = 3, versionMinor = 3;
const char* title = "OpenGL window";
Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN;
bool init();
bool shouldRun();
void setShouldRun(bool value);
void destroy();
void swapBuffers();
SDL_Window* getWindow();
};
The source for GLrenderer
GLrenderer::GLrenderer() {}
bool GLrenderer::init(){
if(!initSDL()) return false;
if(!initGL()) return false;
isRunning = true;
return true;
}
bool GLrenderer::initSDL(){
if(SDL_Init(SDL_INIT_EVERYTHING) < 0){
printf("Failed to init SDL.\n");
return false;
}
window = SDL_CreateWindow(
title,
winX, winY,
width, height,
flags
);
if(window == NULL){
printf("Failed to create SDL_Window.\n");
return false;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, versionMajor);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, versionMinor);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
GLcontext = SDL_GL_CreateContext(window);
if(!GLcontext){
printf("Failed to create OpenGl context.\n");
return false;
}
SDL_GL_MakeCurrent(window, GLcontext);
return true;
}
bool GLrenderer::initGL(){
glewExperimental = GL_TRUE;
if(glewInit() != GLEW_OK){
printf("Failed to init glew.\n");
return false;
}
return true;
}
bool GLrenderer::shouldRun(){
return isRunning;
}
void GLrenderer::setShouldRun(bool value){
isRunning = value;
}
void GLrenderer::destroy(){
SDL_DestroyWindow(window);
SDL_GL_DeleteContext(GLcontext);
SDL_Quit();
}
SDL_Window* GLrenderer::getWindow(){
return window;
}
void GLrenderer::swapBuffers(){
SDL_GL_SwapWindow(window);
}
Header for my class im using to create the triangle
class glslShader;
std::string readShader(std::string file);
class glslShader {
private:
GLuint ShaderProgram, VAO, VBO;
std::string vertexFile, fragFile;
public:
glslShader(std::string _vertexFile, std::string _fragFile);
void createShape(std::vector<GLfloat> vertices);
bool compileShaders();
void draw();
};
And finally the source for that header
bool fileExsists(std::string file){
std::fstream test(file);
return test.good();
}
std::string readShader(std::string file){
if(!fileExsists(file)){
printf("Not able to locate shader\n");
return "";
}
const int maxLine = 130;
std::string shader = "";
std::fstream shaderFile(file);
while(!shaderFile.eof()){
char line[maxLine];
shaderFile.getline(line, 130);
shader += line;
shader += "\n";
}
return shader;
}
glslShader::glslShader(std::string _vertexFile, std::string _fragFile) : vertexFile{_vertexFile}, fragFile{_fragFile} {}
void glslShader::createShape(std::vector<GLfloat> vertices){
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices.data()), vertices.data(), GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
}
bool addShader(GLuint program, const char* shaderSRC, GLenum type){
GLuint shader = glCreateShader(type);
const GLchar* src[1];
src[0] = shaderSRC;
GLint size[1];
size[0] = strlen(shaderSRC);
glShaderSource(shader, 1, src, size);
GLint result = 0;
GLchar log[1024];
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
if(!result){
glGetShaderInfoLog(shader, 1024, NULL, log);
printf("ERROR: Failed to compile shader: &s\n", log);
return false;
}
glAttachShader(program, shader);
return true;
}
bool glslShader::compileShaders(){
ShaderProgram = glCreateProgram();
if (!ShaderProgram){
printf("ERROR: Failed to create shader program.\n");
return false;
}
if (!addShader(ShaderProgram, readShader("VertexShader.glsl").c_str(), GL_VERTEX_SHADER)){
printf("ERROR: failed to create vertex shader.\n");
return false;
}
if (!addShader(ShaderProgram, readShader("FragShader.glsl").c_str(), GL_FRAGMENT_SHADER)){
printf("ERROR: failed to create fragment shader.\n");
return false;
}
GLint result = 0;
GLchar log[1024];
glLinkProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &result);
if(!result){
glGetProgramInfoLog(ShaderProgram, sizeof(log), NULL, log);
printf("ERROR: Failed to link program: %s", log);
return false;
}
glValidateProgram(ShaderProgram);
glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &result);
if (!result){
glGetProgramInfoLog(ShaderProgram, sizeof(log), NULL, log);
printf("ERROR: Failed to validate program: %s\n", log);
return false;
}
return true;
}
void glslShader::draw(){
glUseProgram(ShaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
glUseProgram(0);
}
I am certain its not my shader code because I am using the same shaders that I used to render my last triangle before I was using a class.

glBufferData(GL_ARRAY_BUFFER, sizeof(_verticies.data()), _verticies.data(), GL_STATIC_DRAW);
Should have been:
glBufferData(GL_ARRAY_BUFFER, _verticies.size() * sizeof(Glfloat), _verticies.data(), GL_STATIC_DRAW);

Related

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.

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

multiple glut windows but same display function

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.