I've written a simple OpenGL 3.3 program which is supposed to render a triangle, based off of this tutorial, except I'm using GLFW to create the window and context, instead of doing it from scratch. Also, I'm using Ubuntu.
The triangle doesn't render though, I just get a black screen. Functions like glClearColor() and glClear() seem to be working exactly as they should, but the code to render the triangle doesn't. Here are the relevant bits of it:
#define GLFW_INCLUDE_GL_3
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int main ()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(800, 600, "GLFW test", NULL, NULL);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
float vertices[] = {-0.5f, -0.5f, 0.0f, 0.5f, 0.5f, -0.5f};
GLuint VBOid[1];
glClear(GL_COLOR_BUFFER_BIT);
glGenBuffers(1, VBOid);
glBindBuffer(GL_ARRAY_BUFFER, VBOid[0]);
glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBOid[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 3);
...
}
What am I missing?
In core profile OpenGL 3.3, you need a shader in order to render. So you need to compile and link a program that contains a vertex and fragment shader.
Related
This is my code:
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
const int IMAGE_SIZE = 32;
GLFWwindow* window;
GLuint vao;
GLuint vbo;
int initWindow() {
// Initialize GLFW
if (!glfwInit()) {
cerr << "Error: Failed to initialize GLFW." << endl;
return 1;
}
// Set up GLFW window hints for OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Create window
window = glfwCreateWindow(IMAGE_SIZE * 20, IMAGE_SIZE * 20 + 60, "PBM Image", NULL, NULL);
if (!window) {
cerr << "Error: Failed to create GLFW window." << endl;
glfwTerminate();
return 1;
}
// Create context
glfwMakeContextCurrent(window);
// Set color and blendmode
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Create and bind VAO and VBO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao); // Here is the spot where I get the exception
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
return 0;
}
void renderImage(vector<unsigned char> vertices) {
// Update VBO data
glBufferData(GL_ARRAY_BUFFER, vertices.size(), vertices.data(), GL_STATIC_DRAW);
// Set vertex attribute pointers
glVertexAttribPointer(0, 3, GL_UNSIGNED_BYTE, GL_FALSE, 3 * sizeof(unsigned char), (void*)0);
glEnableVertexAttribArray(0);
// Unbind VBO and VAO
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
// Set up projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, IMAGE_SIZE, 0.0, IMAGE_SIZE, 0.0, 1.0);
// Clear screen
glClear(GL_COLOR_BUFFER_BIT);
// Bind VAO
glBindVertexArray(vao);
// Draw points
glDrawArrays(GL_POINTS, 0, vertices.size() / 3);
// Unbind VAO
glBindVertexArray(0);
// Swap buffers
glfwSwapBuffers(window);
}
int main() {
if (initWindow()) return 1;
// Here comes the code that generates vector<unsigned char> vertices
renderImage(vertices);
getchar();
// Delete VAO and VBO
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
// Terminate GLFW
glfwTerminate();
return 0;
}
It uses glew to setup opengl and glfw for window handling. After initializing the window it generates vector<unsigned char> vertices which renderImage takes in. Afterwards it removes VAO, VBO and terminates GLFW. But it won't even come to that point because it throws the following exception at glBindVertexArray(vao);:
Exception thrown at 0x0000000000000000 in generator.exe: 0xC0000005: Access violation executing location 0x0000000000000000.
Here are my lib and include settings and folders:
VC++ Directories
Input
Lib Folder
Lib x64 Folder
Include GL
Include GLFW
glew needs to be initialized (see Initializing GLEW). If glew is not initialized, the OpenGL API function pointers are not set. Call glewInit() right after glfwMakeContextCurrent(window):
glfwMakeContextCurrent(window);
if (glewInit() != GLEW_OK)
return 1;
I am trying to make a triangle and I'm using GLEW, GLFW and GLM as extensions of OpenGL.
Here's the code I have:
#include <stdlib.h>
#include <stdio.h>
#include <gl\glew.h>
#include <GLFW\glfw3.h>
#include <glm\glm.hpp>
using namespace glm;
int main()
{
if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); //We don't want the old OpenGL
// Open a window and create its OpenGL context
GLFWwindow* window; // (In the accompanying source code, this variable is global)
window = glfwCreateWindow(1024, 768, "Tutorial 01", NULL, NULL);
if (window == NULL)
{
fprintf(stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window); // Initialize GLEW
glewExperimental = true; // Needed in core profile
if (glewInit() != GLEW_OK)
{
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// An array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
// This will identify our vertex buffer
GLuint vertexbuffer;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
// The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
do {
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);
}
Edit
The code is not displaying the white triangle its just opens the window and shows empty black.
Also at first I added the code I messed around with, which is missing part of the code. However it still does not produce the white triangle.
Do I need to use a shader for OpenGL 3.3?
You need to use a shader or you won't see anything. If you do see something then that is unspecified behavior. Which highly depend on each individual driver.
You could try fiddling with the clear color and clear the screen:
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
The tutorial was able to get a white triangle on a black background. On my computer the opposite was the case.
The tutorial also points out:
If you’re on lucky, you can see the result (don’t panic if you don’t)
So read the rest of the tutorial, it also includes a shader.
I am running a basic openGL program that compiles and runs fine in command prompt with the command
g++ gltest.cpp -std=c++11 -lglew32s -lglfw3 -lgdi32 -lopengl32 -o gltest.exe
but when I try to use it in netbeans it gives me a bunch of "undefined reference to `_imp____glewCreateShader'" errors. All references to glew functions.
I have the needed libraries put in the linker options
here is the code:
// g++ gldrop.cpp -std=c++11 -lglew32s -lglfw3 -lgdi32 -lopengl32 -o gldrop.exe
#define GLEW_STATIC
#include <iostream>
#include "gl\glew.h"
#include "gl\glfw3.h"
#include "shaderM.cpp"
#include "glm\glm\gtc\matrix_transform.hpp"
#include "glm\glm\glm.hpp"
#include "data.cpp"
GLFWwindow* window;
int main(int argv, char** argc)
{
//initialize GLFW
if (!glfwInit())
{
std::cout << "Failed to initialize GLFW \n";
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//create GLFW window
window = glfwCreateWindow(640, 480, "GL", NULL, NULL);
glfwMakeContextCurrent(window);
glewExperimental = true;
//initialize GLEW
if(glewInit() != GLEW_OK)
{
std::cout << "failed to initialize glew";
return -1;
}
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
//background
glClearColor(0.4f, 0.3f, 0.7f, 0.0f);
//depth test
glEnable(GL_DEPTH_TEST);
//takes fragments closer to the camera
glDepthFunc(GL_LESS);
//Vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//Vertex buffer
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
//color buffer
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
//create shaders and attach them to a program object
GLuint program = rigShadersToProgram();
GLuint matrixID = glGetUniformLocation(program, "MVP");
//projection matrix 45 degree FoV, 4:3 ratio, display range 0.1 - 100
glm::mat4 projection = glm::perspective(70.0f, 4.0f/3.0f, 0.1f, 100.0f);
//camera matrix
glm::mat4 view = glm::lookAt(
glm::vec3(4,3,-3), //camera is at (4,3,-3)
glm::vec3(0,0, 0), //looks at origin
glm::vec3(0,1, 0) //head is up
);
//model matrix identity matrix
glm::mat4 model = glm::mat4(1.0f);
//model-view-projection
glm::mat4 MVP = projection * view * model;
while (!glfwWindowShouldClose(window))
{
//clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//use the compiled shaders
glUseProgram(program);
//send transformation matrix to currently bound shader
glUniformMatrix4fv(matrixID, 1, GL_FALSE, &MVP[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, //index
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
0 //array buffer offset
);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
1, //index
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
0 //array buffer offset
);
//draw triangle
glDrawArrays(GL_TRIANGLES, 0, 12*3); //start # vertex 0, 3 verticies
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &colorbuffer);
glDeleteProgram(program);
glDeleteVertexArrays(1, &vao);
glfwTerminate();
return 0;
}
Not sure why it won't recognize the libraries.
Where did you download glew32?
maybe you downloaded the Visual C version if not you could've unpacked the wrong version (64 bit).
Another thing I've heard (try this first)
I've had issues with glew32s on mingw and for some reason it doesn't work, use regular glew32. It should still work with the preprocessor and compiles statically without any issue.
I'm going through the second "chapter" on http://www.open.gl and running into a drawing issue which I can't figure out.
int main()
{
//Initialize GLFW, create the window and the context
glfwInit();
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, GL_TRUE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(1024, 768, "Open.GL Drawing 1", nullptr, nullptr);
glfwMakeContextCurrent(window);
//initialize GLEW after context creation
glewExperimental = GL_TRUE;
glewInit();
//loading, compiling, and checking shaders takes place here
[...]
//create, link, and use the shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
//create and bind the vao for the position data
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//triangle vertecies
GLfloat verticies[] = {
0.0f, 0.5f,
0.5f, -0.5f,
-0.5f, -0.5f
};
//vbo for verticies
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW);
//link, define, and enable the position attribute (aka, the verticies)
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posAttrib);
//main loop!
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
}
//clean up after yourself
glfwTerminate();
glDeleteProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
return EXIT_SUCCESS;
}
Vertex shader:
#version 150
in vec2 position;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
}
Fragment shader:
#version 150
out vec4 outColor;
void mian()
{
outColor = vec4(1.0, 1.0, 1.0, 1.0);
}
When compiled with
g++ -fdiagnostics-color -Wall -Wextra -std=c++11 -lGLEW -lGLU -lGL -lglfw -o drawing1 drawing1.cpp
I get no warnings, but a blank screen when the program runs. I checked the example code he links as well as the github copy of the example source. Unfortunately, he uses SFML whereas I'm using GLFW, so I attempted to compensate for that difference.
I did my best to mimic his example code (ordering of things, etc) as well as adding in the last few lines of main() and the main loop (there was no mention of deleting shaders or clearing the viewport's color in the tutorial, but those statements were present in his example code) but still wound up with the same result. Checking glGetError() gave me an invalid enum error, but this post says that might be an expected behavior with glewExperimental.
After that, I'm not sure how to further isolate the issue. I look forward to someone pointing out what will obviously be a simple mistake. =)
As Joey Dewd pointed out, I didn't proof read my shader code very well. For the record, it was me typing mian instead of main in my fragment shader that caused the issues. On his suggestion, I added code to check for errors in linking (I was already checking for compilation errors) and sure enough, when I recreated my typo, the linker complained.
Fragment info
-------------
(0) : error C3001: no program defined
Thanks Joey. =)
This is my code so far, it's just tutorial code from open.gl
#include <GL/GL.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <thread>
#define GLEW_STATIC
int main(){
//printf("%s\n", glGetString(GL_EXTENSIONS))
glewExperimental = GL_TRUE;
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL", nullptr, nullptr); // Windowed
//GLFWwindow* window = glfwCreateWindow(1920, 1080, "OpenGL", glfwGetPrimaryMonitor(), nullptr); fs
//typedef void (*GENBUFFERS) (GLsizei, GLuint*);
//GENBUFFERS glGenBuffers = (GENBUFFERS)glfwGetProcAddress("glGenBuffers");
printf("%s\n", glGetString(GL_EXTENSIONS));
glfwMakeContextCurrent(window);
glewInit();
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
printf("%u\n", vertexBuffer);
float vertices[] = {
0.0f, 0.5f, // Vertex 1 (X, Y)
0.5f, -0.5f, // Vertex 2 (X, Y)
-0.5f, -0.5f // Vertex 3 (X, Y)
};
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//glfwSetWindowShouldClose(window, GL_FALSE);
while(!glfwWindowShouldClose(window)){
glfwSwapBuffers(window);
glfwPollEvents();
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
}
glfwTerminate();
}
returns the exception above... what is going on and what's wrong?
the error drops at glGenBuffers(1,&vertexBuffer);
I'm still very new to opengl programming so please break it down into autismally small pieces for me if you can :)
An error occurring at location 0 suggests you're trying to call a function using a null function pointer. The culprit in your case seems to be glGenBuffers. It's been in the core for a long time, so it's almost certainly supported by your machine. It probably just hasn't been initialised properly.
You can get libraries such as GLEW (GL Extension Wrangler) to help you with that. It's not something you should rely on long-term, but can definitely help you get started without worrying about lots of details.
Alternatively, a very quick-and-dirty solution may be just to call glGenBuffersARB() instead. Again, that's definitely not something to rely on long-term though!
These questions may help:
glGenBuffers not defined?
OpenGL: How to check if the user supports glGenBuffers()?