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;
}
Related
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 my OpenGL - Hello Triangle demo here but I cant make it work. Does anybody know where the problem can be? I am able to compile and run the code but triangle does not show up. It only opens window with grey background.
#include <glew/glew.h>
#include <glfw/glfw3.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
if (!glfwInit()) {
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
GLFWwindow* window = glfwCreateWindow(800, 800, "Anton Tutorials - Hello Triangle", NULL, NULL);
if (window == NULL) {
fprintf(stderr, "Failed to open GLFW window.\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental = GL_TRUE; // Needed in core profile
const GLenum err = glewInit();
if (err != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
return -1;
}
// Enable depth-testing
glEnable(GL_DEPTH_TEST);
// Depth-testing interprets a smaller value as "closer"
glDepthFunc(GL_LESS);
//Defining vertices for triangle
GLfloat points[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
//Vertex buffer object creation
GLuint vbo = 0;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
//Vertex attribute object creation
GLuint vao = 0;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glDisableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
//Loading shaders - Vertex shader
const char* vertex_shader =
"#version 410\n"
"in vec3 vp; "
"void main() {"
" gl_Position = vec4 (vp, 1.0);"
" }";
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vs, 1, &vertex_shader, NULL);
glCompileShader(vs);
//Loading shaders - Fragment shader
const char* fragment_shader =
"#version 410\n"
"out vec4 frag_colour; "
"void main() {"
" frag_colour = vec4 (0.5, 0.0, 0.5, 1.0);"
" }";
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fs, 1, &fragment_shader, NULL);
glCompileShader(fs);
//Attach shaders
GLuint shader_programme = glCreateProgram();
glAttachShader(shader_programme, fs);
glAttachShader(shader_programme, vs);
glLinkProgram(shader_programme);
//RenderLoop
while (!glfwWindowShouldClose(window))
{
glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(shader_programme);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, 3);
glfwPollEvents();
glfwSwapBuffers(window);
}
glfwTerminate();
return 0;
}
You need to enable the 'vp' attribute.
Earlier in your code, you say this:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
If the layout location of your vp shader variable changes, this might now longer be valid.
It would be better to do this:
GLint vpAttr = glGetAttribLocation(shader_programme, "vp");
glVertexAttribPointer(vpAttr, 3, GL_FLOAT, GL_FALSE, 0, NULL);
Then enable the attribute:
glEnableVertexAttribArray(vpAttr);
Otherwise, you should explicitly set the layout location of vp in vertex shader, so you can confidently use 0:
"layout (location=0) in vec3 vp;"
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.
I just got a laptop with an Intel HD4000 "graphics card" and my code that works on my stationary computer with an HD6950 gives me an access violation. I changed from version 4.4 to 4.0 since the HD4000 only supports up to 4.0.
Looking at the OpenGL wiki for it says it can only guarantee alignment from version 4.2 and up, so I'm thinking that may be the issue but I'm not sure and I don't know how to deal with it
I took this code from open.gl and modified it to use GLFW to test with:
// Link statically with GLEW
#define GLEW_STATIC
// Headers
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <windows.h>
// Shader sources
const GLchar* vertexSource =
"#version 150 core\n"
"in vec2 position;"
"in vec3 color;"
"out vec3 Color;"
"void main() {"
" Color = color;"
" gl_Position = vec4(position, 0.0, 1.0);"
"}";
const GLchar* fragmentSource =
"#version 150 core\n"
"in vec3 Color;"
"out vec4 outColor;"
"void main() {"
" outColor = vec4(Color, 1.0);"
"}";
int main()
{
if(!glfwInit())
return -1;
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = nullptr;
window = glfwCreateWindow(800, 600, "OpenGL", NULL, NULL);
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = GL_TRUE;
int glewRes = glewInit();
if(glewRes != GLEW_OK)
{
glfwTerminate();
OutputDebugStringA(reinterpret_cast<const char*>(glewGetErrorString(glewRes)));
OutputDebugStringA("\n");
return -2;
}
// 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.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
//glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), NULL, GL_DYNAMIC_DRAW);
GLfloat* mappedData = static_cast<GLfloat*>(glMapBufferRange(GL_ARRAY_BUFFER, 0, sizeof(vertices), GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT));
GLenum error = glGetError();
error = glGetError();
error = glGetError();
if(mappedData == NULL)
{
glfwTerminate();
return -3;
}
for(int i = 0; i < ARRAYSIZE(vertices); i++)
{
mappedData[i] = vertices[i];
}
glUnmapBuffer(GL_ARRAY_BUFFER);
// Create an element array
GLuint ebo;
glGenBuffers(1, &ebo);
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, 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, 5 * sizeof(GLfloat), 0);
GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
while(!glfwWindowShouldClose(window))
{
glfwPollEvents();
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw a rectangle from the 2 triangles using 6 indices
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
// Swap buffers
glfwSwapBuffers(window);
}
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &ebo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
glfwTerminate();
}
For some reason whenever I use glMapBufferRange it gives me an access violation at mappedData[i] = vertices[i];.
If I simply use glBufferData or glMapBuffer it works fine
Windows just installed 38 updates and now it works
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;
}