I am trying to make a game in C++ and using SDL2 with OpenGL.
When I try to draw a simple triangle to the opengl context with GLEW nothing is showing up. I haven't used opengl before.
Here is my code:
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/gl.h>
#include <SDL2/SDL.h>
#include <iostream>
I have Fragment and Vertex shaders but StackOverflow said I had too much code and not enough details.
int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
SDL_Window* window = SDL_CreateWindow("GAME", 100, 100, 800, 600, SDL_WINDOW_OPENGL);
SDL_GLContext context = SDL_GL_CreateContext(window);
glewExperimental = GL_TRUE;
glewInit();
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
printf("%u\n", vertexBuffer);
float vertices[] = {
0.0f, 0.5f,
0.5f, -0.5f,
-0.5f, -0.5f
};
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER,vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posAttrib);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
SDL_Event event;
while(true)
{
if (SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT) break;
}
SDL_GL_SwapWindow(window);
glClearColor(0.2578125f, 0.52734375f, 0.95703125f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
SDL_GL_DeleteContext(context);
SDL_Quit();
return 0;
}
I compile this with g++ src/main.cpp glad/src/glad.c -I./glad/include -o main -lGL -lglfw -lGLEW -ldl -lSDL2 -ldl --std=c++14
The vertex specification is stored in the Vertex Array Object. glVertexAttribPointer and glEnableVertexAttribArray set states in the currently bound VAO. So you have to create and bind the VAO before the vertex specification.
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posAttrib);
Related
I mean for the following code to draw a horizontal line across the screen. Instead, it draws the line and then draws a line that fades off towards the origin. A picture is posted below.
I think that the critical pieces of code are
float vertices[] =
{
-0.5, 0.7, 1, 1, 1,
0.5, 0.7, 1, 1, 1
};
and
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
while (not glfwWindowShouldClose(window))
{
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_LINE_STRIP, 0, sizeof(vertices)/sizeof(float));
glfwSwapBuffers(window);
glfwPollEvents();
}
The full code is
# include <GL/glew.h>
# include <GLFW/glfw3.h>
const GLchar * vertex_shader_source =
"\
# version 150 core\n\
in vec2 position;\
in vec3 color;\
out vec3 Color;\
void main() { Color = color; gl_Position = vec4(position, 0, 1); }\
";
const GLchar * fragment_shader_source =
"\
# version 150 core\n\
in vec3 Color;\
out vec4 outColor;\
void main() { outColor = vec4(Color, 1.0); }\
";
float vertices[] =
{
-0.5, 0.7, 1, 1, 1,
0.5, 0.7, 1, 1, 1
};
int main (int argc, char ** argv)
{
// ---- INITIALIZE STUFF ---- //
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(800, 600, "open-gl", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
// ---- MAKE SHADERS ---- //
GLuint vertex_shader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex_shader, 1, &vertex_shader_source, NULL);
glCompileShader(vertex_shader);
GLuint fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment_shader, 1, &fragment_shader_source, NULL);
glCompileShader(fragment_shader);
GLuint shader_program = glCreateProgram();
glAttachShader(shader_program, vertex_shader);
glAttachShader(shader_program, fragment_shader);
glBindFragDataLocation(shader_program, 0, "outColor");
glLinkProgram(shader_program);
glUseProgram(shader_program);
// ---- MAKE VERTEX BUFFER OBJECT ---- //
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
// ---- MAKE VERTEX ARRAY OBJECT ---- //
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLint posAttrib = glGetAttribLocation(shader_program, "position");
GLint colAttrib = glGetAttribLocation(shader_program, "color");
glEnableVertexAttribArray(posAttrib);
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5*sizeof(float), 0);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5*sizeof(float), (void*)(2*sizeof(float)));
// ---- DO OTHER THINGS ---- //
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
while (not glfwWindowShouldClose(window))
{
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glDrawArrays(GL_LINE_STRIP, 0, sizeof(vertices)/sizeof(float));
glfwSwapBuffers(window);
glfwPollEvents();
}
// ---- CLEAN UP ---- //
glDeleteProgram(shader_program);
glDeleteShader(vertex_shader);
glDeleteShader(fragment_shader);
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
glfwTerminate();
return 0;
}
The output is
I have no idea what the problem is; I have searched the internet, but I cannot find anyone who has had a similar problem. The best that I have found is someone who said that OpenGL implementations do not tend to do lines very well. This does not happen with GL_LINES, however.
I am using OpenGL 3.2 with GLFW and GLEW. I have an Acer Aspire v5-571P-6648; I do not know specifically what model of graphics card it has, but I can look for it.
You last argument for
glDrawArrays(GL_LINE_STRIP, 0, sizeof(vertices)/sizeof(float));
is wrong, it should be 2 (see https://www.opengl.org/sdk/docs/man/html/glDrawArrays.xhtml).
I tried simple openGl program to draw triangle, i am able to see only black screen on window.
Below is the code for your reference.
Let me know what i am doing wrong.
// Headers
#include <GL/glew.h>
#include <GL/glut.h>//Drawing funciton
#include <GL/freeglut.h>
// Link statically with GLEW
#define GLEW_STATIC
// Shader sources
const GLchar* vertexSource =
"##version 300 es\n"
"in vec2 position;"
"void main()"
"{"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSource =
"##version 300 es\n"
"out vec4 outColor;"
"void main()"
"{"
" outColor = vec4(1.0, 1.0, 1.0, 1.0);"
"}";
int main(int argc,char**argv)
{ glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(800,600);
glutCreateWindow("GW");
//glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE,GLUT_ACTION_GLUTMAINLOOP_RETURNS);
// Initialize GLEW
glewExperimental = GL_TRUE;
glewInit();
// Create Vertex Array Object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo;
glGenBuffers(1, &vbo);
GLfloat vertices[] = {
0.0f, 0.5f,
0.5f, -0.5f,
-0.5f, -0.5f
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Create and compile the vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
// Create and compile the fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
bool running = true;
while (running)
{
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw a triangle from the 3 vertices
glDrawArrays(GL_TRIANGLES, 0, 3);
// Swap buffers
glutSwapBuffers();
}
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
return 0;
}
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 following open.gl and I have gotten to the rendering stage but my triangle does not appear on the screen. Only a black box.
I'm on Win7, latest drivers and everything, VS2013.
To make it easy I put the code here:
#define GLEW_STATIC
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
using namespace std;
int main() {
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(800, 600, "OpenGL", nullptr, nullptr);
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE;
glewInit();
float vertices[] = {
0.0f, 0.5f,
0.5f, -0.5f,
-0.5f, -0.5f
};
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
const char* vertexShaderCode =
"#version 150\n"
"in vec2 position;"
"void main() {"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const char* fragmentShaderCode =
"#version 150\n"
"out vec4 outColor;"
"void main() {"
" outColor = vec4(1.0, 1.0, 1.0, 1.0);"
"}";
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderCode, NULL);
glCompileShader(vertexShader);
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderCode, NULL);
glCompileShader(fragmentShader);
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
glUseProgram(shaderProgram);
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(posAttrib);
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
while(!glfwWindowShouldClose(window)) {
glfwPollEvents();
glfwSwapBuffers(window);
glDrawArrays(GL_TRIANGLES, 0, 3);
}
glfwTerminate();
}
Bind the VAO before you specify the vertex layout:
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(0);
Check all glFw commands for failure. For debugging check glGetError after every OpenGL command. Also make sure your shaders have compiled correctly, if not make sure you print the error messages.
Lastly, check the viewport.
Ok Im trying to learn OpenGL 3.x, I used to use the old interface, and its not really going to well. Im using SDL2 for windowing and input.
What I would think the code should do is draw a red triangle on a blue background. The Problem is that it only does this sometimes, actually it seems to be completely random, sometimes it does that sometimes it just displays a black window.
I have no ideas as to why.
#include "SDL2/SDL.h"
#include "GL/glew.h"
GLuint makeShader(const char * shader, GLint t){
//---- Make Shader ----
GLuint s = glCreateShader(t);
glShaderSource(s, 1, &shader, NULL);
glCompileShader(s);
//---- Get Error Msg ----
int l=0;
glGetShaderiv(s, GL_INFO_LOG_LENGTH, &l);
char *msg = new char [l+1];
glGetShaderInfoLog(s, l, NULL, msg);
printf("Shader MSG: %s", msg);
delete [] msg;
return s;
}
int main(){
//----Init SDL & GL Context----
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *screen = SDL_CreateWindow("My Game Window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
//1024, 768,
640, 480,
SDL_WINDOW_OPENGL);
SDL_GLContext glContext = SDL_GL_CreateContext(screen);
SDL_Event e;
//----Init GLEW---
glewExperimental=true;
GLenum err = glewInit();
if(GLEW_OK != err)
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
//----VAO----
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
//----Make Shaders----
const char *vscr = "#version 330 core\nlayout(location = 0) in vec4 position;\nvoid main(){gl_Position = position * 0.5; gl_Position.w = 1.0;}";
GLuint vshader = makeShader(vscr, GL_VERTEX_SHADER);
const char *fscr = "#version 330 core\nout vec3 color;\nvoid main(){ color = vec3(1,0,0);}";
GLuint fshader = makeShader(fscr, GL_FRAGMENT_SHADER);
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, vshader);
glAttachShader(ProgramID, fshader);
glLinkProgram(ProgramID);
// ----make geometry----
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,
};
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);
glViewport(0,0,640,480);
glClearColor(0.0f, 0.0f, 1.0f, 0.0f);
//----MAIN LOOP----
while(1){
glClear(GL_COLOR_BUFFER_BIT);
SDL_PollEvent(&e);
glUseProgram(ProgramID);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glFlush();
SDL_GL_SwapWindow(screen);
if(e.type == SDL_QUIT)
break;
}
SDL_GL_DeleteContext(screen);
return 0;
}