How to draw a VAO made out of 5 triangles in OpenGL? - c++

I have recently written a program to draw a triangle with 3 different RGB values and I want to do the same with another separate VAO in the same program but I want this one composed of 5 triangles. Here is my main.cpp:
void framebuffer_size_callback(GFLWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
// Shaders
const char *vertexShaderSource =
"#version 410\n"
"in vec3 vp;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(aPos, 1.0);\n"
"}\0";
const char *fragmentShader1Source =
"#version 410\n"
"out vec4 FragColor;\n"
"in vec3 myColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(myColor, 1.0f);\n"
"}\n\0";
int main ()
{
// start GL context and O/S window using the GLFW helper library
if (!glfwInit ())
{
fprintf (stderr, "ERROR: could not start GLFW3\n");
return 1;
}
// uncomment these lines if on Apple OS X
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(640, 480, "LearnOpenGL", NULL, NULL);
if (!window)
{
fprintf(stderr, "ERROR: could not open window with GLFW3\n");
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
// start GLEW extension handler
glewExperimental = GL_TRUE;
glewInit();
// get version info
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION);
printf("Renderer: %s\n", renderer);
printf("OpenGL version supported %s\n", version);
glEnable(GL_DEPTH_TEST); // enable depth-testing
glDepthFunc(GL_LESS);
/* OTHER STUFF GOES HERE */
// Draw a single triangle VBO
float points[] = {
// positions // colors
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f 0.0f, 1.0f
};
GLuint VBO = 0;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
// Generate a VAO.
GLuint VAO = 0;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
// Compile a Vertex Shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// Compile a fragment shader.
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// Compile shaders into a executable shader program.
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, fragmentShader);
glAttachShader(shaderProgram, vertexShader);
glLinkProgram(shaderProgram);
// Drawing the triangles aka render loop
while (!glfwWindowShouldClose(window))
{
processInput(window);
// wipe the drawing surface clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw Triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
// Draw Triangle Fan; unfinished
// swap buffers and poll IO events
glfwPollEvents();
glfwSwapBuffers(window);
}
// close GL context and any other GLFW resources
glfwTerminate();
return 0;
}
Do I simply create another float "points" matrix like I did with my first VBO or something else? The tutorial Im following wasn't perfectly clear on this part.
Also, Im using Xcode on my Mac and I created separate .cpp files for my Fragment and Vertex shaders. Should I switch those to header files instead?

You have to specify an input attribute for the color (aColor) and to pass the color attribute from the vertex shader to the fragment shader (myColor). Use Layout Qualifiers to specify the attribute indices.
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
out vec3 myColor;
void main()
{
myColor = aColor;
gl_Position = vec4(aPos, 1.0);
}
#version 330 core
out vec4 FragColor;
in vec3 myColor;
void main()
{
FragColor = vec4(myColor, 1.0f);
}
Note your current vertex shader does not compile. Check if compiling of a shader succeeded checked by glGetShaderiv and the parameter GL_COMPILE_STATUS and if the linking of a program was successful can be checked by glGetProgramiv and the parameter GL_LINK_STATUS. See the answer to OpenGL ignores Quads and makes them Triangles for some code snippets.
Your vertices are tuples with 6 components (x, y, z, r, g, b):
float points[] = {
// positions // colors
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f 0.0f, 1.0f
};
Use glVertexAttribPointer to specify 2 vertex attributes. The stride and the offset have to be specified in bytes. The stride is 6 * sizeof(float). The offset of the vertex coordinates is 0 and the offset of the color attributes is 3 * sizeof(float). e.g:
GLuint VBO = 0;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
// Generate a VAO.
GLuint VAO = 0;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), NULL);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
If you want to draw more complex meshes, then you have to extend the vertes arrays. Just add another 3 vertices and colors to points array for the next triangle. Alternatively you can use a different primitive type like GL_TRIANGLE_STRIP or GL_TRIANGLE_FAN. See Triangle primitives
Example code:
#include <iostream>
#include <vector>
// Shaders
const char *vertexShaderSource = R"(#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aColor;
out vec3 myColor;
void main()
{
myColor = aColor;
gl_Position = vec4(aPos, 1.0);
}
)";
const char *fragmentShaderSource = R"(#version 330 core
out vec4 FragColor;
in vec3 myColor;
void main()
{
FragColor = vec4(myColor, 1.0f);
}
)";
bool CompileStatus( GLuint shader );
bool LinkStatus( GLuint program );
float radians( float deg ) { return deg * 3.141529 / 180.0; }
int main ()
{
// start GL context and O/S window using the GLFW helper library
if (!glfwInit())
{
fprintf (stderr, "ERROR: could not start GLFW3\n");
return 1;
}
// uncomment these lines if on Apple OS X
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);
GLFWwindow* window = glfwCreateWindow(640, 480, "LearnOpenGL", NULL, NULL);
if (!window)
{
fprintf(stderr, "ERROR: could not open window with GLFW3\n");
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
// start GLEW extension handler
glewExperimental = GL_TRUE;
glewInit();
// get version info
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION);
printf("Renderer: %s\n", renderer);
printf("OpenGL version supported %s\n", version);
glEnable(GL_DEPTH_TEST); // enable depth-testing
glDepthFunc(GL_LESS);
/* OTHER STUFF GOES HERE */
// Draw a single triangle VBO
float points[] = {
// positions // colors
0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f * cos(radians(72)), 0.5f * sin(radians(72)), 0.0f, 0.0f, 0.0f, 1.0f,
0.5f * cos(radians(144)), 0.5f * sin(radians(144)), 0.0f, 1.0f, 1.0f, 0.0f,
0.5f * cos(radians(216)), 0.5f * sin(radians(216)), 0.0f, 0.0f, 1.0f, 1.0f,
0.5f * cos(radians(288)), 0.5f * sin(radians(288)), 0.0f, 1.0f, 0.0f, 1.0f,
0.5, 0.0f, 0.0f, 1.0f, 0.5f, 0.0f
};
GLuint VBO = 0;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
// Generate a VAO.
GLuint VAO = 0;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), NULL);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float)));
// Compile a Vertex Shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
CompileStatus( vertexShader );
// Compile a fragment shader.
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
CompileStatus( fragmentShader );
// Compile shaders into a executable shader program.
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, fragmentShader);
glAttachShader(shaderProgram, vertexShader);
glLinkProgram(shaderProgram);
LinkStatus( shaderProgram );
// Drawing the triangles aka render loop
while (!glfwWindowShouldClose(window))
{
//processInput(window);
// wipe the drawing surface clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw Triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLE_FAN, 0, 7);
// Draw Triangle Fan; unfinished
// swap buffers and poll IO events
glfwPollEvents();
glfwSwapBuffers(window);
}
// close GL context and any other GLFW resources
glfwTerminate();
return 0;
}
bool CompileStatus( GLuint shader )
{
GLint status = GL_TRUE;
glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
if (status == GL_FALSE)
{
GLint logLen;
glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetShaderInfoLog( shader, logLen, &written, log.data() );
std::cout << "compile error:" << std::endl << log.data() << std::endl;
}
return status != GL_FALSE;
}
bool LinkStatus( GLuint program )
{
GLint status = GL_TRUE;
glGetProgramiv( program, GL_LINK_STATUS, &status );
if (status == GL_FALSE)
{
GLint logLen;
glGetProgramiv( program, GL_INFO_LOG_LENGTH, &logLen );
std::vector< char >log( logLen );
GLsizei written;
glGetProgramInfoLog( program, logLen, &written, log.data() );
std::cout << "link error:" << std::endl << log.data() << std::endl;
}
return status != GL_FALSE;
}

You would do this by adding creating another float array containing your new points, and creating another VAO and VBO. Since you want a triangle fan (based on the comment in your code), and not 5 individual triangles you would make it like this:
float points_5_triangles[] = {
// positions // colors
// Original triangle
x1, y1, z1, r1, g1, b1, // point 1
x2, y2, z2, r2, g2, b2, // point 2
x3, y3, z3, r3, g3, b3, // point 3
// Another triangle made from point 1, 3 and 4
x4, y4, z4, r4, g4, b4,
// Another triangle made from point 1, 4 and 5
x5, y5, z5, r5, g5, b5,
// Another triangle made from point 1, 5 and 6
x6, y6, z6, r6, g6, b6,
// Another triangle made from point 1, 6 and 7
x7, y7, z7, r7, g7, b7,
};
GLuint VBO_5_triangles = 0;
glGenBuffers(1, &VBO_5_triangles);
glBindBuffer(GL_ARRAY_BUFFER, VBO_5_triangles);
glBufferData(GL_ARRAY_BUFFER, sizeof(points_5_triangles), points_5_triangles, GL_STATIC_DRAW);
// Generate another VAO.
GLuint VAO_5_triangles = 0;
glGenVertexArrays(1, &VAO_5_triangles);
glBindVertexArray(VAO_5_triangles);
glBindBuffer(GL_ARRAY_BUFFER, VBO_5_triangles);
glBufferData(GL_ARRAY_BUFFER, sizeof(points_5_triangles), points_5_triangles, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
Now when drawing your two objects you would first bind the target VAO, then render, then carry on to the next object:
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(VAO_5_triangles);
glDrawArrays(GL_TRIANGLE_FAN, 0, 7);
For more information on how a triangle fan is drawn see Triangle primitives

Related

OpenGL fragment shader crashes with EXC_BAD_ACCESS on glDrawArrays

I'm using OpenGL 3.3 on Mac OSX 11.5.2. I have 6 fragment shaders, 3 that works and 3 that crashes with EXC_BAD_ACCESS. They all use the same vertex shader. There have been many questions about this problem, but I've made sure to:
Unbind my previous state.
Made sure attribute arrays enabled and used.
Am only using a single-thread, i.e. no concurrency.
The shaders that crash are all using one array of offsets and a kernel to do post-processing effects. If I replace texture_coordinate.st + offsets[i] with just texture_coordinate.st, it'll work just fine. As this makes the offsets array unused and optimized out, I have a suspicion that it could be due to a register allocation bug as mentioned in the comments in this question, but can't confirm.
I've also checked for other problems, such as loading them in different orders, using different compiler flags, but the crashes are consistent.
Here's a minimal, reproducible example (dependent on glad and glfw3, compiled with c++17) with one of the problematic shaders.
#include <glad/glad.h>
#include <GLFW/glfw3.h>
const char VERTEX_POST[] = R"(
#version 330 core
layout (location = 0) in vec2 position;
layout (location = 1) in vec2 in_texture_coordinate;
out vec2 texture_coordinate;
void main()
{
gl_Position = vec4(position.x, position.y, 0.0, 1.0);
texture_coordinate = in_texture_coordinate;
}
)";
const char FRAGMENT_POST[] = R"(
#version 330 core
in vec2 texture_coordinate;
out vec4 FragColor;
uniform sampler2D image;
const float offset = 1.0 / 300.0;
void main()
{
vec2 offsets[9] = vec2[](
vec2(-offset, offset), // top-left
vec2( 0.0f, offset), // top-center
vec2( offset, offset), // top-right
vec2(-offset, 0.0f), // center-left
vec2( 0.0f, 0.0f), // center-center
vec2( offset, 0.0f), // center-right
vec2(-offset, -offset), // bottom-left
vec2( 0.0f, -offset), // bottom-center
vec2( offset, -offset) // bottom-right
);
float kernel[9] = float[](
-1, -1, -1,
-1, 9, -1,
-1, -1, -1
);
vec3 sample_texture[9];
for(int i = 0; i < 9; i++)
sample_texture[i] = vec3(texture(image, texture_coordinate + offsets[i]));
vec3 color = vec3(0.0);
for (int i = 0; i < 9; i++)
color += sample_texture[i] * kernel[i];
FragColor = vec4(color, 1.0);
}
)";
float vertices[] = {
// Positions // Texture coords
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 0.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 0.0f, 0.0f,
1.0f, -1.0f, 0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f, 1.0f, 1.0f
};
GLuint create_shader(const char* source, GLenum type)
{
GLuint id = glCreateShader(type);
glShaderSource(id, 1, &source, nullptr);
glCompileShader(id);
int success;
glGetShaderiv(id, GL_COMPILE_STATUS, &success);
assert(success);
return id;
}
int main()
{
// ---- INIT GLFW & GLAD ----
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, GLFW_TRUE);
GLFWwindow* window = glfwCreateWindow(800, 800, "Temp", nullptr, nullptr);
if (window == nullptr) return -1;
glfwMakeContextCurrent(window);
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) return -1;
// ---- CREATE QUAD ----
GLuint quad, vbo;
glGenVertexArrays(1, &quad);
glGenBuffers(1, &vbo);
glBindVertexArray(quad);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)0);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(3 * sizeof(float)));
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// ---- CREATE TEXTURE ----
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
char data[800 * 800 * 4] = {};
for (char& i : data) i = 127;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 800, 800, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
// ---- CREATE SHADER PROGRAM ----
GLuint vertex_shader = create_shader(VERTEX_POST, GL_VERTEX_SHADER);
GLuint fragment_shader = create_shader(FRAGMENT_POST, GL_FRAGMENT_SHADER);
GLuint program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader);
glLinkProgram(program);
glValidateProgram(program);
int success;
glGetProgramiv(program, GL_LINK_STATUS, &success);
assert(success);
// ---- MAIN LOOP ----
while (!glfwWindowShouldClose(window))
{
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(program);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);
glUniform1i(glGetUniformLocation(program, "image"), 0);
glBindVertexArray(quad);
glDrawArrays(GL_TRIANGLES, 0, 6);
glfwSwapBuffers(window);
glfwPollEvents();
}
return 0;
}
The example gives me a grey image when not including offsets and otherwise exhibits the crash. What could be causing this?

My square I'm trying to render isn't showing up when using OpenGL [duplicate]

This question already has an answer here:
Why is the sprite not rendering in OpenGL?
(1 answer)
Closed 2 years ago.
I'm trying to render a square using two triangles, and then applying some transformations, but for whatever reason it isn't showing up. Here is the code:
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace std;
#define WINDOW_TITLE "Modern OpenGL 3D Cube"
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version "\n" #Source
#endif
GLint shaderProgram, windowWidth = 800, windowHeight = 600;
GLuint VBO, VAO, EBO, texture;
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShader(void);
void UCreateBuffers(void);
const GLchar* vertexShaderSource = GLSL(330,
layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color;
out vec3 mobileColor;
uniform mat4 shaderTransform;
void main() {
gl_Position = shaderTransform * vec4(position, 1.0f);
mobileColor = color;
});
const GLchar* fragmentShaderSource = GLSL(330,
in vec3 mobileColor;
out vec4 gpuColor;
void main() {
gpuColor = vec4(mobileColor, 1.0);
});
//main program
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(windowWidth, windowHeight);
glutCreateWindow(WINDOW_TITLE);
glutReshapeFunc(UResizeWindow);
glewExperimental = GL_TRUE;
if (glewInit() != GLEW_OK) {
cout << "Failed to initialize GLEW" << endl;
return -1;
}
UCreateShader();
UCreateBuffers();
glUseProgram(shaderProgram);
glClearColor(0, 0, 0, 1);
glutDisplayFunc(URenderGraphics);
glutMainLoop();
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &EBO);
return 0;
}
void UResizeWindow(int w, int h) {
windowWidth = w;
windowHeight = h;
glViewport(0, 0, windowWidth, windowHeight);
}
void URenderGraphics(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(VAO);
glm::mat4 currentTransform;
currentTransform = glm::translate(currentTransform, glm::vec3(0.0f, 0.5f, 0.0f));
currentTransform = glm::rotate(currentTransform, 45.0f, glm::vec3(0.0f, 0.0f, 1.0f));
currentTransform = glm::scale(currentTransform, glm::vec3(0.5f, 0.5f, 0.5f));
GLuint transformLocation = glGetUniformLocation(shaderProgram, "shaderTransform");
glUniformMatrix4fv(transformLocation, 1, GL_FALSE, glm::value_ptr(currentTransform));
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glutSwapBuffers();
}
void UCreateShader() {
GLint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
GLint 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);
}
void UCreateBuffers() {
GLfloat vertices[] = {
0.5f, 0.5f, 0.0f, 1, 0, 0, //top right vertex 0
0.5f, -0.5f, 0.0f, 0, 1, 0, //bottom right vertex 1
-0.5f, -0.5f, 0.0f, 0, 0, 1, //bottom left vertex 2
-0.5f, 0.5f, 0.0f, 1, 0, 1 //top left vertex 3
};
GLuint indices[] = {
0, 1, 3, //triangle 1
1, 2, 3 //triangle 2
};
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glBindVertexArray(0);
}
It compiles and runs just fine, but it only opens a blank window. No graphics are shown on that window like it normally would. The output is supposed to look like a slightly rotated square rotated about its z-axis, but nothing appears at all. All help appreciated.
Some common things I check, when I get the infamous blank screen:
forgetting to call glUseProgram(shaderID) before you start passing uniforms (done)
pass the model matrix as an identity matrix.
double checking if the VBO/EBO are laid out in memory correctly (also, simplifying them during this step, ie. removing the color attribute, just pass position, and hard code the color in the fragment shader)
doing some error checking to see if there is a problem with the shader compilation using glGetShaderInfoLog and glGetProgramInfoLog.
The model matrix variable glm::mat4 currentTransform has to be initialized by the Identity matrix.
The OpenGL Mathematics (GLM) API documentation is based on OpenGL Shading Language (GLSL) and refers to The OpenGL Shading Language specification.
5.4.2 Vector and Matrix Constructors
[...] If there is a single scalar parameter to a matrix constructor, it is used to initialize all the components on the matrix's diagonal, with the remaining components initialized to 0.0.
An Identity matrix can be initialized by the single parameter 1.0:
glm::mat4 currentTransform;
glm::mat4 currentTransform(1.0f);

Modern OpenGL Black Screen with shader program and no errors

I have no errors but when I run the program all I have is a black screen and I am supposed to have two triangles:
#include <iostream> //includes C++ i/o stream
#include <GL/glew.h> //includes glew header
#include <GL/freeglut.h> //includes freeglut header
using namespace std; //Uses the standard namespace
#define WINDOW_TITLE "3-1 Assignment" //Macro for window title
//Vertex and Fragment shader source macro
#ifndef GLSL
#define GLSL(Version, Source) "#version " #Version "\n" #Source
#endif
//Windows Variables for height and width
int WindowWidth=800, WindowHeight=600;
/*User-defined function prototypes to: initialize the program, set the window size, redraw graphics on the window when resized and render graphics on the screen*/
void UInitalize(int, char*[]);
void UInitWindow(int, char*[]);
void UResizeWindow(int, int);
void URenderGraphics(void);
void UCreateShaders(void);
void UCreateVBO();
//Vertex and Shader program source code
const GLchar * VertexShader = GLSL(440,
//Receive Vertex coordinates from attribute
in layout(location=0) vec4 vertex_Position;
//for attribute 1 expect vec(4) floats passed into the vertex shader
in layout(location=1) vec4 colorFromVBO;
//Declare a vec4 variable that will reference the vertex colors passed into the vertex shader from the buffer
out vec4 colorFromVShader;
void main(){
//Sends vertex positions
gl_Position= vertex_Position;
//References vertex colors sent from the buffer
colorFromVShader= colorFromVBO;
}
);
const GLchar * FragmentShader = GLSL(440,
//vertex colors from the shader
in vec4 colorFromVShader;
//vec 4 variable that will reference vertex colors passed into the fragment shader from the vertex shader
out vec4 vertex_color;
void main(){
//gl_FragCOlor= vec4(0.0, 1.0, 0.0, 1.0);
vertex_Color= colorFromVShader;
}
);
//Main Function
int main(int argc, char* argv[])
{
UInitalize(argc, argv); //Initialize openGL program
glutMainLoop(); //Starts openGL loop in background
exit(EXIT_SUCCESS); //Ends the program
}
//Implements createVBO function
void UCreateVBO(void)
{
// Specifies Coordinates
GLfloat verts[]=
{
/*index 0*/
-1.0f, 1.0f, // top-center of the screen
1.0f, 0.0f, 0.0f, 1.0f, // Red vertex
/*index 1*/
-1.0f, 0.0f, // bottom-left of the screen
0.0f, 0.0f, 1.0f, 1.0f, // Blue vertex
/*index 2*/
-0.5f, 0.0f, // bottom-right of the screen
0.0f, 1.0f, 0.0f, 1.0f, // Green vertex
/*index 3*/
0.0f, 0.0f, // bottom-left of the screen
1.0f, 0.0f, 0.0f, 1.0f, // Red vertex
/*index 4*/
0.0f, -1.0f, // bottom-right of the screen
0.0f, 1.0f, 0.0f, 1.0f, // Green vertex
};
//Stores the size of the verts array
float numVertices= sizeof(verts);
//Variable for the vertex buffer object id
GLuint myBufferID;
//creates 1 buffer
glGenBuffers(1, &myBufferID);
//Activates the buffer
glBindBuffer(GL_ARRAY_BUFFER, myBufferID);
//Sends vertex data to the GPU
glBufferData(GL_ARRAY_BUFFER, numVertices, verts, GL_STATIC_DRAW);
//Creates vertex attribute pointer
//Number of coordinates per vertex
GLuint floatsPerVertex= 2;
//Specifies the initial position of the coordinates in the buffer
glEnableVertexAttribArray(0);
//Strides between vertex coordinates is 6 (x, y ,r, g, b, a)
//the number of floats before each vertex position
GLint vertexStride= sizeof(float)*6;
//Instructs GPU on how to handle the vertex buffer object
//parameters: atrribPointerPosition | coordinates per vertex|data type| deactivate normalizations | 0 strides | 0 offset
glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, vertexStride, 0);
//Sets an attribute pointer for the vertex colors
glEnableVertexAttribArray(1);
GLint colorStride= sizeof(float)*6;
//Parameters: attribPointerPosition 1 | floats per color is 4 | data type | deactivate normalization | 6 strides until the next color | 2 floats until the beginning of each color
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, colorStride, (char*)(sizeof(float)*2));
//Creates a buffer object for the indexes
GLushort indicies[]= {0,1,2,2,3,4};
float numIndicies= sizeof(indicies);
GLuint indexBufferID;
glGenBuffers(1, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndicies, indicies, GL_STATIC_DRAW);
}
//Implements UInitalize function
void UInitalize(int argc, char* argv[])
{
//glew status variable
GLenum GlewInitResult;
UInitWindow(argc, argv);
//Check glew status
GlewInitResult= glewInit();
if (GLEW_OK != GlewInitResult)
{
fprintf(stderr,"ERROR: %s\n", glewGetErrorString(GlewInitResult));
exit(EXIT_FAILURE);
}
//Display GPU OpenGl version
fprintf(stdout, "INFO: OpenGL Version: %s\n", glGetString(GL_VERSION));
//Makes the screen black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
//Implements the UInitWindow function
void UInitWindow(int argc, char* argv[])
{
//Initialize freeglut
glutInit(&argc, argv);
//Set window size
glutInitWindowSize(WindowWidth, WindowHeight);
//Memory buffer setup for display
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
//Creates a window with the macro placeholder title
glutCreateWindow(WINDOW_TITLE);
//Called when window is resized
glutReshapeFunc(UResizeWindow);
//Renders graphics on the screen
glutDisplayFunc(URenderGraphics);
}
//Implements the UResizeWindow function
void UResizeWindow(int Width, int Height)
{
glViewport(0, 0, Width, Height);
}
//Implements the URenderGraphics
void URenderGraphics(void)
{
//Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//Create the triangle
//Specifies the number of vertexes
GLuint totalVertices = 6;
//Draw the triangles
//glDrawArrays(GL_TRIANGLES, 0, totalVertices);
glDrawElements(GL_TRIANGLES, totalVertices, GL_UNSIGNED_SHORT, NULL);
//Flips the back buffer with the front buffer every frame, akin to GL Flush
glutSwapBuffers();
}
//Initialize the UCreateShaders function
void UCreateShaders(void)
{
//Create a shader program object
GLuint ProgramId = glCreateProgram();
//Create the vertex shader
GLuint vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
//Create the fragment shader
GLuint fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
//Get the source for the vertex shader
glShaderSource(vertexShaderId, 1, &VertexShader, NULL);
//Get the source for the fragment shader
glShaderSource(fragmentShaderId, 1, &FragmentShader, NULL);
//Complies the vertex shader
glCompileShader(vertexShaderId);
//Compiles the fragment shader
glCompileShader(fragmentShaderId);
//Attach shaders
glAttachShader(ProgramId, vertexShaderId);
glAttachShader(ProgramId, fragmentShaderId);
//Link the shader program
glLinkProgram(ProgramId);
//Utilizes the shader program
glUseProgram(ProgramId);
}
Couple issues:
UCreateShaders() and UCreateVBO() are never called.
Without a shader or geometry bound glDrawElements() can't do anything useful.
Fragment shader case mismatch causing a link failure: vertex_color != vertex_Color:
0:6(2): error: `vertex_Color' undeclared
0:6(2): error: value of type vec4 cannot be assigned to variable of type error
Make sure to check GL_COMPILE_STATUS & GL_LINK_STATUS & grab the appropriate info logs (glGetShaderInfoLog()/glGetProgramInfoLog()) when loading shaders to help identify issues like this in the future.
All together:
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <cstdio>
#include <cstdlib>
#include <iostream>
void CheckStatus( GLuint obj, bool isShader )
{
GLint status = GL_FALSE, log[ 1 << 11 ] = { 0 };
( isShader ? glGetShaderiv : glGetProgramiv )( obj, isShader ? GL_COMPILE_STATUS : GL_LINK_STATUS, &status );
if( status == GL_TRUE ) return;
( isShader ? glGetShaderInfoLog : glGetProgramInfoLog )( obj, sizeof( log ), NULL, (GLchar*)log );
std::cerr << (GLchar*)log << "\n";
std::exit( EXIT_FAILURE );
}
void AttachShader( GLuint program, GLenum type, const char* src )
{
GLuint shader = glCreateShader( type );
glShaderSource( shader, 1, &src, NULL );
glCompileShader( shader );
CheckStatus( shader, true );
glAttachShader( program, shader );
glDeleteShader( shader );
}
const char* const vert = R"GLSL(
#version 440
in layout(location=0) vec4 vertex_Position;
in layout(location=1) vec4 colorFromVBO;
out vec4 colorFromVShader;
void main()
{
gl_Position = vertex_Position;
colorFromVShader = colorFromVBO;
}
)GLSL";
const char* const frag = R"GLSL(
#version 440
in vec4 colorFromVShader;
out vec4 vertex_color;
void main()
{
vertex_color = colorFromVShader;
}
)GLSL";
void UCreateShaders()
{
GLuint prog = glCreateProgram();
AttachShader( prog, GL_VERTEX_SHADER, vert );
AttachShader( prog, GL_FRAGMENT_SHADER, frag );
glLinkProgram( prog );
CheckStatus( prog, false );
glUseProgram( prog );
}
void UCreateVBO()
{
// Specifies Coordinates
GLfloat verts[]=
{
/*index 0*/
-1.0f, 1.0f, // top-center of the screen
1.0f, 0.0f, 0.0f, 1.0f, // Red vertex
/*index 1*/
-1.0f, 0.0f, // bottom-left of the screen
0.0f, 0.0f, 1.0f, 1.0f, // Blue vertex
/*index 2*/
-0.5f, 0.0f, // bottom-right of the screen
0.0f, 1.0f, 0.0f, 1.0f, // Green vertex
/*index 3*/
0.0f, 0.0f, // bottom-left of the screen
1.0f, 0.0f, 0.0f, 1.0f, // Red vertex
/*index 4*/
0.0f, -1.0f, // bottom-right of the screen
0.0f, 1.0f, 0.0f, 1.0f, // Green vertex
};
//Variable for the vertex buffer object id
GLuint myBufferID;
glGenBuffers(1, &myBufferID);
glBindBuffer(GL_ARRAY_BUFFER, myBufferID);
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float)*6, 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float)*6, (char*)(sizeof(float)*2));
glEnableVertexAttribArray(1);
//Creates a buffer object for the indexes
GLushort indicies[]= {0,1,2,2,3,4};
GLuint indexBufferID;
glGenBuffers(1, &indexBufferID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indicies), indicies, GL_STATIC_DRAW);
}
void URenderGraphics(void)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLuint totalVertices = 6;
glDrawElements(GL_TRIANGLES, totalVertices, GL_UNSIGNED_SHORT, NULL);
glutSwapBuffers();
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitWindowSize(640, 480);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutCreateWindow("GLUT");
glutDisplayFunc(URenderGraphics);
GLenum GlewInitResult = glewInit();
if (GLEW_OK != GlewInitResult)
{
fprintf(stderr,"ERROR: %s\n", glewGetErrorString(GlewInitResult));
exit(EXIT_FAILURE);
}
fprintf(stdout, "INFO: OpenGL Version: %s\n", glGetString(GL_VERSION));
UCreateVBO();
UCreateShaders();
glutMainLoop();
return 0;
}

How to translate and rotate a Triangle in OpenGL over time?

I am trying to rotate and translate my single triangle over time. I have already written the main.cpp and I have written separate files for my Vertex and Fragment shader source code.
Here is the code in my main.cpp file:
void framebuffer_size_callback(GFLWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
// Shaders
const char *vertexShaderSource =
"#version 410\n"
"in vec3 vp;\n"
"void main()\n"
"{\n"
"gl_Position = vec4(aPos, 1.0);\n"
"}\0";
const char *fragmentShaderSource =
"#version 410\n"
"out vec4 FragColor;\n"
"in vec3 myColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(myColor, 1.0f);\n"
"}\n\0";
int main ()
{
// start GL context and O/S window using the GLFW helper library
if (!glfwInit ())
{
fprintf (stderr, "ERROR: could not start GLFW3\n");
return 1;
}
// uncomment these lines if on Apple OS X
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
GLFWwindow* window = glfwCreateWindow(640, 480, "LearnOpenGL", NULL, NULL);
if (!window)
{
fprintf(stderr, "ERROR: could not open window with GLFW3\n");
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
// start GLEW extension handler
glewExperimental = GL_TRUE;
glewInit();
// get version info
const GLubyte* renderer = glGetString(GL_RENDERER);
const GLubyte* version = glGetString(GL_VERSION);
printf("Renderer: %s\n", renderer);
printf("OpenGL version supported %s\n", version);
glEnable(GL_DEPTH_TEST); // enable depth-testing
glDepthFunc(GL_LESS);
// Draw a single triangle
float points[] = {
// positions // colors
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f 0.0f, 1.0f
};
GLuint VBO = 0;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
// Generate a VAO.
GLuint VAO = 0;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
// Compile a Vertex Shader
int vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
glCompileShader(vertexShader);
// Compile a fragment shader.
int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
glCompileShader(fragmentShader);
// Compile shaders into a executable shader program.
int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, fragmentShader);
glAttachShader(shaderProgram, vertexShader);
glLinkProgram(shaderProgram);
// Create another float array to make my triangle fan.
float points_5_triangles[] = {
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.5f, 0.0f, 1.0f, 2.0f, 0.5f,
// Another triangle made from point 1, 3, and 4
-0.5f,
}
// Generate another VBO for my Triangle Fan
GLuint VBO_5_triangles = 0;
glGenBuffers(1, &VBO_5_triangles);
glBindBuffer(GL_ARRAY_BUFFER, VBO_5_triangles);
glBufferData(GL_ARRAY_BUFFER, sizeof(points_5_triangles), points_5_triangles, GL_STATIC_DRAW);
// Generate another VAO for my Triangle Fan
GLuint VAO_5_triangles = 0;
glGenVertexArrays(1, &VAO_5_triangles);
glBindVertexArray(VAO_5_triangles);
glBindBuffer(GL_ARRAY_BUFFER, VBO_5_triangles);
glBufferData(GL_ARRAY_BUFFER, sizeof(points_5_triangles), points_5_triangles, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
// Drawing the triangles aka render loop
while (!glfwWindowShouldClose(window))
{
processInput(window);
// wipe the drawing surface clear
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Draw Triangle
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
// Draw Triangle Fan
glBindVertexArray(VAO_5_triangles);
glDrawArrays(GL_TRIANGLE_FAN, 0, 7);
// swap buffers and poll IO events
glfwPollEvents();
glfwSwapBuffers(window);
}
// close GL context and any other GLFW resources
glfwTerminate();
return 0;
}
The tutorial I am following does go over transformations but in the example it uses, the triangles have textures as well as shaders. For my purposes, I want to do this without textures added to my code.
Can someone walk me through how to add 2 transformations: translate and rotation to my "single triangle" as shown in this code?
Your triangle having a texture or not has nothing to do with transformation.
You rotate your triangle simply by calculating a transformation matrix, passing it to your vertex shader and multiply it with your coordinates.
Your Vertex Shader should look look something like this:
const char *vertexShaderSource =
"#version 410\n"
"layout (location = 0) in vec3 vp;\n"
"uniform mat4 transform;"
"void main()\n"
"{\n"
" gl_Position = transform * vec4(vp, 1.0);\n"
"}\0";
I recommend you to use the glm library for that. You calculate your matrix and pass it to your shader like this:
auto transformMatrix = glm::rotate( /* your rotation calculation */ );
auto transLoc = glGetUniformLocation(shaderProgram, "transform");
glUniformMatrix4fv(transLoc , 1, GL_FALSE, glm::value_ptr(transformMatrix));

glMapBufferRange gives me an access violation

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