Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I'm trying to get screenWidth and screenHeight into my fragment shader through uniform variables. Here's my main.cpp where the offender lies, I can get the location (non -1) but when it actually sets the uniform variable thingy I segfault.
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include "math_3d.h"
#include "shader.h"
// Global
GLuint VBO;
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 CreateVertexBuffer()
{
Vector3f Verticies[3];
Verticies[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Verticies[1] = Vector3f(1.0f, -1.0f, 0.0f);
Verticies[2] = Vector3f(0.0f, 1.0f, 0.0f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Verticies), Verticies, GL_STATIC_DRAW);
}
int main(int argc, char** argv)
{
const int SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
glutInitWindowPosition(100, 100);
glutCreateWindow("Test Window");
glutDisplayFunc(RenderSceneCB);
GLenum res = glewInit();
if(res != GLEW_OK)
{
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION);
printf("Renderer: %s\n", renderer);
printf("Version: %s\n", version);
Shader vertexShader(GL_VERTEX_SHADER, "shader.vs");
Shader fragShader(GL_FRAGMENT_SHADER, "shader.fs");
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader.shader);
glAttachShader(program, fragShader.shader);
glLinkProgram(program);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
printf("No link\n");
}
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &status);
if (status == GL_FALSE)
{
printf("No validate\n");
}
glUseProgram(program);
printf("UNIFORM\n");
// Set uniform variables
GLint location = glGetUniformLocation(program, "screenWidth");
printf("loc: %d\n", location);
glProgramUniform1i(program, location, 800);
/*
GLint location2 = glGetUniformLocation(program, "screenHeight");
printf("loc: %d\n", location2);
glProgramUniform1i(program, location2, 600);
printf("uniform done\n");
*/
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glPointSize(10.0f);
CreateVertexBuffer();
glutMainLoop();
return 0;
}
The shader looks like this:
#version 130
uniform int screenWidth = 800;
uniform int screenHeight = 600;
out vec4 FragColor;
void main()
{
FragColor = vec4(gl_FragCoord.x/screenWidth, gl_FragCoord.y/screenHeight, 0.0, 1.0);
}
Your problem is actually that glProgramUniform1i (...) is relatively new. You have not come out and stated your OpenGL version explicitly, but your shader targets GLSL 1.30 (OpenGL 3.0) so chances are very good your implementation does not understand that function.
That function started out life in the Direct State Access extension (GL_EXT_direct_state_access), where it goes by the name glProgramUniform1iEXT (...) and was promoted to core when Separate Shader Objects were (GL 4.1).
The only difference between the two functions (glUniform1i (...) and glProgramUniform1i{EXT} (...)) is that one uses the currently bound program object, and the other lets you pass the one you need.
Changed how I set the uniform variables to this and everything worked out. I changed glProgramUniform1i to glUniform1i and took away the program parameter.
Here's the final main.cpp, look for the uniform section to see my changes.
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <stdio.h>
#include "math_3d.h"
#include "shader.h"
// Global
GLuint VBO;
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 CreateVertexBuffer()
{
Vector3f Verticies[3];
Verticies[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Verticies[1] = Vector3f(1.0f, -1.0f, 0.0f);
Verticies[2] = Vector3f(0.0f, 1.0f, 0.0f);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(Verticies), Verticies, GL_STATIC_DRAW);
}
int main(int argc, char** argv)
{
const int SCREEN_WIDTH = 800, SCREEN_HEIGHT = 600;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
glutInitWindowPosition(100, 100);
glutCreateWindow("Test Window");
glutDisplayFunc(RenderSceneCB);
GLenum res = glewInit();
if(res != GLEW_OK)
{
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
}
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION);
printf("Renderer: %s\n", renderer);
printf("Version: %s\n", version);
Shader vertexShader(GL_VERTEX_SHADER, "shader.vs");
Shader fragShader(GL_FRAGMENT_SHADER, "shader.fs");
GLuint program = glCreateProgram();
glAttachShader(program, vertexShader.shader);
glAttachShader(program, fragShader.shader);
glLinkProgram(program);
GLint status;
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
printf("No link\n");
}
glValidateProgram(program);
glGetProgramiv(program, GL_VALIDATE_STATUS, &status);
if (status == GL_FALSE)
{
printf("No validate\n");
}
glUseProgram(program);
// Set uniform variables
GLint location = glGetUniformLocation(program, "screenWidth");
glUniform1i(location, 800);
GLint location2 = glGetUniformLocation(program, "screenHeight");
glUniform1i(location2, 600);
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glPointSize(10.0f);
CreateVertexBuffer();
glutMainLoop();
return 0;
}
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 months ago.
Improve this question
I just started learning OpenGL by following https://learnopengl.com/Getting-started/Hello-Triangle, following the tutorial I wrote the code as per my understanding which compiles and does give me an output but instead of an orangish triangle it shows a white one. If I replace the shaderProgram() with the code from https://learnopengl.com/code_viewer_gh.php?code=src/1.getting_started/2.1.hello_triangle/hello_triangle.cpp it works (shows the orange triangle), so I think I narrowed the problem to shader program compilation, I just couldn't find what's wrong with it, following is my code.
// Local Headers
#include "glitter.hpp"
// System Headers
#include <glad/glad.h>
#include <GLFW/glfw3.h>
// Standard Headers
#include <cstdio>
#include <cstdlib>
#include <stdexcept>
#include <iostream>
#include <memory>
void _delete_shader(const GLuint *shader)
{
if (!shader) return;
glDeleteShader(*shader);
delete shader;
}
using shader_t = std::unique_ptr<GLuint, decltype(&_delete_shader)>;
// window resize callback
void framebuffer_size_callback(GLFWwindow* , int width, int height)
{
glViewport(0, 0, width, height);
}
void processInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, true);
}
}
shader_t compileShader(const char *source, GLenum shaderType)
{
auto shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &source, nullptr);
glCompileShader(shader);
int success;
char log[512];
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shader, sizeof(log), nullptr, log);
throw std::runtime_error(log);
}
return shader_t(new GLuint {shader}, &_delete_shader);
}
shader_t vertexshader() try
{
static const char *source = R"(
#version 330 core
layout (location = 0) in vec3 aPos;
void main()
{
gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
)";
return compileShader(source, GL_VERTEX_SHADER);
}
catch(const std::exception& e)
{
printf("error in vertex shader, %s\n", e.what());
exit(-1);
}
shader_t fragmentShader() try
{
static const char *source = R"(
#version 330 core
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}
)";
return compileShader(source, GL_FRAGMENT_SHADER);
}
catch(const std::exception &e)
{
printf("error in fragment shader, %s\n", e.what());
exit(-1);
}
uint32_t shaderProgram() try
{
uint32_t program = glCreateProgram();
const auto vertexShader = ::vertexshader();
glAttachShader(program, *vertexShader);
const auto fragmentShader = ::fragmentShader();
glAttachShader(program, *fragmentShader);
glLinkProgram(program);
int success;
glGetProgramiv(program, GL_LINK_STATUS, &success);
if (!success)
{
char log[512];
glGetProgramInfoLog(program, 512, nullptr, log);
throw std::runtime_error(log);
}
}
catch(const std::exception &e)
{
printf("error in shader program, %s\n", e.what());
exit(-1);
}
int main(int , char * [])
{
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, "LearnOpenGL", nullptr, nullptr);
if (window == nullptr)
{
printf("Failed to create window\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
puts("Failed to initialize GLAD\n");
glfwTerminate();
return -1;
}
glViewport(0, 0, 800, 600);
float vertices[] =
{
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
const auto shaderProgram = ::shaderProgram();
unsigned int VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).
glBindVertexArray(VAO);
// copy vertices into gpu memory
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// how data should be interpreted
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *)0);
glEnableVertexAttribArray(0);
// note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's bound vertex buffer object so afterwards we can safely unbind
glBindBuffer(GL_ARRAY_BUFFER, 0);
// You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
// VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.
glBindVertexArray(0);
while (!glfwWindowShouldClose(window))
{
// inputs
processInput(window);
// paint color
glClearColor(.2f, .3f, .3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// draw triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
// final rendering step
glfwSwapBuffers(window);
// check for events
glfwPollEvents();
}
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteProgram(shaderProgram);
glfwTerminate();
return 0;
}
shaderProgram() never returns anything, so the name of your GL program object is just lost, and your shaderProgram local variable contains just some undefined value, hence you never use that program.
Note that such mistakes will be spotted by almost every decent compiler, just enable (and read) the warnings...
I'm learning OpenGL with SDL2, and following this tutorial, and I have come to the Drawing Polygons -> Shaders part. However, although I have done everything that the tutorial have instructed, I'm not able to get any output from the code,
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
//Glew
#define GLEW_STATIC
#include <GL/glew.h>
//SDL headers
#include "SDL.h"
#include "SDL_opengl.h"
//OpenGL headers
#include <OpenGL/gl.h>
#include <OpenGL/glext.h>
//Constants
#define SCREEN_H 800
#define SCREEN_W 600
#define SCREEN_POS_X 0
#define SCREEN_POS_Y 0
#define SCREEN_FLAGS SDL_WINDOW_SHOWN|SDL_WINDOW_INPUT_FOCUS|SDL_WINDOW_MOUSE_FOCUS|SDL_WINDOW_OPENGL
//SDL_WINDOWPOS_CENTERED
bool done = false;
SDL_Window * pWindow = NULL;
SDL_GLContext pGLContext = NULL;
//Methods
int Init(void );
void GameLoop();
void Render();
void EventTick();
void Quit(void );
// Shader sources
const GLchar* vertexSource = R"glsl(
#version 150 core
in vec2 position;
void main()
{
gl_Position = vec4(position, 0.0, 1.0);
}
)glsl";
const GLchar* fragmentSource = R"glsl(
#version 150 core
out vec4 outColor;
void main()
{
outColor = vec4(1.0, 1.0, 1.0, 1.0);
}
)glsl";
int main(int argc, char const *argv[])
{
Init();
GameLoop();
Quit();
return 0;
}
int Init()
{
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr, "SDL_Error: %s\n", SDL_GetError());
return -1;
}
//Compatibility
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, 2);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
pWindow = SDL_CreateWindow("Main", SCREEN_POS_X, SCREEN_POS_Y, SCREEN_W, SCREEN_H, SCREEN_FLAGS);
if (pWindow == NULL)
{
fprintf(stderr, "SDL_Error: %s\n", SDL_GetError());
return -1;
}
pGLContext = SDL_GL_CreateContext(pWindow);
glewExperimental = GL_TRUE;
glewInit();
return 0;
}
void GameLoop()
{
printf("%s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
printf("%s\n", glGetString(GL_VERSION));
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
float Vertices[] = {
0.0f, 20.0f,
20.0f, 0.0f,
20.0f, 20.0f
};
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);
//Check the vertex shader compilation
GLint status_vertex;
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &status_vertex);
if (status_vertex != GL_TRUE)
{
char buffer[512];
glGetShaderInfoLog(vertexShader, 512, NULL, buffer);
fprintf(stdout, "Vertex Shader: %s\n", buffer);
}
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
//Check the fragment shader compilation
GLint status_fragment;
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status_fragment);
if (status_fragment != GL_TRUE)
{
char buffer[512];
glGetShaderInfoLog(fragmentShader, 512, NULL, buffer);
fprintf(stdout, "Fragment Shader: %s\n", buffer);
}
GLuint shaderProgram = glCreateProgram();
if (shaderProgram == 0)
{
fprintf(stderr, "glGetError: %u\n", glGetError());
}
glBindAttribLocation(shaderProgram, 0, "position");
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);
GLint program_linked;
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &program_linked);
if (program_linked != GL_TRUE)
{
GLsizei log_length = 0;
GLchar message[1024];
glGetProgramInfoLog(shaderProgram, 1024, &log_length, message);
fprintf(stdout, "%s\n", message);
}
fprintf(stderr, "glGetError (End): %u\n", glGetError());
fprintf(stderr, "SDL Error: %s\n", SDL_GetError());
while(!done)
{
EventTick();
Render();
}
fprintf(stderr, "glGetError (End): %u\n", glGetError());
fprintf(stderr, "SDL Error: %s\n", SDL_GetError());
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
}
void Render()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0f, 1.0f, 0.0f);
glDrawArrays(GL_TRIANGLES, 0, 3);
SDL_GL_SwapWindow(pWindow);
}
void EventTick()
{
SDL_Event s_GameEngEvent;
while(SDL_PollEvent(&s_GameEngEvent))
{
switch(s_GameEngEvent.type)
{
case SDL_QUIT:
{
fprintf(stdout, "SQL is quitting...\n");
done = true;
}break;
case SDL_KEYDOWN:
{
switch(s_GameEngEvent.key.keysym.scancode)
{
case SDL_SCANCODE_ESCAPE:
{
fprintf(stdout, "SQL is quitting...\n");
done = true;
}break;
default:
break;
}
}break;
}
}
}
void Quit(void )
{
//Destructions...
SDL_GL_DeleteContext(pGLContext);
SDL_DestroyWindow(pWindow);
SDL_Quit();
}
I have several parts of the code one by one, and compared to the original code, but found nothing.
I would really appreciated if someone could check where the problematic part is. I mean I know I did not try to write a good code above, I was trying to focus on how the OpenGL works, but for the time being my goal is to find the error that I'm making.
Note:
I'm not sure whether such questions are acceptable in here, if so,please close it.
Edit:
I'm compiling the code using g++ with c++11.
The triangle you try to draw is outside of the visible area. By default (that means without any projections/transformations applied), the visible area goes from -1 to 1 on all three axis. The triangle used in the code does not intersect this area, thus nothing gets rendered.
Besides that: You are calling the glColor3f function which is deprecated in a core profile. This should report a GL_INVALID_OPERATION which you are most probably not seeing because error checking only happens when the renderloop has ended. You should really check for errors somewhere inside the renderloop.
I'm trying to draw a triangle using glDrawArrays function and gl Vertex, Color pointers.
The result is only black empty screen.
static const GLfloat vboData[] =
{ -0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
};
static const GLfloat colors[]={
0.0f, 1.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f,
};
while(!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vboData);
glColorPointer(3, GL_FLOAT, 0, colors);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glfwSwapBuffers(window);
glfwPollEvents();
}
Using VBO and VAO also doesn't work.
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
static const GLfloat vboData[] =
{ -0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
};
GLuint vbo;
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vboData), vboData, GL_STATIC_DRAW);
while(!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(vao);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
So, what I needed to get my code working is adding shaders to the project.
Here is minimal example.
This is my main.cpp
#include <iostream>
#include <fstream>
#include <algorithm>
#include "Loader.hpp"
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLFWwindow *window;
int main(void)
{
//Viewport,window setup using GLFW;
if(!glfwInit()){
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
window = glfwCreateWindow(640, 480, "OpenGL Triangle", NULL, NULL);
if(!window){
glfwTerminate();
exit(EXIT_FAILURE);
}
glfwMakeContextCurrent(window);
glewExperimental = true;
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}
//Loading and compiling shaders;
GLuint shaderID = LoadShader("vertexs.shader", "fragments.shader");
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
static const GLfloat vboData[] =
{ -1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
};
GLuint vbo;
glGenBuffers(1,&vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vboData), vboData, GL_STATIC_DRAW);
glUseProgram(shaderID); //Attaching shaders
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
while(!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwSwapBuffers(window);
glfwPollEvents();
}
glDeleteBuffers(1, &vbo);
glDeleteProgram(shaderID);
glDeleteVertexArrays(1, &vao);
glfwTerminate();
exit(EXIT_SUCCESS);
return 0;
}
Loader.hpp
#ifndef Loader_hpp
#define Loader_hpp
#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
GLuint LoadShader(const char* vertex_file_path, const char* fragment_file_path);
#endif
Loader.cpp
#include "Loader.hpp"
GLuint LoadShader(const char * vertex_file_path,const char * fragment_file_path)
{
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open()){
std::string Line = "";
while(getline(VertexShaderStream, Line))
VertexShaderCode += "\n" + Line;
VertexShaderStream.close();
}
else
{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path);
getchar();
return 0;
}
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open())
{
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "\n" + Line;
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s\n", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 )
{
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
printf("%s\n", &VertexShaderErrorMessage[0]);
}
// Compile Fragment Shader
printf("Compiling shader : %s\n", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 )
{
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
printf("%s\n", &FragmentShaderErrorMessage[0]);
}
// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 )
{
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
printf("%s\n", &ProgramErrorMessage[0]);
}
glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
vertexs.shader (extension actually doesn't matter)
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
void main()
{
//We're not modifying positions of vertices
gl_Position.xyz = vertexPosition_modelspace;
gl_Position.w = 1.0;
}
fragments.shader
#version 330 core
out vec3 color;
void main()
{
color = vec3(1,0,1);
}
I also found these tutorials extremely useful to make this solution, so the code above is partially taken from there.
I have tried to create two rectangle objects with two different colors and moving in opposite direction. However, I am stuck in rendering the two rectangle with different colors (currently they are the same color).
What is the way to do it?
Here is the code:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "ogldev_util.h"
#include "ogldev_math_3d.h"
GLuint VBO1;
GLuint VBO2;
GLuint gScaleLocation1;
GLuint gScaleLocation2;
const char* pVSFileName = "shader.vs";
const char* pFSFileName = "shader.fs";
static void RenderSceneCB()
{
glClear(GL_COLOR_BUFFER_BIT);
static float Scale1 = 0.0f;
Scale1 += 0.01f;
glUniform1f(gScaleLocation1, sinf(Scale1));
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
static float Scale2 = 0.0f;
Scale2 -= 0.01f;
glUniform1f(gScaleLocation2, sinf(Scale2));
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
glutSwapBuffers();
}
static void InitializeGlutCallbacks()
{
glutDisplayFunc(RenderSceneCB);
glutIdleFunc(RenderSceneCB);
}
static void CreateVertexBuffer()
{
Vector3f Vertices[6];
Vertices[0] = Vector3f(1.0f, -0.5f, 0.0f);
Vertices[1] = Vector3f(1.0f, 0.5f, 0.0f);
Vertices[2] = Vector3f(3.0f, -0.5f, 0.0f);
Vertices[3] = Vector3f(1.0f, 0.5f, 0.0f);
Vertices[4] = Vector3f(3.0f, 0.5f, 0.0f);
Vertices[5] = Vector3f(3.0f, -0.5f, 0.0f);
glGenBuffers(1, &VBO1);
glBindBuffer(GL_ARRAY_BUFFER, VBO1);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
Vector3f Vertices2[6];
Vertices2[0] = Vector3f(-3.0f, -0.5f, 0.0f);
Vertices2[1] = Vector3f(-3.0f, 0.5f, 0.0f);
Vertices2[2] = Vector3f(-1.0f, -0.5f, 0.0f);
Vertices2[3] = Vector3f(-3.0f, 0.5f, 0.0f);
Vertices2[4] = Vector3f(-1.0f, 0.5f, 0.0f);
Vertices2[5] = Vector3f(-1.0f, -0.5f, 0.0f);
glGenBuffers(1, &VBO2);
glBindBuffer(GL_ARRAY_BUFFER, VBO2);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices2), Vertices2, 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(1);
}
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);
gScaleLocation1 = glGetUniformLocation(ShaderProgram, "gScale");
assert(gScaleLocation1 != 0xFFFFFFFF);
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(1024, 768);
glutInitWindowPosition(100, 100);
glutCreateWindow("Tutorial 05");
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;
}
Fragment Shader
#version 330
out vec4 FragColor;
void main()
{
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
It depends. Easiest way in this case is to add uniform vec3 color; and gl_FragColor = vec4(color, 1.0); inside your fragment shader and then initialize it with desired color by invoking glUniform3f before rendering of each rectangle. However, with rectangle count growth you would be better to create your vertex struct that will carry not only coordinates, but a color as well.
Also, I highly recommend this http://www.opengl-tutorial.org/ opengl tutorials web site.
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;
}