I am fallowing this tutorial http://learnopengl.com/#!Getting-started/Hello-Triangle and problem with this tutorials is that there is no full code example, and it's little hard to fallow. My code run successful, but my triangle is blank / white. And I think some functions is called twice, and program still can run successful if I delete some of that commands.
// SHADERS
GLuint VBO;
GLuint VAO = 0;
GLuint program;
GLuint vertexShader;
GLuint fragmentShader;
const char* vertexShaderSource =
"#version 330"
"layout (location = 0) in vec3 position;"
"void main(){"
"gl_Position = vec4(position.x, position.y, position.z, 1.0);"
"}";
const char* fragmentShaderSource =
"#version 330"
"out vec4 color;"
"void main(){"
"color = vec4(1.0, 0.5, 1.0, 1.0);"
"}";
void compileShaders() {
vertexShader = glCreateShader(GL_VERTEX_SHADER); // pravi vertex shader
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); // Odredjuje izvor vertex shadera
glCompileShader(vertexShader); // kompajlira shader
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(vertexShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
}
void linkShaders() {
program = glCreateProgram(); // pravi program ID
// Linkuje shaderse i program
glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);
glLinkProgram(program);
glUseProgram(program); // koristi program
// Brise shaderse jer vise nisu potrebni i tako oslobadja memoriju
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0); // MISLIM DA JE OVO VISAK
}
void initVBO() {
GLfloat vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
}
void initVAO() {
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
}
void Init() {
glClearColor(0.20, 0.63, 0.67, 1.0);
glViewport(0, 0, WIDTH, HEIGHT);
compileShaders();
linkShaders();
}
void Render() {
glClear(GL_COLOR_BUFFER_BIT);
initVAO();
initVBO();
glUseProgram(program);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0); // oslobadja momoriju
glutSwapBuffers();
}
Your shaders shouldn't compile. As a result, you don't have a valid program. Depending on the profile of the GL context - and the actual GL implementation - you will get different results. With nvidia drivers, you will typically see a white triangle in that scenario.
The reason why your shaders are invalid is because you forgot to add a newline \n after the #version 330 directive.
You are using C/C++'s syntax for concatenating strings by combining "string1" "string2". The fact that you have a newline outside of the quotes is totally irrelevant, the string you are specifying is
#version 330layout (location = 0) in vec3 position;[...]
all in one line, and that is not a valid preprocessor statement...
You always should check the compile status of your shaders, and the link status of your program. And you should always query the compiler and linker info logs. Have a look at the OpenGL wiki artice about shader compilation for details of how to do that.
Related
I want to draw different figures using triangle fans but I am not sure how to make the program draw the second figure. Do I need a second vertexShaderSource and a second fragmentShaderSource each time I want to change the color or draw a new figure?
Here is the code:
#include <GL/glew.h>
#include <GL/glut.h>
#include <stdio.h>
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n""void main()\n"
"{\n"
" FragColor = vec4(1.0f, 0.0f, 0.0f, 0.0f);\n" // To set the color.
"}\n\0";
// Set of vertices for the different figures that make up the drawing.
float vertices[] = {
-0.8f, 0.6f, 0.0f, // Center.
-0.8f, 0.4f, 0.0f,
-0.83f, 0.44f, 0.0f,
-0.87f, 0.51f, 0.0f,
-0.9f, 0.57f, 0.0f,
-0.93f, 0.63f, 0.0f,
-0.95f, 0.69f, 0.0f,
-0.97f, 0.75f, 0.0f,
-0.98f, 0.8f, 0.0f,
-0.91f, 0.8f, 0.0f,
-0.85f, 0.79f, 0.0f,
-0.8f, 0.77f, 0.0f,
};
unsigned int VBO, VAO;
GLuint vertexShader;
GLuint fragmentShader;
GLuint shaderProgram;
void display(void){
// Background color.
glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLE_FAN, 0, 12);
glBindVertexArray(0);
glFlush();
}
// Main.
int main(int argc, char** argv){
glutInit(&argc, argv);
// Color mode.
glutInitDisplayMode(GLUT_RGBA);
// Window size.
glutInitWindowSize(500, 500);
// Title.
glutCreateWindow("Tarea 3: Figura con curvas");
GLenum err = glewInit();
if(err!=GLEW_OK) {
printf("glewInit failed: %s",glewGetErrorString(err));
exit(1);
}
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glutDisplayFunc(display);
glutMainLoop();
}
No is not necessary (or recommended) to use different shaders for the meshes. If you want to draw multiple objects, then you can put the vertex attributes of the meshes to separate Vertex Buffer Objects:
GLuint VBOs[2];
glGenBuffers(2, VBOs);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices_1, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices_2, GL_STATIC_DRAW);
Specify a Vertex Array Object for each mesh:
GLuint VAOs[2];
glGenVertexArrays(2, VAOs);
glBindVertexArray(VAOs[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(VAOs[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBOs[1]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
Bind the VAO, before the draw call:
glBindVertexArray(VAOs[0]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 12);
glBindVertexArray(VAOs[1]);
glDrawArrays(...);
Of course it is also possible to put all the vertex attributes of the different meshes consecutively in the data store of one VBO. If the vertex specification is identically, then it is event possible to use one single VAO.
Different locations of different meshes can be achieved by vertex transformation in the vertex shader. Use a Uniform of type mat4, to transform the vertices of a mesh:
#version 330 core
layout (location = 0) in vec3 aPos;
uniform mat4 u_model;
void main()
{
gl_Position = u_model * vec4(aPos.xyz, 1.0);
}
See further LearnOpenGL - Transformations.
If the 2 figures are identical, but have just a different location, then you can draw the same mesh twice, but you have to change the model transformation u_model.
You are looking for Uniform buffer objects.
If you have only a single value for a whole draw call, then your shader should be parametrized. The obvious thing you want to parametrize first is the color in the fragment shader, followed by adding a projection matrix to the vertex shader.
From that point onwards it's just alternating between setting new values to uniforms and draw-calls as long as it is the same 3D model.
For different models refer to #rabbid76's answer.
I am trying to create a simple program with openGL. The goal is to create a triangle with colours for every vertex. The problem is that I can not figure out how to apply the colours to the triangle's vertices.
My vertex shader:
#version 330
layout(location = 0) in vec4 vertex_position;
layout(location = 1) in vec4 vertex_color;
smooth out vec4 theColor;
void main()
{
gl_Position = vec4(vertex_position.x, vertex_position.y, vertex_position.z, 1.0);
theColor = vertex_color;
}
My fragment shader:
#version 330
smooth in vec4 theColor;
out vec4 outColor;
void main()
{
outColor = theColor;
}
main code:
float vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f,
0.5f, 0.6f, 0.1f,
0.2f, 0.6, 0.3f,
0.1f, 0.23f, 0.78f
};
GLuint my_vao, my_vbo;
glGenVertexArrays(1, &my_vao);
glBindVertexArray(my_vao);
glGenBuffers(1, &my_vbo);
glBindBuffer(GL_ARRAY_BUFFER, my_vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
// glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
// glVertexAttribPointer(3,4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(vao);
glViewport(0, 0, viewport_width, viewport_height);
glDrawArrays(GL_TRIANGLES, 0, 3);
swapBuffers();
The array vertices consists of the vertex points (first 3 vectors) and the color values (second 3 vectors). You can see my result in the following picture:
I have been trying to apply the colours with the following code:
glEnableVertexAttribArray(1);
glVertexAttribPointer(3,4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (void*)0);
Unfortunately it does not work and I have no idea how to fix that. Can anyone help me out here?
For compiling and loading my shaders I use:
std::string loadVertexShader(const char* vertexPath)
{
std::string vertexCode;
std::ifstream vShaderFile;
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try
{
vShaderFile.open(vertexPath);
std::stringstream vShaderStream;
vShaderStream << vShaderFile.rdbuf();
vShaderFile.close();
vertexCode = vShaderStream.str();
}
catch (std::ifstream::failure e)
{
std::cout << "ERROR::VERTEXSHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
return vertexCode;
}
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
std::string vertexVal = loadVertexShader("shader/vertexshader.shader");
const char* vShaderCode = vertexVal.c_str();
std::string fragmentVal = loadFragmentShader("shader/fragmentshader.shader");
const char* fShaderCode = fragmentVal.c_str();
glShaderSource(vertexShader, 1, &vShaderCode, NULL);
glCompileShader(vertexShader);
glShaderSource(fragmentShader, 1, &fShaderCode, NULL);
glCompileShader(fragmentShader);
GLint vertexStatus;
char vertexInfoLog[512];
char fragmentInfoLog[512];
glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &vertexStatus);
GLint fragmentStatus;
glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &fragmentStatus);
if (!vertexStatus)
{
glGetShaderInfoLog(vertexShader, 512, NULL, fragmentInfoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << fragmentInfoLog << std::endl;
}
if (!fragmentStatus)
{
glGetShaderInfoLog(fragmentShader, 512, NULL, vertexInfoLog);
std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << vertexInfoLog << std::endl;
}
First of all, as was revealed in the discussion in comments, you don't link your program. A typical shader program setup looks like this:
GLuint program = glCreateProgram();
glAttachShader(program, shader1);
glAttachShader(program, shader2);
...
glAttachShader(program, shaderN);
glLinkProgram(program); // <<<<<<<<< a-ha!
After that, a good idea is to check if program linkage was OK. A good example of the full shaders & program setup can be found on OpenGL wiki.
After successful program linkage, you can even detach the shaders from the program (glDetachShader) and delete them (glDeleteShader) - the program is already linked, shaders are of no use now (unless you intend to attach them to another program, of course).
Secondly, your arguments to glVertexAttribPointer are slightly messed up (which is totally OK - it takes time and effort to get used to them).
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
GLsizei stride, const GLvoid * pointer);
index is the attribute index - same as location as specified in shader, so for your color attribute it should be 1.
size is the attribute's dimension, i.e. number of components; supposing that you are using 3-float RGB, size should be 3
type is the actual type of the components; in you case these are floating-points too, so GL_FLOAT
stride is the distance between attributes of adjacent vertices, which is 3 floats in your case, i.e. 12 bytes; since there's nothing in between adjacent attributes in your vertices array, we can actually leave this zero (both for coordinates & colors)
pointer is the pointer to actual attributes data (or, in your case, offset in VBO); you are passing the same pointer to both glVertexAttribPointer calls, while your color values are 9 floats after the beginning of coordinate values
So, it should be
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (float const *)(nullptr) + 9);
So I've been building a pretty simple piece of code that renders .OBJ files and lets the user look around using VBOs and the most simple GLSL shaders immaginable, but when run the window is just a static image (looks like the object seen from 0,0,0). Without the shader program it still renders normally, just without color. Any idea what I colud be doing wrong?
VBO & shader stuff:
//Create buffer for vertex data (x,y,z)
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vector3f), &vertices[0], GL_STATIC_DRAW);
//Create buffer for color data (r,g,b)
glGenBuffers(1, &colorBuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ARRAY_BUFFER, temp.size() * sizeof(vector3f), &temp[0], GL_STATIC_DRAW);
//Create and compile shaders
GLuint vertShader = 0, fragShader = 0, program = 0;
createShader("vertex.glsl", GL_VERTEX_SHADER, vertShader);
createShader("fragment.glsl", GL_FRAGMENT_SHADER, fragShader);
program = glCreateProgram();
glAttachShader(program, vertShader);
glAttachShader(program, fragShader);
glBindAttribLocation(program, vertexAttribIndex, "vertex_position");
glBindAttribLocation(program, colorAttribIndex, "vertex_colour");
glLinkProgram(program);
printShaderInfoLog(vertShader);
printProgramInfoLog(program);
//Set attribute pointers for GLSL
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glVertexAttribPointer(vertexAttribIndex, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(vertexAttribIndex);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
glVertexAttribPointer(colorAttribIndex, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(colorAttribIndex);
Render loop:
while (!glfwWindowShouldClose(window)) {
glClearColor(0.0F, 0.0F, 0.0F, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glUseProgram(program);
glViewport(0, 0, width, height);
gluPerspective(70.0, width / height, 1.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, vertBufferSize);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glfwSwapBuffers(window);
glfwPollEvents();
}
Vertex shader:
#version 420
layout(location = 0) in vec3 vertex_position;
layout(location = 1) in vec3 vertex_colour;
out vec3 colour;
out vec4 gl_Position;
void main () {
colour = vertex_colour;
gl_Position = vec4 (vertex_position, 1.0);
}
Fragment shader:
#version 420
in vec3 colour;
out vec4 colorOut;
void main () {
colorOut = vec4(colour, 1.0);
}
Sorry if I've missed out anything obvious, I've been fighting this for hours.
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 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