OpenGL on Mac OS X only draws black screen instead of triangle (GLEW, GLFW)
I am new to programming and OpenGL and I am following The Cherno's OpenGL beginner's tutorial. But instead of drawing a triangle it shows a black screen.
I believe my shaders are being parsed and compiled correctly. I am using Mac OS 10.13 with OpenGL 3.2. GLFW does give an error after loading the window but I've read that the error doesn't have any serious consequences. I have included the error below.
I followed The Cherno's tutorial very closely but due to my lack of experience with OpenGL I had a hard time finding questions similar to mine. I did remove the semicolons after the main() functions in Basic.shader because the shaders would not compile while they were there.
This is my first time posting to StackOverflow so I don't how to format my questions. I am sorry for the dutch commentary, I will write in english from now on ;) If my code is difficult to follow please comment or send me an email at afas460x@gmail.com
EDIT 1: I have discovered it has something to do with a VAO. I have no idea what it is or how to use it. The docs are extremely confusing. Can someone explain?
main.cpp:
// OpenGL test
// Geschreven door Job Winterdijk
// 18-11-2018
// foutcodes door return:
// 2 : !glfwInit
// 3 : !glfwCreateWindow
// 4 : glewInit != GLEW_OK
// 5 : CompileShader()
// 6 : ParseShader() > ongedefieneerde shader
// debug macros
#define DEBUG_OUTPUT_PARSE_SHADER 1
#define DEBUG_OUTPUT_ARGV_0 1
#define DEBUG_OUTPUT_GLSL_VERSION 1
// gedeelde libs
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstring>
// GLEW moet eerder geinclude worden dan ander GL libs
#include "include/GL/glew.h"
// Gedeelde OpenGL libs
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
// Statische libs
#include "include/GLFW/glfw3.h"
struct ShaderSource
{
std::string VertexShader;
std::string FragmentShader;
};
static void TerminateWithError(unsigned int err)
{
// dit is niet goed :(
std::cout << "weg ermee..." << std::endl;
glfwTerminate();
exit(err);
}
static ShaderSource ParseShader(const std::string& path)
{
// maakt een enum type aan om by te houden naar welke stream er geschreven moet worden
enum class ShaderTarget
{
NONE=-1, VERTEX=0, FRAGMENT=1
};
ShaderTarget target = ShaderTarget::NONE;
// maakt een nieuwe input stream aan
std::ifstream stream(path);
// maakt twee nieuwe output streams aan
// 0 = de vertex shader
// 1 = de fragment shader
std::stringstream out[2];
// houd een lijn uit het bestand vast
std::string line;
// deze loop blijft lopen totdat getline == null AKA het einde van het bestand
while (getline(stream, line)) {
if (line.find("#shader") != std::string::npos) {
if (line.find("vertex") != std::string::npos) {
// de vertex shader is gevonden, schrijf naar vertex shader string
target = ShaderTarget::VERTEX;
} else if (line.find("fragment") != std::string::npos){
// de fragment shader is gevonden, schrijf naar fragment shader string
target = ShaderTarget::FRAGMENT;
} else {
TerminateWithError(6);
}
} else {
// de gelezen lijn is een lijn die code bevat
out[(int) target] << line << 'n';
}
}
return {out[0].str(), out[1].str()};
}
static unsigned int CompileShader(const std::string& inputShader, unsigned int type)
{
unsigned int id = glCreateShader(type); // maakt een lege shader aan
const char* inputShaderCS = inputShader.c_str(); // maakt een char pointer naar het eerste element van de CS van std::string, werkt alleen maar zolang de oorspronkelijke string ook blijft bestaan
glShaderSource(id, 1, &inputShaderCS, nullptr); // geeft de ongecompileerde shader door aan OpenGL
glCompileShader(id); // compileert de shader
// hopa we gaan nu error handelen hebbe we er een beetje zin in!!!!!
// glGetShaderiv() haalt informatie over een shader op en stopt dit in een var waar de pointer naar wijst
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
// kijken of het compileren succesvol was
if (result == GL_FALSE) {
// als het niet succesvol was wordt de rede opgeslagen in de info log
// die kan je met getShaderiv() lezen
// net zoals de lengte van de info log
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
// message moet op de heap gealloceerd worden omdat je pas tijdens runtime weet hoelang de foutmelding is
char* message = new char[length];
glGetShaderInfoLog(id, length, &length, message);
// zet het type shader om in menselijke taal
char ShaderTypeString[10];
if (type == GL_VERTEX_SHADER) {
strcpy(ShaderTypeString, "VERTEX");
} else if (type == GL_FRAGMENT_SHADER) {
strcpy(ShaderTypeString, "FRAGMENT");
}
// schrijf een foutmelding naar stderr stream
std::cerr << "[CompileShader(in, type) | main.cpp] Er is een fout opgetreden tijdens het compileren van een shader." << std::endl;
std::cerr << "shader type: " << ShaderTypeString << std::endl;
std::cerr << "Shader info log:n" << message << std::endl;
delete message;
TerminateWithError(5);
}
return id; // returned de aangemaakte en gecompileerde shader
}
static unsigned int CreateShaders(const std::string& vertexShader, const std::string& fragmentShader)
{
unsigned int program = glCreateProgram(); // een programma zorgt ervoor dat meerdere shaders aan elkaar gekoppeld kunnen worden
// compilleert bijde shaders
unsigned int vertexShaderID = CompileShader(vertexShader, GL_VERTEX_SHADER);
unsigned int fragmentShaderID = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
// voegt bijde shader aan het programma toe
glAttachShader(program, vertexShaderID);
glAttachShader(program, fragmentShaderID);
// linkt het programma AKA maakt het programma uitvoerbaar
glLinkProgram(program);
// kijkt of het programma in ?deze staat? uitgevoerd kan worden
glValidateProgram(program);
// verwijderd de shaders, dit kan omdat de shaders nu onderdeel zijn van de program (net als .o bestanden zegmaar)
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
// returned het ID van de program
return program;
}
int main(int argc, char *argv)
{
// (debug) print de uitvoer van argv[0] met als doel te achterhalen wat het path is waarvan main uitgevoerd wordt
#if DEBUG_OUTPUT_ARGV_0==1
std::cout << "executable path: n" << argv[0] << "nn";
#endif
GLFWwindow *window; // het scherm
// initialiseert glfw en tekent een scherm
if (!glfwInit()) return 2;
// dit gaat er hopenlijk voor zorgen dat ik OpenGL 3.3 kan gebruiken
// anders ga ik huilen :(
// ben letterlijk een uur bezig geweest met dit oplossen ;-;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
// glfwCreateWindow geeft een foutmelding
window = glfwCreateWindow(500, 500, "OpenGL test/yehes", NULL, NULL);
if (!window) {
glfwTerminate();
return 3;
}
// selecteert een OpenGL context
glfwMakeContextCurrent(window);
// print de ondersteunde GLSL versie
// handige reminder: dit kan alleen maar als er een actieve OpenGL context is
// anders krijg je eem EXC_BAD_ACCES en dan ben je echt een jaar bezig met de oplossing zoeken
#if DEBUG_OUTPUT_GLSL_VERSION==1
std::cout << "Ondersteunde GLSL versie is: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << "n" << std::endl;
#endif
// initialiseert GLEW
if (glewInit() != GLEW_OK) {
return 4;
}
// de buffer is wat er aan de GPU wordt doorgegeven
unsigned int buffer; // buffer ID
glGenBuffers(1, &buffer); // maakt buffer aan
glBindBuffer(GL_ARRAY_BUFFER, buffer); // selecteert de buffer
// dit verteld OpenGL?of de shader? of de GPU? hoed de vertex geformat is
glEnable(0); // activeert de type vertex
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2, 0); // definieert de type vertex
// dit zijn de vertexen die in de buffer geladen gaan worden
float data[6] = {
-0.5f,-0.5f,
0.0f, 0.5f,
0.5f, -0.5f
};
// maakt de buffer aan en laad de data in de buffer
// als je nog geen dat in de buffer wil laden dan kan je NULL invullen op de plek waarnu data staat
glBufferData(GL_ARRAY_BUFFER, 6*sizeof(float), data, GL_STATIC_DRAW);
// de shaders worden het geheugen in geladen
ShaderSource source = ParseShader("./res/Shaders/Basic.shader");
// (debug) laat de uitvoer van de geparste shaders zien
// om de mysterieuze bug op te lossen
#if DEBUG_OUTPUT_PARSE_SHADER==1
std::cout << "ParseShader : VERTEXr" << source.VertexShader << "rParseShader : FRAGMENTr" << source.FragmentShader << std::endl;
std::cout << "---END---" << "n" << std::endl;
#endif
// het programma wordt aangemaakt en de shaders worden eraan gebonden
unsigned int program = CreateShaders(source.VertexShader, source.FragmentShader);
// het programma wordt geselecteerd
glUseProgram(program);
// dit is de game loop
while (!glfwWindowShouldClose(window)) {
// docs.gl zegt dat dit de buffer leeg haalt maar wss is dat een andere buffer want anders zou de driehoek toch verdwijnen?
glClear(GL_COLOR_BUFFER_BIT);
// hier moet je renderen
glDrawArrays(GL_TRIANGLES, 0, 3);
// hier moet je stoppen met renderen
// glfw heeft twee buffers de front en de back buffer
// de front buffer is wat er nu op het scherm staat
// de back buffer is waar je naar rendert
// glfwSwapBuffers() wisselt deze om
glfwSwapBuffers(window);
// glfwPollEvents() haalt nieuwe informatie van de window system om te kijken of er nieuwe gebruikers input is
// deze gebruik je als je een continue game loop hebt
// als er alleen maar iets hoeft te veranderen als er gebruikersinvoer is hebruik je glfwWaitEvents()
glfwPollEvents();
}
// het programma moet verwijderd worden
glDeleteProgram(program);
glfwTerminate();
return 0;
}
Basic.shader:
#shader vertex
#version 330 core
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
#shader fragment
#version 330 core
layout(location = 0) out vec4 color;
void main()
{
color = vec4(1.0, 0.0, 0.0, 1.0);
}
The error message printed after calling glfwCreateWindow():
Setting <GLFWContentView: 0x1007650c0> as the first responder for window <GLFWWindow: 0x10073bea0>, but it is in a different window ((null))! This would eventually crash when the view is freed. The first responder will be set to nil.
(
0 AppKit 0x00007fff2e896862 -[NSWindow _validateFirstResponder:] + 578
1 AppKit 0x00007fff2dfdd5f0 -[NSWindow _setFirstResponder:] + 31
2 AppKit 0x00007fff2e07bd5d -[NSWindow _realMakeFirstResponder:] + 448
3 OpenGL test 0x0000000100035c3a createNativeWindow + 1034
4 OpenGL test 0x00000001000355cf _glfwPlatformCreateWindow + 63
5 OpenGL test 0x000000010002de57 glfwCreateWindow + 887
6 OpenGL test 0x00000001000014d7 main + 231
7 libdyld.dylib 0x00007fff588ec015 start + 1
)
c++ macos opengl glfw glew
|
show 6 more comments
I am new to programming and OpenGL and I am following The Cherno's OpenGL beginner's tutorial. But instead of drawing a triangle it shows a black screen.
I believe my shaders are being parsed and compiled correctly. I am using Mac OS 10.13 with OpenGL 3.2. GLFW does give an error after loading the window but I've read that the error doesn't have any serious consequences. I have included the error below.
I followed The Cherno's tutorial very closely but due to my lack of experience with OpenGL I had a hard time finding questions similar to mine. I did remove the semicolons after the main() functions in Basic.shader because the shaders would not compile while they were there.
This is my first time posting to StackOverflow so I don't how to format my questions. I am sorry for the dutch commentary, I will write in english from now on ;) If my code is difficult to follow please comment or send me an email at afas460x@gmail.com
EDIT 1: I have discovered it has something to do with a VAO. I have no idea what it is or how to use it. The docs are extremely confusing. Can someone explain?
main.cpp:
// OpenGL test
// Geschreven door Job Winterdijk
// 18-11-2018
// foutcodes door return:
// 2 : !glfwInit
// 3 : !glfwCreateWindow
// 4 : glewInit != GLEW_OK
// 5 : CompileShader()
// 6 : ParseShader() > ongedefieneerde shader
// debug macros
#define DEBUG_OUTPUT_PARSE_SHADER 1
#define DEBUG_OUTPUT_ARGV_0 1
#define DEBUG_OUTPUT_GLSL_VERSION 1
// gedeelde libs
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstring>
// GLEW moet eerder geinclude worden dan ander GL libs
#include "include/GL/glew.h"
// Gedeelde OpenGL libs
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
// Statische libs
#include "include/GLFW/glfw3.h"
struct ShaderSource
{
std::string VertexShader;
std::string FragmentShader;
};
static void TerminateWithError(unsigned int err)
{
// dit is niet goed :(
std::cout << "weg ermee..." << std::endl;
glfwTerminate();
exit(err);
}
static ShaderSource ParseShader(const std::string& path)
{
// maakt een enum type aan om by te houden naar welke stream er geschreven moet worden
enum class ShaderTarget
{
NONE=-1, VERTEX=0, FRAGMENT=1
};
ShaderTarget target = ShaderTarget::NONE;
// maakt een nieuwe input stream aan
std::ifstream stream(path);
// maakt twee nieuwe output streams aan
// 0 = de vertex shader
// 1 = de fragment shader
std::stringstream out[2];
// houd een lijn uit het bestand vast
std::string line;
// deze loop blijft lopen totdat getline == null AKA het einde van het bestand
while (getline(stream, line)) {
if (line.find("#shader") != std::string::npos) {
if (line.find("vertex") != std::string::npos) {
// de vertex shader is gevonden, schrijf naar vertex shader string
target = ShaderTarget::VERTEX;
} else if (line.find("fragment") != std::string::npos){
// de fragment shader is gevonden, schrijf naar fragment shader string
target = ShaderTarget::FRAGMENT;
} else {
TerminateWithError(6);
}
} else {
// de gelezen lijn is een lijn die code bevat
out[(int) target] << line << 'n';
}
}
return {out[0].str(), out[1].str()};
}
static unsigned int CompileShader(const std::string& inputShader, unsigned int type)
{
unsigned int id = glCreateShader(type); // maakt een lege shader aan
const char* inputShaderCS = inputShader.c_str(); // maakt een char pointer naar het eerste element van de CS van std::string, werkt alleen maar zolang de oorspronkelijke string ook blijft bestaan
glShaderSource(id, 1, &inputShaderCS, nullptr); // geeft de ongecompileerde shader door aan OpenGL
glCompileShader(id); // compileert de shader
// hopa we gaan nu error handelen hebbe we er een beetje zin in!!!!!
// glGetShaderiv() haalt informatie over een shader op en stopt dit in een var waar de pointer naar wijst
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
// kijken of het compileren succesvol was
if (result == GL_FALSE) {
// als het niet succesvol was wordt de rede opgeslagen in de info log
// die kan je met getShaderiv() lezen
// net zoals de lengte van de info log
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
// message moet op de heap gealloceerd worden omdat je pas tijdens runtime weet hoelang de foutmelding is
char* message = new char[length];
glGetShaderInfoLog(id, length, &length, message);
// zet het type shader om in menselijke taal
char ShaderTypeString[10];
if (type == GL_VERTEX_SHADER) {
strcpy(ShaderTypeString, "VERTEX");
} else if (type == GL_FRAGMENT_SHADER) {
strcpy(ShaderTypeString, "FRAGMENT");
}
// schrijf een foutmelding naar stderr stream
std::cerr << "[CompileShader(in, type) | main.cpp] Er is een fout opgetreden tijdens het compileren van een shader." << std::endl;
std::cerr << "shader type: " << ShaderTypeString << std::endl;
std::cerr << "Shader info log:n" << message << std::endl;
delete message;
TerminateWithError(5);
}
return id; // returned de aangemaakte en gecompileerde shader
}
static unsigned int CreateShaders(const std::string& vertexShader, const std::string& fragmentShader)
{
unsigned int program = glCreateProgram(); // een programma zorgt ervoor dat meerdere shaders aan elkaar gekoppeld kunnen worden
// compilleert bijde shaders
unsigned int vertexShaderID = CompileShader(vertexShader, GL_VERTEX_SHADER);
unsigned int fragmentShaderID = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
// voegt bijde shader aan het programma toe
glAttachShader(program, vertexShaderID);
glAttachShader(program, fragmentShaderID);
// linkt het programma AKA maakt het programma uitvoerbaar
glLinkProgram(program);
// kijkt of het programma in ?deze staat? uitgevoerd kan worden
glValidateProgram(program);
// verwijderd de shaders, dit kan omdat de shaders nu onderdeel zijn van de program (net als .o bestanden zegmaar)
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
// returned het ID van de program
return program;
}
int main(int argc, char *argv)
{
// (debug) print de uitvoer van argv[0] met als doel te achterhalen wat het path is waarvan main uitgevoerd wordt
#if DEBUG_OUTPUT_ARGV_0==1
std::cout << "executable path: n" << argv[0] << "nn";
#endif
GLFWwindow *window; // het scherm
// initialiseert glfw en tekent een scherm
if (!glfwInit()) return 2;
// dit gaat er hopenlijk voor zorgen dat ik OpenGL 3.3 kan gebruiken
// anders ga ik huilen :(
// ben letterlijk een uur bezig geweest met dit oplossen ;-;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
// glfwCreateWindow geeft een foutmelding
window = glfwCreateWindow(500, 500, "OpenGL test/yehes", NULL, NULL);
if (!window) {
glfwTerminate();
return 3;
}
// selecteert een OpenGL context
glfwMakeContextCurrent(window);
// print de ondersteunde GLSL versie
// handige reminder: dit kan alleen maar als er een actieve OpenGL context is
// anders krijg je eem EXC_BAD_ACCES en dan ben je echt een jaar bezig met de oplossing zoeken
#if DEBUG_OUTPUT_GLSL_VERSION==1
std::cout << "Ondersteunde GLSL versie is: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << "n" << std::endl;
#endif
// initialiseert GLEW
if (glewInit() != GLEW_OK) {
return 4;
}
// de buffer is wat er aan de GPU wordt doorgegeven
unsigned int buffer; // buffer ID
glGenBuffers(1, &buffer); // maakt buffer aan
glBindBuffer(GL_ARRAY_BUFFER, buffer); // selecteert de buffer
// dit verteld OpenGL?of de shader? of de GPU? hoed de vertex geformat is
glEnable(0); // activeert de type vertex
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2, 0); // definieert de type vertex
// dit zijn de vertexen die in de buffer geladen gaan worden
float data[6] = {
-0.5f,-0.5f,
0.0f, 0.5f,
0.5f, -0.5f
};
// maakt de buffer aan en laad de data in de buffer
// als je nog geen dat in de buffer wil laden dan kan je NULL invullen op de plek waarnu data staat
glBufferData(GL_ARRAY_BUFFER, 6*sizeof(float), data, GL_STATIC_DRAW);
// de shaders worden het geheugen in geladen
ShaderSource source = ParseShader("./res/Shaders/Basic.shader");
// (debug) laat de uitvoer van de geparste shaders zien
// om de mysterieuze bug op te lossen
#if DEBUG_OUTPUT_PARSE_SHADER==1
std::cout << "ParseShader : VERTEXr" << source.VertexShader << "rParseShader : FRAGMENTr" << source.FragmentShader << std::endl;
std::cout << "---END---" << "n" << std::endl;
#endif
// het programma wordt aangemaakt en de shaders worden eraan gebonden
unsigned int program = CreateShaders(source.VertexShader, source.FragmentShader);
// het programma wordt geselecteerd
glUseProgram(program);
// dit is de game loop
while (!glfwWindowShouldClose(window)) {
// docs.gl zegt dat dit de buffer leeg haalt maar wss is dat een andere buffer want anders zou de driehoek toch verdwijnen?
glClear(GL_COLOR_BUFFER_BIT);
// hier moet je renderen
glDrawArrays(GL_TRIANGLES, 0, 3);
// hier moet je stoppen met renderen
// glfw heeft twee buffers de front en de back buffer
// de front buffer is wat er nu op het scherm staat
// de back buffer is waar je naar rendert
// glfwSwapBuffers() wisselt deze om
glfwSwapBuffers(window);
// glfwPollEvents() haalt nieuwe informatie van de window system om te kijken of er nieuwe gebruikers input is
// deze gebruik je als je een continue game loop hebt
// als er alleen maar iets hoeft te veranderen als er gebruikersinvoer is hebruik je glfwWaitEvents()
glfwPollEvents();
}
// het programma moet verwijderd worden
glDeleteProgram(program);
glfwTerminate();
return 0;
}
Basic.shader:
#shader vertex
#version 330 core
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
#shader fragment
#version 330 core
layout(location = 0) out vec4 color;
void main()
{
color = vec4(1.0, 0.0, 0.0, 1.0);
}
The error message printed after calling glfwCreateWindow():
Setting <GLFWContentView: 0x1007650c0> as the first responder for window <GLFWWindow: 0x10073bea0>, but it is in a different window ((null))! This would eventually crash when the view is freed. The first responder will be set to nil.
(
0 AppKit 0x00007fff2e896862 -[NSWindow _validateFirstResponder:] + 578
1 AppKit 0x00007fff2dfdd5f0 -[NSWindow _setFirstResponder:] + 31
2 AppKit 0x00007fff2e07bd5d -[NSWindow _realMakeFirstResponder:] + 448
3 OpenGL test 0x0000000100035c3a createNativeWindow + 1034
4 OpenGL test 0x00000001000355cf _glfwPlatformCreateWindow + 63
5 OpenGL test 0x000000010002de57 glfwCreateWindow + 887
6 OpenGL test 0x00000001000014d7 main + 231
7 libdyld.dylib 0x00007fff588ec015 start + 1
)
c++ macos opengl glfw glew
The first step would be to isolate the problem. Try rending solid color window without any geometry first to make sure that presentation is working.
– VTT
Nov 26 '18 at 20:16
Welcome to stackoverflow. You will get better answers if you can provide a minimal example. Right now you have a lot of code, this makes it harder for other users to assist.
– Simon.S.A.
Nov 26 '18 at 20:19
2
This question is quite similar to this. The solution was to use VAO because OpenGL Core Profile requires it. And you don't use a VAO in your code.
– Ripi2
Nov 26 '18 at 20:22
If your tuto doesn't tell about VAOs then change your tuto. One very recommend is learnopengl.com
– Ripi2
Nov 26 '18 at 20:25
I can render a solid color red window using glClearColor()
– J Win
Nov 26 '18 at 20:32
|
show 6 more comments
I am new to programming and OpenGL and I am following The Cherno's OpenGL beginner's tutorial. But instead of drawing a triangle it shows a black screen.
I believe my shaders are being parsed and compiled correctly. I am using Mac OS 10.13 with OpenGL 3.2. GLFW does give an error after loading the window but I've read that the error doesn't have any serious consequences. I have included the error below.
I followed The Cherno's tutorial very closely but due to my lack of experience with OpenGL I had a hard time finding questions similar to mine. I did remove the semicolons after the main() functions in Basic.shader because the shaders would not compile while they were there.
This is my first time posting to StackOverflow so I don't how to format my questions. I am sorry for the dutch commentary, I will write in english from now on ;) If my code is difficult to follow please comment or send me an email at afas460x@gmail.com
EDIT 1: I have discovered it has something to do with a VAO. I have no idea what it is or how to use it. The docs are extremely confusing. Can someone explain?
main.cpp:
// OpenGL test
// Geschreven door Job Winterdijk
// 18-11-2018
// foutcodes door return:
// 2 : !glfwInit
// 3 : !glfwCreateWindow
// 4 : glewInit != GLEW_OK
// 5 : CompileShader()
// 6 : ParseShader() > ongedefieneerde shader
// debug macros
#define DEBUG_OUTPUT_PARSE_SHADER 1
#define DEBUG_OUTPUT_ARGV_0 1
#define DEBUG_OUTPUT_GLSL_VERSION 1
// gedeelde libs
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstring>
// GLEW moet eerder geinclude worden dan ander GL libs
#include "include/GL/glew.h"
// Gedeelde OpenGL libs
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
// Statische libs
#include "include/GLFW/glfw3.h"
struct ShaderSource
{
std::string VertexShader;
std::string FragmentShader;
};
static void TerminateWithError(unsigned int err)
{
// dit is niet goed :(
std::cout << "weg ermee..." << std::endl;
glfwTerminate();
exit(err);
}
static ShaderSource ParseShader(const std::string& path)
{
// maakt een enum type aan om by te houden naar welke stream er geschreven moet worden
enum class ShaderTarget
{
NONE=-1, VERTEX=0, FRAGMENT=1
};
ShaderTarget target = ShaderTarget::NONE;
// maakt een nieuwe input stream aan
std::ifstream stream(path);
// maakt twee nieuwe output streams aan
// 0 = de vertex shader
// 1 = de fragment shader
std::stringstream out[2];
// houd een lijn uit het bestand vast
std::string line;
// deze loop blijft lopen totdat getline == null AKA het einde van het bestand
while (getline(stream, line)) {
if (line.find("#shader") != std::string::npos) {
if (line.find("vertex") != std::string::npos) {
// de vertex shader is gevonden, schrijf naar vertex shader string
target = ShaderTarget::VERTEX;
} else if (line.find("fragment") != std::string::npos){
// de fragment shader is gevonden, schrijf naar fragment shader string
target = ShaderTarget::FRAGMENT;
} else {
TerminateWithError(6);
}
} else {
// de gelezen lijn is een lijn die code bevat
out[(int) target] << line << 'n';
}
}
return {out[0].str(), out[1].str()};
}
static unsigned int CompileShader(const std::string& inputShader, unsigned int type)
{
unsigned int id = glCreateShader(type); // maakt een lege shader aan
const char* inputShaderCS = inputShader.c_str(); // maakt een char pointer naar het eerste element van de CS van std::string, werkt alleen maar zolang de oorspronkelijke string ook blijft bestaan
glShaderSource(id, 1, &inputShaderCS, nullptr); // geeft de ongecompileerde shader door aan OpenGL
glCompileShader(id); // compileert de shader
// hopa we gaan nu error handelen hebbe we er een beetje zin in!!!!!
// glGetShaderiv() haalt informatie over een shader op en stopt dit in een var waar de pointer naar wijst
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
// kijken of het compileren succesvol was
if (result == GL_FALSE) {
// als het niet succesvol was wordt de rede opgeslagen in de info log
// die kan je met getShaderiv() lezen
// net zoals de lengte van de info log
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
// message moet op de heap gealloceerd worden omdat je pas tijdens runtime weet hoelang de foutmelding is
char* message = new char[length];
glGetShaderInfoLog(id, length, &length, message);
// zet het type shader om in menselijke taal
char ShaderTypeString[10];
if (type == GL_VERTEX_SHADER) {
strcpy(ShaderTypeString, "VERTEX");
} else if (type == GL_FRAGMENT_SHADER) {
strcpy(ShaderTypeString, "FRAGMENT");
}
// schrijf een foutmelding naar stderr stream
std::cerr << "[CompileShader(in, type) | main.cpp] Er is een fout opgetreden tijdens het compileren van een shader." << std::endl;
std::cerr << "shader type: " << ShaderTypeString << std::endl;
std::cerr << "Shader info log:n" << message << std::endl;
delete message;
TerminateWithError(5);
}
return id; // returned de aangemaakte en gecompileerde shader
}
static unsigned int CreateShaders(const std::string& vertexShader, const std::string& fragmentShader)
{
unsigned int program = glCreateProgram(); // een programma zorgt ervoor dat meerdere shaders aan elkaar gekoppeld kunnen worden
// compilleert bijde shaders
unsigned int vertexShaderID = CompileShader(vertexShader, GL_VERTEX_SHADER);
unsigned int fragmentShaderID = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
// voegt bijde shader aan het programma toe
glAttachShader(program, vertexShaderID);
glAttachShader(program, fragmentShaderID);
// linkt het programma AKA maakt het programma uitvoerbaar
glLinkProgram(program);
// kijkt of het programma in ?deze staat? uitgevoerd kan worden
glValidateProgram(program);
// verwijderd de shaders, dit kan omdat de shaders nu onderdeel zijn van de program (net als .o bestanden zegmaar)
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
// returned het ID van de program
return program;
}
int main(int argc, char *argv)
{
// (debug) print de uitvoer van argv[0] met als doel te achterhalen wat het path is waarvan main uitgevoerd wordt
#if DEBUG_OUTPUT_ARGV_0==1
std::cout << "executable path: n" << argv[0] << "nn";
#endif
GLFWwindow *window; // het scherm
// initialiseert glfw en tekent een scherm
if (!glfwInit()) return 2;
// dit gaat er hopenlijk voor zorgen dat ik OpenGL 3.3 kan gebruiken
// anders ga ik huilen :(
// ben letterlijk een uur bezig geweest met dit oplossen ;-;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
// glfwCreateWindow geeft een foutmelding
window = glfwCreateWindow(500, 500, "OpenGL test/yehes", NULL, NULL);
if (!window) {
glfwTerminate();
return 3;
}
// selecteert een OpenGL context
glfwMakeContextCurrent(window);
// print de ondersteunde GLSL versie
// handige reminder: dit kan alleen maar als er een actieve OpenGL context is
// anders krijg je eem EXC_BAD_ACCES en dan ben je echt een jaar bezig met de oplossing zoeken
#if DEBUG_OUTPUT_GLSL_VERSION==1
std::cout << "Ondersteunde GLSL versie is: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << "n" << std::endl;
#endif
// initialiseert GLEW
if (glewInit() != GLEW_OK) {
return 4;
}
// de buffer is wat er aan de GPU wordt doorgegeven
unsigned int buffer; // buffer ID
glGenBuffers(1, &buffer); // maakt buffer aan
glBindBuffer(GL_ARRAY_BUFFER, buffer); // selecteert de buffer
// dit verteld OpenGL?of de shader? of de GPU? hoed de vertex geformat is
glEnable(0); // activeert de type vertex
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2, 0); // definieert de type vertex
// dit zijn de vertexen die in de buffer geladen gaan worden
float data[6] = {
-0.5f,-0.5f,
0.0f, 0.5f,
0.5f, -0.5f
};
// maakt de buffer aan en laad de data in de buffer
// als je nog geen dat in de buffer wil laden dan kan je NULL invullen op de plek waarnu data staat
glBufferData(GL_ARRAY_BUFFER, 6*sizeof(float), data, GL_STATIC_DRAW);
// de shaders worden het geheugen in geladen
ShaderSource source = ParseShader("./res/Shaders/Basic.shader");
// (debug) laat de uitvoer van de geparste shaders zien
// om de mysterieuze bug op te lossen
#if DEBUG_OUTPUT_PARSE_SHADER==1
std::cout << "ParseShader : VERTEXr" << source.VertexShader << "rParseShader : FRAGMENTr" << source.FragmentShader << std::endl;
std::cout << "---END---" << "n" << std::endl;
#endif
// het programma wordt aangemaakt en de shaders worden eraan gebonden
unsigned int program = CreateShaders(source.VertexShader, source.FragmentShader);
// het programma wordt geselecteerd
glUseProgram(program);
// dit is de game loop
while (!glfwWindowShouldClose(window)) {
// docs.gl zegt dat dit de buffer leeg haalt maar wss is dat een andere buffer want anders zou de driehoek toch verdwijnen?
glClear(GL_COLOR_BUFFER_BIT);
// hier moet je renderen
glDrawArrays(GL_TRIANGLES, 0, 3);
// hier moet je stoppen met renderen
// glfw heeft twee buffers de front en de back buffer
// de front buffer is wat er nu op het scherm staat
// de back buffer is waar je naar rendert
// glfwSwapBuffers() wisselt deze om
glfwSwapBuffers(window);
// glfwPollEvents() haalt nieuwe informatie van de window system om te kijken of er nieuwe gebruikers input is
// deze gebruik je als je een continue game loop hebt
// als er alleen maar iets hoeft te veranderen als er gebruikersinvoer is hebruik je glfwWaitEvents()
glfwPollEvents();
}
// het programma moet verwijderd worden
glDeleteProgram(program);
glfwTerminate();
return 0;
}
Basic.shader:
#shader vertex
#version 330 core
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
#shader fragment
#version 330 core
layout(location = 0) out vec4 color;
void main()
{
color = vec4(1.0, 0.0, 0.0, 1.0);
}
The error message printed after calling glfwCreateWindow():
Setting <GLFWContentView: 0x1007650c0> as the first responder for window <GLFWWindow: 0x10073bea0>, but it is in a different window ((null))! This would eventually crash when the view is freed. The first responder will be set to nil.
(
0 AppKit 0x00007fff2e896862 -[NSWindow _validateFirstResponder:] + 578
1 AppKit 0x00007fff2dfdd5f0 -[NSWindow _setFirstResponder:] + 31
2 AppKit 0x00007fff2e07bd5d -[NSWindow _realMakeFirstResponder:] + 448
3 OpenGL test 0x0000000100035c3a createNativeWindow + 1034
4 OpenGL test 0x00000001000355cf _glfwPlatformCreateWindow + 63
5 OpenGL test 0x000000010002de57 glfwCreateWindow + 887
6 OpenGL test 0x00000001000014d7 main + 231
7 libdyld.dylib 0x00007fff588ec015 start + 1
)
c++ macos opengl glfw glew
I am new to programming and OpenGL and I am following The Cherno's OpenGL beginner's tutorial. But instead of drawing a triangle it shows a black screen.
I believe my shaders are being parsed and compiled correctly. I am using Mac OS 10.13 with OpenGL 3.2. GLFW does give an error after loading the window but I've read that the error doesn't have any serious consequences. I have included the error below.
I followed The Cherno's tutorial very closely but due to my lack of experience with OpenGL I had a hard time finding questions similar to mine. I did remove the semicolons after the main() functions in Basic.shader because the shaders would not compile while they were there.
This is my first time posting to StackOverflow so I don't how to format my questions. I am sorry for the dutch commentary, I will write in english from now on ;) If my code is difficult to follow please comment or send me an email at afas460x@gmail.com
EDIT 1: I have discovered it has something to do with a VAO. I have no idea what it is or how to use it. The docs are extremely confusing. Can someone explain?
main.cpp:
// OpenGL test
// Geschreven door Job Winterdijk
// 18-11-2018
// foutcodes door return:
// 2 : !glfwInit
// 3 : !glfwCreateWindow
// 4 : glewInit != GLEW_OK
// 5 : CompileShader()
// 6 : ParseShader() > ongedefieneerde shader
// debug macros
#define DEBUG_OUTPUT_PARSE_SHADER 1
#define DEBUG_OUTPUT_ARGV_0 1
#define DEBUG_OUTPUT_GLSL_VERSION 1
// gedeelde libs
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstring>
// GLEW moet eerder geinclude worden dan ander GL libs
#include "include/GL/glew.h"
// Gedeelde OpenGL libs
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
// Statische libs
#include "include/GLFW/glfw3.h"
struct ShaderSource
{
std::string VertexShader;
std::string FragmentShader;
};
static void TerminateWithError(unsigned int err)
{
// dit is niet goed :(
std::cout << "weg ermee..." << std::endl;
glfwTerminate();
exit(err);
}
static ShaderSource ParseShader(const std::string& path)
{
// maakt een enum type aan om by te houden naar welke stream er geschreven moet worden
enum class ShaderTarget
{
NONE=-1, VERTEX=0, FRAGMENT=1
};
ShaderTarget target = ShaderTarget::NONE;
// maakt een nieuwe input stream aan
std::ifstream stream(path);
// maakt twee nieuwe output streams aan
// 0 = de vertex shader
// 1 = de fragment shader
std::stringstream out[2];
// houd een lijn uit het bestand vast
std::string line;
// deze loop blijft lopen totdat getline == null AKA het einde van het bestand
while (getline(stream, line)) {
if (line.find("#shader") != std::string::npos) {
if (line.find("vertex") != std::string::npos) {
// de vertex shader is gevonden, schrijf naar vertex shader string
target = ShaderTarget::VERTEX;
} else if (line.find("fragment") != std::string::npos){
// de fragment shader is gevonden, schrijf naar fragment shader string
target = ShaderTarget::FRAGMENT;
} else {
TerminateWithError(6);
}
} else {
// de gelezen lijn is een lijn die code bevat
out[(int) target] << line << 'n';
}
}
return {out[0].str(), out[1].str()};
}
static unsigned int CompileShader(const std::string& inputShader, unsigned int type)
{
unsigned int id = glCreateShader(type); // maakt een lege shader aan
const char* inputShaderCS = inputShader.c_str(); // maakt een char pointer naar het eerste element van de CS van std::string, werkt alleen maar zolang de oorspronkelijke string ook blijft bestaan
glShaderSource(id, 1, &inputShaderCS, nullptr); // geeft de ongecompileerde shader door aan OpenGL
glCompileShader(id); // compileert de shader
// hopa we gaan nu error handelen hebbe we er een beetje zin in!!!!!
// glGetShaderiv() haalt informatie over een shader op en stopt dit in een var waar de pointer naar wijst
int result;
glGetShaderiv(id, GL_COMPILE_STATUS, &result);
// kijken of het compileren succesvol was
if (result == GL_FALSE) {
// als het niet succesvol was wordt de rede opgeslagen in de info log
// die kan je met getShaderiv() lezen
// net zoals de lengte van de info log
int length;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
// message moet op de heap gealloceerd worden omdat je pas tijdens runtime weet hoelang de foutmelding is
char* message = new char[length];
glGetShaderInfoLog(id, length, &length, message);
// zet het type shader om in menselijke taal
char ShaderTypeString[10];
if (type == GL_VERTEX_SHADER) {
strcpy(ShaderTypeString, "VERTEX");
} else if (type == GL_FRAGMENT_SHADER) {
strcpy(ShaderTypeString, "FRAGMENT");
}
// schrijf een foutmelding naar stderr stream
std::cerr << "[CompileShader(in, type) | main.cpp] Er is een fout opgetreden tijdens het compileren van een shader." << std::endl;
std::cerr << "shader type: " << ShaderTypeString << std::endl;
std::cerr << "Shader info log:n" << message << std::endl;
delete message;
TerminateWithError(5);
}
return id; // returned de aangemaakte en gecompileerde shader
}
static unsigned int CreateShaders(const std::string& vertexShader, const std::string& fragmentShader)
{
unsigned int program = glCreateProgram(); // een programma zorgt ervoor dat meerdere shaders aan elkaar gekoppeld kunnen worden
// compilleert bijde shaders
unsigned int vertexShaderID = CompileShader(vertexShader, GL_VERTEX_SHADER);
unsigned int fragmentShaderID = CompileShader(fragmentShader, GL_FRAGMENT_SHADER);
// voegt bijde shader aan het programma toe
glAttachShader(program, vertexShaderID);
glAttachShader(program, fragmentShaderID);
// linkt het programma AKA maakt het programma uitvoerbaar
glLinkProgram(program);
// kijkt of het programma in ?deze staat? uitgevoerd kan worden
glValidateProgram(program);
// verwijderd de shaders, dit kan omdat de shaders nu onderdeel zijn van de program (net als .o bestanden zegmaar)
glDeleteShader(vertexShaderID);
glDeleteShader(fragmentShaderID);
// returned het ID van de program
return program;
}
int main(int argc, char *argv)
{
// (debug) print de uitvoer van argv[0] met als doel te achterhalen wat het path is waarvan main uitgevoerd wordt
#if DEBUG_OUTPUT_ARGV_0==1
std::cout << "executable path: n" << argv[0] << "nn";
#endif
GLFWwindow *window; // het scherm
// initialiseert glfw en tekent een scherm
if (!glfwInit()) return 2;
// dit gaat er hopenlijk voor zorgen dat ik OpenGL 3.3 kan gebruiken
// anders ga ik huilen :(
// ben letterlijk een uur bezig geweest met dit oplossen ;-;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
// glfwCreateWindow geeft een foutmelding
window = glfwCreateWindow(500, 500, "OpenGL test/yehes", NULL, NULL);
if (!window) {
glfwTerminate();
return 3;
}
// selecteert een OpenGL context
glfwMakeContextCurrent(window);
// print de ondersteunde GLSL versie
// handige reminder: dit kan alleen maar als er een actieve OpenGL context is
// anders krijg je eem EXC_BAD_ACCES en dan ben je echt een jaar bezig met de oplossing zoeken
#if DEBUG_OUTPUT_GLSL_VERSION==1
std::cout << "Ondersteunde GLSL versie is: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << "n" << std::endl;
#endif
// initialiseert GLEW
if (glewInit() != GLEW_OK) {
return 4;
}
// de buffer is wat er aan de GPU wordt doorgegeven
unsigned int buffer; // buffer ID
glGenBuffers(1, &buffer); // maakt buffer aan
glBindBuffer(GL_ARRAY_BUFFER, buffer); // selecteert de buffer
// dit verteld OpenGL?of de shader? of de GPU? hoed de vertex geformat is
glEnable(0); // activeert de type vertex
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*2, 0); // definieert de type vertex
// dit zijn de vertexen die in de buffer geladen gaan worden
float data[6] = {
-0.5f,-0.5f,
0.0f, 0.5f,
0.5f, -0.5f
};
// maakt de buffer aan en laad de data in de buffer
// als je nog geen dat in de buffer wil laden dan kan je NULL invullen op de plek waarnu data staat
glBufferData(GL_ARRAY_BUFFER, 6*sizeof(float), data, GL_STATIC_DRAW);
// de shaders worden het geheugen in geladen
ShaderSource source = ParseShader("./res/Shaders/Basic.shader");
// (debug) laat de uitvoer van de geparste shaders zien
// om de mysterieuze bug op te lossen
#if DEBUG_OUTPUT_PARSE_SHADER==1
std::cout << "ParseShader : VERTEXr" << source.VertexShader << "rParseShader : FRAGMENTr" << source.FragmentShader << std::endl;
std::cout << "---END---" << "n" << std::endl;
#endif
// het programma wordt aangemaakt en de shaders worden eraan gebonden
unsigned int program = CreateShaders(source.VertexShader, source.FragmentShader);
// het programma wordt geselecteerd
glUseProgram(program);
// dit is de game loop
while (!glfwWindowShouldClose(window)) {
// docs.gl zegt dat dit de buffer leeg haalt maar wss is dat een andere buffer want anders zou de driehoek toch verdwijnen?
glClear(GL_COLOR_BUFFER_BIT);
// hier moet je renderen
glDrawArrays(GL_TRIANGLES, 0, 3);
// hier moet je stoppen met renderen
// glfw heeft twee buffers de front en de back buffer
// de front buffer is wat er nu op het scherm staat
// de back buffer is waar je naar rendert
// glfwSwapBuffers() wisselt deze om
glfwSwapBuffers(window);
// glfwPollEvents() haalt nieuwe informatie van de window system om te kijken of er nieuwe gebruikers input is
// deze gebruik je als je een continue game loop hebt
// als er alleen maar iets hoeft te veranderen als er gebruikersinvoer is hebruik je glfwWaitEvents()
glfwPollEvents();
}
// het programma moet verwijderd worden
glDeleteProgram(program);
glfwTerminate();
return 0;
}
Basic.shader:
#shader vertex
#version 330 core
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
#shader fragment
#version 330 core
layout(location = 0) out vec4 color;
void main()
{
color = vec4(1.0, 0.0, 0.0, 1.0);
}
The error message printed after calling glfwCreateWindow():
Setting <GLFWContentView: 0x1007650c0> as the first responder for window <GLFWWindow: 0x10073bea0>, but it is in a different window ((null))! This would eventually crash when the view is freed. The first responder will be set to nil.
(
0 AppKit 0x00007fff2e896862 -[NSWindow _validateFirstResponder:] + 578
1 AppKit 0x00007fff2dfdd5f0 -[NSWindow _setFirstResponder:] + 31
2 AppKit 0x00007fff2e07bd5d -[NSWindow _realMakeFirstResponder:] + 448
3 OpenGL test 0x0000000100035c3a createNativeWindow + 1034
4 OpenGL test 0x00000001000355cf _glfwPlatformCreateWindow + 63
5 OpenGL test 0x000000010002de57 glfwCreateWindow + 887
6 OpenGL test 0x00000001000014d7 main + 231
7 libdyld.dylib 0x00007fff588ec015 start + 1
)
c++ macos opengl glfw glew
c++ macos opengl glfw glew
edited Nov 26 '18 at 20:17
J Win
asked Nov 26 '18 at 20:12
J WinJ Win
11
11
The first step would be to isolate the problem. Try rending solid color window without any geometry first to make sure that presentation is working.
– VTT
Nov 26 '18 at 20:16
Welcome to stackoverflow. You will get better answers if you can provide a minimal example. Right now you have a lot of code, this makes it harder for other users to assist.
– Simon.S.A.
Nov 26 '18 at 20:19
2
This question is quite similar to this. The solution was to use VAO because OpenGL Core Profile requires it. And you don't use a VAO in your code.
– Ripi2
Nov 26 '18 at 20:22
If your tuto doesn't tell about VAOs then change your tuto. One very recommend is learnopengl.com
– Ripi2
Nov 26 '18 at 20:25
I can render a solid color red window using glClearColor()
– J Win
Nov 26 '18 at 20:32
|
show 6 more comments
The first step would be to isolate the problem. Try rending solid color window without any geometry first to make sure that presentation is working.
– VTT
Nov 26 '18 at 20:16
Welcome to stackoverflow. You will get better answers if you can provide a minimal example. Right now you have a lot of code, this makes it harder for other users to assist.
– Simon.S.A.
Nov 26 '18 at 20:19
2
This question is quite similar to this. The solution was to use VAO because OpenGL Core Profile requires it. And you don't use a VAO in your code.
– Ripi2
Nov 26 '18 at 20:22
If your tuto doesn't tell about VAOs then change your tuto. One very recommend is learnopengl.com
– Ripi2
Nov 26 '18 at 20:25
I can render a solid color red window using glClearColor()
– J Win
Nov 26 '18 at 20:32
The first step would be to isolate the problem. Try rending solid color window without any geometry first to make sure that presentation is working.
– VTT
Nov 26 '18 at 20:16
The first step would be to isolate the problem. Try rending solid color window without any geometry first to make sure that presentation is working.
– VTT
Nov 26 '18 at 20:16
Welcome to stackoverflow. You will get better answers if you can provide a minimal example. Right now you have a lot of code, this makes it harder for other users to assist.
– Simon.S.A.
Nov 26 '18 at 20:19
Welcome to stackoverflow. You will get better answers if you can provide a minimal example. Right now you have a lot of code, this makes it harder for other users to assist.
– Simon.S.A.
Nov 26 '18 at 20:19
2
2
This question is quite similar to this. The solution was to use VAO because OpenGL Core Profile requires it. And you don't use a VAO in your code.
– Ripi2
Nov 26 '18 at 20:22
This question is quite similar to this. The solution was to use VAO because OpenGL Core Profile requires it. And you don't use a VAO in your code.
– Ripi2
Nov 26 '18 at 20:22
If your tuto doesn't tell about VAOs then change your tuto. One very recommend is learnopengl.com
– Ripi2
Nov 26 '18 at 20:25
If your tuto doesn't tell about VAOs then change your tuto. One very recommend is learnopengl.com
– Ripi2
Nov 26 '18 at 20:25
I can render a solid color red window using glClearColor()
– J Win
Nov 26 '18 at 20:32
I can render a solid color red window using glClearColor()
– J Win
Nov 26 '18 at 20:32
|
show 6 more comments
0
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53488338%2fopengl-on-mac-os-x-only-draws-black-screen-instead-of-triangle-glew-glfw%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53488338%2fopengl-on-mac-os-x-only-draws-black-screen-instead-of-triangle-glew-glfw%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
The first step would be to isolate the problem. Try rending solid color window without any geometry first to make sure that presentation is working.
– VTT
Nov 26 '18 at 20:16
Welcome to stackoverflow. You will get better answers if you can provide a minimal example. Right now you have a lot of code, this makes it harder for other users to assist.
– Simon.S.A.
Nov 26 '18 at 20:19
2
This question is quite similar to this. The solution was to use VAO because OpenGL Core Profile requires it. And you don't use a VAO in your code.
– Ripi2
Nov 26 '18 at 20:22
If your tuto doesn't tell about VAOs then change your tuto. One very recommend is learnopengl.com
– Ripi2
Nov 26 '18 at 20:25
I can render a solid color red window using glClearColor()
– J Win
Nov 26 '18 at 20:32