OpenGL Height Map from text segmentation fault - c++

I am trying to create a heightmap from 25 float values like so:
#define HEIGHT_VERTS 5
#define VALS_PER_VERT_HEIGHT 5
float heightmapVerts[ HEIGHT_VERTS*VALS_PER_VERT_HEIGHT ] = {
//5
-0.9, -0.6, -0.4, -0.6, -0.9,
-0.2, 0.1, 0.3, 0.1, -0.3,
0, 0.4, 0.8, 0.4, 0,
-0.2, 0.1, 0.3, 0.1, -0.3,
0.5, -0.6, -0.4, -0.6, -0.9,
};
I am getting a segmentation fault when calling:
glDrawArrays(GL_TRIANGLES, 0, HEIGHT_VERTS);
I have been suggested that it's because the size argument of glVertexAttribPointer() must be 1, 2, 3, or 4. I pass 5 with:
glVertexAttribPointer(vertLocHeight, VALS_PER_VERT_HEIGHT, GL_FLOAT, GL_FALSE, 0, 0);
but I get another error saying that I have too many vertices if these values are smaller (eg: #define VALS_PER_VERT_HEIGHT 3)
error: too many initializers for ‘float [15]’
I have attached the rest of my code for some context, I am very very new to OpenGL so I apologize if the code is messy.
#include <stdio.h>
// GLEW loads OpenGL extensions. Required for all OpenGL programs.
#include <GL/glew.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
// Utility code to load and compile GLSL shader programs
#include "shader.hpp"
#include <iostream>
#include <fstream>
#include <vector>
#include "glm/glm.hpp"
#define WINDOW_WIDTH 400
#define WINDOW_HEIGHT 400
#define VALS_PER_VERT_HEIGHT 5//5
#define VALS_PER_COLOUR_HEIGHT 4
#define HEIGHT_VERTS 5 //height map vertices per line
using namespace std;
// Handle to our VAO generated in setShaderData method
//heightmap
unsigned int vertexVaoHandleHeight;
// Handle to our shader program
unsigned int programID;
/**
* Sets the shader uniforms and vertex data
* This happens ONCE only, before any frames are rendered
* #param id, Shader program object to use
* #returns 0 for success, error otherwise
*/
int setShaderData(const unsigned int &id)
{
float heightmapVerts[ HEIGHT_VERTS*VALS_PER_VERT_HEIGHT ] = {
//5
-0.9, -0.6, -0.4, -0.6, -0.9,
-0.2, 0.1, 0.3, 0.1, -0.3,
0, 0.4, 0.8, 0.4, 0,
-0.2, 0.1, 0.3, 0.1, -0.3,
0.5, -0.6, -0.4, -0.6, -0.9,
};
// Colours for each vertex; red, green, blue and alpha
// This data is indexed the same order as the vertex data, but reads 4 values
// Alpha will not be used directly in this example program
float heightColours[ HEIGHT_VERTS*VALS_PER_COLOUR_HEIGHT ] = {
0.8f, 0.7f, 0.5f, 1.0f,
0.3f, 0.7f, 0.1f, 1.0f,
0.8f, 0.2f, 0.5f, 1.0f,
};
// heightmap stuff ##################################################
// Generate storage on the GPU for our triangle and make it current.
// A VAO is a set of data buffers on the GPU
glGenVertexArrays(1, &vertexVaoHandleHeight);
glBindVertexArray(vertexVaoHandleHeight);
// Generate new buffers in our VAO
// A single data buffer store for generic, per-vertex attributes
unsigned int bufferHeight[2];
glGenBuffers(2, bufferHeight);
// Allocate GPU memory for our vertices and copy them over
glBindBuffer(GL_ARRAY_BUFFER, bufferHeight[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*HEIGHT_VERTS*VALS_PER_VERT_HEIGHT, heightmapVerts, GL_STATIC_DRAW);
// Do the same for our vertex colours
glBindBuffer(GL_ARRAY_BUFFER, bufferHeight[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*HEIGHT_VERTS*VALS_PER_COLOUR_HEIGHT, heightColours, GL_STATIC_DRAW);
// Now we tell OpenGL how to interpret the data we just gave it
// Tell OpenGL what shader variable it corresponds to
// Tell OpenGL how it's formatted (floating point, 3 values per vertex)
int vertLocHeight = glGetAttribLocation(id, "a_vertex");
glBindBuffer(GL_ARRAY_BUFFER, bufferHeight[0]);
glEnableVertexAttribArray(vertLocHeight);
glVertexAttribPointer(vertLocHeight, VALS_PER_VERT_HEIGHT, GL_FLOAT, GL_FALSE, 0, 0);
// Do the same for the vertex colours
int colourLocHeight = glGetAttribLocation(id, "a_colour");
glBindBuffer(GL_ARRAY_BUFFER, bufferHeight[1]);
glEnableVertexAttribArray(colourLocHeight);
glVertexAttribPointer(colourLocHeight, VALS_PER_COLOUR_HEIGHT, GL_FLOAT, GL_FALSE, 0, 0);
// heightmap stuff ##################################################
// An argument of zero un-binds all VAO's and stops us
// from accidentally changing the VAO state
glBindVertexArray(0);
// The same is true for buffers, so we un-bind it too
glBindBuffer(GL_ARRAY_BUFFER, 0);
return 0; // return success
}
/**
* Renders a frame of the state and shaders we have set up to the window
* Executed each time a frame is to be drawn.
*/
void render()
{
// Clear the previous pixels we have drawn to the colour buffer (display buffer)
// Called each frame so we don't draw over the top of everything previous
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
// HEIGHT MAP STUFF ###################################
// Make the VAO with our vertex data buffer current
glBindVertexArray(vertexVaoHandleHeight);
// Send command to GPU to draw the data in the current VAO as triangles
//CRASHES HERE
glDrawArrays(GL_TRIANGLES, 0, HEIGHT_VERTS);
glBindVertexArray(0); // Un-bind the VAO
// HEIGHT MAP STUFF ###################################
glutSwapBuffers(); // Swap the back buffer with the front buffer, showing what has been rendered
glFlush(); // Guarantees previous commands have been completed before continuing
}

You are messing things up.
1) With glVertexAttribPointer(), you setup vertex attributes - those are almost always vectors of some kind. For vertex position, if you need to draw scene in 2D, pass size = 2 (because each vertex has x and y coordinates), for 3D - pass 3 (x, y, z).
2) I think your interpretation of heightmap is also quite incorrect. You filled array only with height values (in 3D space, those are Y coordinates). But where are X and Z? You need to render vertices, so you need to pass all x, y and z coords, so OpenGL can know where each point should be rendered.
Your program crashes, because you send not enough data and OpenGL tries to read from memory, that doesn't belong to you.
I assume, that you want a heightmap, which is a 5x5 grid? Init data this way:
float heightmapVerts[25] =
{
//leave this as it is right now
};
vec3 vertices[5][5];
for(int z_num = 0; z_num < 5; ++z_num)
{
for(int x_num = 0; x_num < 5; ++x_num)
{
vertices[z_num][x_num].x = x_num * 0.5f;
vertices[z_num][x_num].z = z_num * 0.5f;
vertices[z_num][x_num].y = heightmapVerts[z_num * 5 + x_num];
}
}
Then you can call:
glVertexAttribPointer(vertLocHeight, 3, GL_FLOAT, GL_FALSE, 0, 0);
Update:
vec3 stands for 3-dimensional vector. I wrote it as pseudocode to
illustrate conception, but for the sake of simplicity, you may want to
use this great library: OpenGL Mathematics.
Update 2:
One more thing: color data is also set improperly. You probably want
color to be an RGB value, so every vertex needs additional 3 floats to
represent its color. Also, position and color should be place in
single VBO, there is no need for separating them.
I am not sure, if you got all basics required to do any simple
drawings. You may want to read these articles:
OpenGL Wiki
This nice tutorial
Lighthouse 3D

Related

OpenGL Index Buffer Object element order incorrectly drawn

Notice how my program draws a single triangle, but instead what I am trying to express in code is to draw a square. My tri_indicies index buffer object I believe correctly orders these elements such that a square should be drawn, but when executing the program the draw order I have defined in the tri_indicies is not reflected in the window. Not sure if the error is rooted in tri_indicies, despite my changes to the element order not effecting my rendered output I want to believe it is here, but is it most likely somewhere else.
My program uses abstractions to notably the VertexBuffer, VertexArray, and IndexBuffer all detailed below.
const int buffer_object_size = 8;
const int index_buffer_object_size = 6;
float tri_verticies[buffer_object_size] = {
-0.7f, -0.7f, // 0
0.7f, -0.7f, // 1
0.7f, 0.7f, // 2
-0.7f, 0.7f // 3
};
unsigned int tri_indicies[index_buffer_object_size] = {
0, 1, 2,
2, 3, 0
};
VertexArray vertexArray;
VertexBuffer vertexBuffer(tri_verticies, buffer_object_size * sizeof(float)); // no call vertexBuffer.bind() constructor does it
VertexBufferLayout vertexBufferLayout;
vertexBufferLayout.push<float>(3);
vertexArray.add_buffer(vertexBuffer, vertexBufferLayout);
IndexBuffer indexBuffer(tri_indicies, index_buffer_object_size);
ShaderManager shaderManager;
ShaderSource shaderSource = shaderManager.parse_shader("BasicUniform.shader"); // ensure debug working dir is relative to $(ProjectDir)
unsigned int shader = shaderManager.create_shader(shaderSource.vertex_source, shaderSource.fragment_source);
MyGLCall(glUseProgram(shader));
Later in main I have a loop that is supposed to draw my square to the screen and fade the blue color value between 1.0f and 0.0f.
while (!glfwWindowShouldClose(window))
{
MyGLCall(glClear(GL_COLOR_BUFFER_BIT));
vertexArray.bind();
indexBuffer.bind();
MyGLCall(glDrawElements(GL_TRIANGLES, index_buffer_object_size, GL_UNSIGNED_INT, nullptr)); // nullptr since we bind buffers using glGenBuffers
if (blue > 1.0f) {
increment_color = -0.05f;
}
else if (blue < 0.0f) {
increment_color = 0.05f;
}
blue += increment_color;
glfwSwapBuffers(window);
glfwPollEvents();
}
The array tri_verticies consists of vertex coordinates with 2 components (x, y). So the tuple size for the specification of the array of generic vertex attribute data has to be 2 rather than 3:
vertexBufferLayout.push<float>(3);
vertexBufferLayout.push<float>(2);
What you actually do, is to specify an array with the following coordinates:
-0.7, -0.7, 0.7 // 0
-0.7, 0.7, 0.7 // 1
???, ???, ??? // 2
???, ???, ??? // 3
In general out-of-bound access to buffer objects has undefined results.
See OpenGL 4.6 API Core Profile Specification - 6.4 Effects of Accessing Outside Buffer Bounds, page 79

How to render some vertices in a buffer as points and the rest using lines in qopenglwidget?

I have a set of vertices and normals stored in a buffer. I want to display most of the vertices as points but i want draw lines for the remaining few vertices. These are all stored inside one vector with the points part in the front and i know the location of the buffer until they are to be displayed using points. I also know the count of elements for each drawing task. I am using only one vao and one buffer object for this task.
I initialize the GLWidget with the following code:
void GLWidget::initializeGL()
{
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::cleanup);
initializeOpenGLFunctions();
glClearColor(0, 0, 0, m_transparent ? 0 : 1);
m_program = new QOpenGLShaderProgram;
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource);
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource);
m_program->bindAttributeLocation("vertex", 0);
m_program->bindAttributeLocation("normal", 1);
m_program->link();
m_program->bind();
m_projMatrixLoc = m_program->uniformLocation("projMatrix");
m_mvMatrixLoc = m_program->uniformLocation("mvMatrix");
m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
m_lightPosLoc = m_program->uniformLocation("lightPos");
m_vao.create();
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
m_obj.create();
setupBuffer();
setupVertexAttribs();
m_camera.setToIdentity();
QVector3D camPos = QVector3D(0.0, 0.0, 15.0);
m_camera.translate(-camPos);
QVector3D camTarget = QVector3D(0.0, 0.0, 0.0);
QVector3D camDirection = QVector3D(camPos - camTarget).normalized();
QVector3D worldUp = QVector3D(0.0, 1.0, 0.0);
QVector3D camRight = QVector3D::crossProduct(worldUp, camDirection).normalized();
QVector3D camUp = QVector3D::crossProduct(camDirection, camRight);
m_camera.lookAt(camPos, camTarget, camUp);
// Light position is fixed.
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 200));
m_program->release();
}
Where the functions setupBuffer() setupVertexAtrribs() do the same tasks as their names imply. The vertices are layed out in the buffer with xyz positions of the vertex followed by the xyz of its associated normal. They are implemented as follows
void GLWidget::setupBuffer()
{
m_obj.bind();
m_obj.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
}
void GLWidget::setupVertexAttribs()
{
m_obj.bind();
QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();
f->glEnableVertexAttribArray(0);
f->glEnableVertexAttribArray(1);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(0));
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat)));
m_obj.release();
}
Now, the QVector vertices is the buffer that is being passed to opengl. The last few entries in this vector are the vertices that need to be drawn using GL_LINES.
My paintGL() function looks something like this:
void GLWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
glEnable(GL_POINT_SIZE);
glEnable(GL_LINE_WIDTH);
glPointSize(2);
glLineWidth(10);
m_world.setToIdentity();
m_world.rotate(180.0f - (m_xRot / 16.0f), 1, 0, 0);
m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
m_world.scale(m_dispScale);
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
m_program->bind();
m_program->setUniformValue(m_projMatrixLoc, m_proj);
m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
QMatrix3x3 normalMatrix = m_world.normalMatrix();
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);
glDrawArrays(GL_POINTS, 0, vertices.size() - camVertices.size());
// Draw camera frustums
glDrawArrays(GL_LINES, vertices.size() - camVertices.size(), camVertices.size());
//glDrawElements(GL_POINTS, vecIndices.size(), GL_UNSIGNED_INT, 0);
m_program->release();
}
QVector camVertices is another vector that contains points that need to be drawn using lines. The data in camVertices is appended to the end of the vector 'Vertices' before rendering. As seen in the above code, I call glDrawArrays function twice - first, starting from 0 index of the buffer, second, starting from where the previous call ended to display the remaining of the points.
The problem is that the points are being displayed fine. However the second call only displays the points but does not draw any lines.
Here's a link to a screenshot of the displayed output - https://drive.google.com/open?id=1i7CjO1qkBALw78KKYGvBteydhfAWh3wh
The picture shows an example of the displayed out where the bright green points seen on the top outlying from the rest (box of many points) are the ones that are to be drawn with lines. However, I only see points but not any lines.
i did a simple test and i'm able to draw points and lines using the following code:
glDrawArrays(GL_POINTS, 0, verticesCount() - 10);
glDrawArrays(GL_LINES, 10, 10);
Which is not very different from yours except for the variables. I'm also using 1 VAO. So it's definitely possible to draw lines after points as we would expect.
Could you try the same (using an integer instead of your variables)
Can you show the debug information on your vertices?
Can you upload a minimal compilable example?

change Vector<float> to heightmap coordinates OpenGL

I have a file which has terrain coordinates in it like this:
//The first value is how many rows and columns the map has (assuming its a square)
5
-0.9 -0.6 -0.4 -0.6 -0.9
-0.2 0.1 0.3 0.1 -0.3
0 0.4 0.8 0.4 0
-0.2 0.1 0.3 0.1 -0.3
0.5 -0.6 -0.4 -0.6 -0.9
I have put these values into a vector(float) and now need to format it so that I can render the vertices and make a terrain. How do I go about doing this?
std::fstream myfile("heights.csv", std::ios_base::in);
std::vector<float> numbers;
float a;
while (myfile >> a){/*printf("%f ", a);*/
numbers.push_back(a);
}
Just for reference, here is the rest of my code, it's basically code for rending 2 triangles on the screen, which I plan to remove later (just trying to learn)
/**
* A typical program flow and methods for rendering simple polygons
* using freeglut and openGL + GLSL
*/
#include <stdio.h>
// GLEW loads OpenGL extensions. Required for all OpenGL programs.
#include <GL/glew.h>
#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif
// Utility code to load and compile GLSL shader programs
#include "shader.hpp"
#include <iostream>
#include <fstream>
#include <vector>
#define WINDOW_WIDTH 400
#define WINDOW_HEIGHT 400
#define VALS_PER_VERT 3
#define VALS_PER_COLOUR 4
#define NUM_VERTS 3 // Total number of vertices to load/render
using namespace std;
// Handle to our VAO generated in setShaderData method
unsigned int vertexVaoHandle;
unsigned int vertexVaoHandle2;
// Handle to our shader program
unsigned int programID;
/**
* Sets the shader uniforms and vertex data
* This happens ONCE only, before any frames are rendered
* #param id, Shader program object to use
* #returns 0 for success, error otherwise
*/
int setShaderData(const unsigned int &id)
{
/*
* What we want to draw
* Each set of 3 vertices (9 floats) defines one triangle
* You can define more triangles to draw here
*/
float vertices[ NUM_VERTS*VALS_PER_VERT ] = {
-0.5f, -0.5f, -0.0f, // Bottom left
0.5f, -0.5f, -0.0f, // Bottom right
0.0f, 0.5f, -0.0f // Top
};
float vertices2[ NUM_VERTS*VALS_PER_VERT ] = {
-0.9f, -0.9f, -0.0f, // Bottom left
0.9f, -0.9f, -0.0f, // Bottom right
0.9f, 0.5f, -0.0f // Top
};
float heightmap[ NUM_VERTS*VALS_PER_VERT ] = {
-0.9f, -0.9f, -0.0f, // Bottom left
0.9f, -0.9f, -0.0f, // Bottom right
0.9f, 0.5f, -0.0f
};
// Colours for each vertex; red, green, blue and alpha
// This data is indexed the same order as the vertex data, but reads 4 values
// Alpha will not be used directly in this example program
float colours[ NUM_VERTS*VALS_PER_COLOUR ] = {
0.8f, 0.7f, 0.5f, 1.0f,
0.3f, 0.7f, 0.1f, 1.0f,
0.8f, 0.2f, 0.5f, 1.0f,
};
float colours2[ NUM_VERTS*VALS_PER_COLOUR ] = {
0.8f, 0.7f, 0.5f, 1.0f,
0.3f, 0.7f, 0.1f, 1.0f,
0.8f, 0.2f, 0.5f, 1.0f,
};
// Generate storage on the GPU for our triangle and make it current.
// A VAO is a set of data buffers on the GPU
glGenVertexArrays(1, &vertexVaoHandle);
glBindVertexArray(vertexVaoHandle);
// Generate new buffers in our VAO
// A single data buffer store for generic, per-vertex attributes
unsigned int buffer[2];
glGenBuffers(2, buffer);
// Allocate GPU memory for our vertices and copy them over
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*NUM_VERTS*VALS_PER_VERT, vertices, GL_STATIC_DRAW);
// Do the same for our vertex colours
glBindBuffer(GL_ARRAY_BUFFER, buffer[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*NUM_VERTS*VALS_PER_COLOUR, colours, GL_STATIC_DRAW);
// Now we tell OpenGL how to interpret the data we just gave it
// Tell OpenGL what shader variable it corresponds to
// Tell OpenGL how it's formatted (floating point, 3 values per vertex)
int vertLoc = glGetAttribLocation(id, "a_vertex");
glBindBuffer(GL_ARRAY_BUFFER, buffer[0]);
glEnableVertexAttribArray(vertLoc);
glVertexAttribPointer(vertLoc, VALS_PER_VERT, GL_FLOAT, GL_FALSE, 0, 0);
// Do the same for the vertex colours
int colourLoc = glGetAttribLocation(id, "a_colour");
glBindBuffer(GL_ARRAY_BUFFER, buffer[1]);
glEnableVertexAttribArray(colourLoc);
glVertexAttribPointer(colourLoc, VALS_PER_COLOUR, GL_FLOAT, GL_FALSE, 0, 0);
// An argument of zero un-binds all VAO's and stops us
// from accidentally changing the VAO state
glBindVertexArray(0);
// The same is true for buffers, so we un-bind it too
glBindBuffer(GL_ARRAY_BUFFER, 0);
// SECOND TRI
// Generate storage on the GPU for our triangle and make it current.
// A VAO is a set of data buffers on the GPU
glGenVertexArrays(1, &vertexVaoHandle2);
glBindVertexArray(vertexVaoHandle2);
// Generate new buffers in our VAO
// A single data buffer store for generic, per-vertex attributes
unsigned int buffer2[2];
glGenBuffers(2, buffer2);
// Allocate GPU memory for our vertices and copy them over
glBindBuffer(GL_ARRAY_BUFFER, buffer2[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*NUM_VERTS*VALS_PER_VERT, vertices2, GL_STATIC_DRAW);
// Do the same for our vertex colours
glBindBuffer(GL_ARRAY_BUFFER, buffer2[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*NUM_VERTS*VALS_PER_COLOUR, colours2, GL_STATIC_DRAW);
// Now we tell OpenGL how to interpret the data we just gave it
// Tell OpenGL what shader variable it corresponds to
// Tell OpenGL how it's formatted (floating point, 3 values per vertex)
int vertLoc2 = glGetAttribLocation(id, "a_vertex");
glBindBuffer(GL_ARRAY_BUFFER, buffer2[0]);
glEnableVertexAttribArray(vertLoc2);
glVertexAttribPointer(vertLoc2, VALS_PER_VERT, GL_FLOAT, GL_FALSE, 0, 0);
// Do the same for the vertex colours
int colourLoc2 = glGetAttribLocation(id, "a_colour");
glBindBuffer(GL_ARRAY_BUFFER, buffer2[1]);
glEnableVertexAttribArray(colourLoc2);
glVertexAttribPointer(colourLoc2, VALS_PER_COLOUR, GL_FLOAT, GL_FALSE, 0, 0);
// An argument of zero un-binds all VAO's and stops us
// from accidentally changing the VAO state
glBindVertexArray(0);
// The same is true for buffers, so we un-bind it too
glBindBuffer(GL_ARRAY_BUFFER, 0);
return 0; // return success
}
/**
* Renders a frame of the state and shaders we have set up to the window
* Executed each time a frame is to be drawn.
*/
void render()
{
// Clear the previous pixels we have drawn to the colour buffer (display buffer)
// Called each frame so we don't draw over the top of everything previous
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(programID);
// Make the VAO with our vertex data buffer current
glBindVertexArray(vertexVaoHandle);
// Send command to GPU to draw the data in the current VAO as triangles
glDrawArrays(GL_TRIANGLES, 0, NUM_VERTS);
glBindVertexArray(0); // Un-bind the VAO
// SECOND TRIANGLE
// Make the VAO with our vertex data buffer current
glBindVertexArray(vertexVaoHandle2);
// Send command to GPU to draw the data in the current VAO as triangles
glDrawArrays(GL_TRIANGLES, 0, NUM_VERTS);
glBindVertexArray(0); // Un-bind the VAO
// XXXXXXXX
glutSwapBuffers(); // Swap the back buffer with the front buffer, showing what has been rendered
glFlush(); // Guarantees previous commands have been completed before continuing
}
/**
* Program entry. Sets up OpenGL state, GLSL Shaders and GLUT window and function call backs
* Takes no arguments
*/
int main(int argc, char **argv) {
//READ IN FILE//
std::fstream myfile("heights.csv", std::ios_base::in);
std::vector<float> numbers;
float a;
while (myfile >> a){/*printf("%f ", a);*/
numbers.push_back(a);
}
for (int i=0; i<numbers.size();i++){cout << numbers[i] << endl;}
getchar();
//READ IN FILE//
// Set up GLUT window
glutInit(&argc, argv); // Starts GLUT systems, passing in command line args
glutInitWindowPosition(100, 0); // Positions the window on the screen relative to top left
glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); // Size in pixels
// Display mode takes bit flags defining properties you want the window to have;
// GLUT_RGBA : Set the pixel format to have Red Green Blue and Alpha colour channels
// GLUT_DOUBLE : Each frame is drawn to a hidden back buffer hiding the image construction
// GLUT_DEPTH : A depth buffer is kept so that polygons can be drawn in-front/behind others (not used in this application)
#ifdef __APPLE__
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_3_2_CORE_PROFILE);
#else
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH );
#endif
glutCreateWindow("Hello World!"); // Makes the actual window and displays
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Sets the (background) colour for each time the frame-buffer (colour buffer) is cleared
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
// Set up the shaders we are to use. 0 indicates error.
programID = LoadShaders("minimal.vert", "minimal.frag");
if (programID == 0)
return 1;
// Set this shader program in use
// This is an OpenGL state modification and persists unless changed
glUseProgram(programID);
// Set the vertex data for the program
if (setShaderData(programID) != 0)
return 1;
// Render call to a function we defined,
// that is called each time GLUT thinks we need to update
// the window contents, this method has our drawing logic
glutDisplayFunc(render);
// Start an infinite loop where GLUT calls methods (like render)
// set with glut*Func when needed.
// Runs until something kills the window
glutMainLoop();
return 0;
}
Actually , i could not understand what do you want to do. But maybe this helps.
Read first line and get row,col size. Allocate multidimensional array. Go ahead to read next lines. Put the values inside array that are extracted from lines.
std::ifstream file( "heights.csv" );
std::string line;
getline(file , line);
int ColRowSize;
line >> ColRowSize;
/// allocate map
float** data = malloc(ColRowSize * sizeof(float *));
for(i = 0; i < ColRowSize; i++)
{
array[i] = malloc(ColRowSize * sizeof(float));
}
/// read from file
for(i = 0; i < ColRowSize; i++)
{
getline(file , line);
for(j = 0; j < ColRowSize; j++)
line >> data[i][j];
}

OpenGL vertex array not rendering

I'm trying to draw some basic triangles using opengl, but it's not rendering on screen. These are the relevant functions:
glewInit();
glClearColor(0.0, 0.0, 0.0, 1.0);
glFrontFace(GL_CW);
glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
Vertex vertices[] = {Vertex(Vector3f(0.0, 1.0, 0.0)),
Vertex(Vector3f(-1.0, -1.0, 0.0)),
Vertex(Vector3f(1.0, -1.0, 0.0))};
mesh.addVertices(vertices, 3);
Pastebin links to Vertex.hpp and Vector3f.hpp:
Vertex.hpp
Vector3f.hpp
/*
* Mesh.cpp:
*/
Mesh::Mesh()
{
glGenBuffers(1, &m_vbo); // unsigned int Mesh::m_vbo
}
void Mesh::addVertices(Vertex vertices[4], int indexSize)
{
m_size = indexSize * 3;
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glBufferData(GL_ARRAY_BUFFER, m_size, vertices, GL_STATIC_DRAW);
}
void Mesh::draw()
{
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(Vertex), 0);
glDrawArrays(GL_TRIANGLES, 0, m_size);
glDisableVertexAttribArray(0);
}
It's just black if I call glClear otherwise just the random noise of a default window. I can make it draw a triangle by using the most primitive method:
glBegin(GL_TRIANGLES);
glColor3f(0.4, 0.0, 0.0);
glVertex2d(0.0, 0.5);
glVertex2d(-0.5, -0.5);
glVertex2d(0.5, -0.5);
glEnd();
That works and displays what it should do correctly, so I guess that at least says my application is not 100% busted. The tutorial I'm following is in Java, and I'm translating it to C++ SFML as I go along, so I guess it's possible that something got lost in translation so to speak, unless I'm just missing something really basic (more likely.)
How do we fix this so it uses the Vertex list to draw the triangle like it's supposed to?
So many mistakes. There are truly a lot of examples, in any language, so why?
const float pi = 3.141592653589793; is member field of Vector3f. Do you realise this is non-static member and it is included in each and every Vector3f you use, so your vectors actually have four elements - x, y, z, and pi? Did you informed GL about it, so it could skip this garbage data? I don't think so.
You using glVertexAttribPointer, but don't have active shader. There is no guarantee that position is in slot 0. Either use glVertexPointer, or use shader with position attribute bound to 0.
void Mesh::addVertices(Vertex vertices[4], int indexSize) what [4] supposed to mean here? While it is not an error, it is at least misguiding.
glBufferData(GL_ARRAY_BUFFER, m_size, vertices, GL_STATIC_DRAW); m_size is 3*3 in your example, while documentation says it should be array size in bytes - which is sizeof(Vertex) * indexSize.
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 4 * sizeof(Vertex), 0); why stride parameter is 4*sizeof(Vertex)? Either set it to 0 or write correct stride - which is sizeof(Vertex).
glDrawArrays(GL_TRIANGLES, 0, m_size); m_size is already [incorrectly] set as "vertex buffer size", while DrawArrays expects number of vertices to draw - which is m_size / sizeof(Vertex) (given m_size is calculated correctly).

glUseProgram affecting more than just the VAO

I have successfully created a VAO which produces a triangle which can then be rotated with the mouse (with help from shaders).
My problem comes when I try to draw something else using the standard 'glBegin()' and 'glEnd()' functions. It draws successfully, but now, when I try to rotate the triangle the new drawing also rotates.
I know the problem is somehow fixed using the glUseProgram() function, but I'm not entirely sure why or where it should be added.
Here is my code (I've added it all but the main area of focus should be the display() and init() functions:
#include <GL/glew/glew.h>
#include <GL/freeglut.h>
#include <CoreStructures\CoreStructures.h>
#include <iostream>
#include "texture_loader.h"
#include "shader_setup.h"
using namespace std;
using namespace CoreStructures;
float theta = 0.0f;
bool mDown = false;
int mouse_x, mouse_y;
GLuint myShaderProgram;
GLuint locT; // location of "T" uniform variable in myShaderProgram
GLuint locR; // location of "R" uniform variable in myShaderProgram
GLuint sunPosVBO, sunColourVBO, sunIndicesVBO, sunVAO;
// Packed vertex arrays for the star object
// 1) Position Array - Store vertices as (x,y) pairs
static GLfloat sunVertices [] = {
-0.1f, 0.7f,
0.1f, 0.7f,
0.0f, 0.55f
};
// 2) Colour Array - Store RGB values as unsigned bytes
static GLubyte sunColors [] = {
255, 0, 0, 255,
255, 255, 0, 255,
0, 255, 0, 255
};
// 4) Index Array - Store indices to star vertices - this determines the order the vertices are to be processed
static GLubyte sunVertexIndices [] = {0, 1, 2};
void setupSunVAO(void) {
glGenVertexArrays(1, &sunVAO);
glBindVertexArray(sunVAO);
// copy star vertex position data to VBO
glGenBuffers(1, &sunPosVBO);
glBindBuffer(GL_ARRAY_BUFFER, sunPosVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(sunVertices), sunVertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)0);
// copy star vertex colour data to VBO
glGenBuffers(1, &sunColourVBO);
glBindBuffer(GL_ARRAY_BUFFER, sunColourVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(sunColors), sunColors, GL_STATIC_DRAW);
glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, (const GLvoid*)0);
// enable position, colour buffer inputs
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
// setup star vertex index array
glGenBuffers(1, &sunIndicesVBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sunIndicesVBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(sunVertexIndices), sunVertexIndices, GL_STATIC_DRAW);
glBindVertexArray(0);
}
void report_version(void) {
int majorVersion, minorVersion;
glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
cout << "OpenGL version " << majorVersion << "." << minorVersion << "\n\n";
}
void init(void) {
// initialise glew library
GLenum err = glewInit();
// ensure glew was initialised successfully before proceeding
if (err==GLEW_OK)
cout << "GLEW initialised okay\n";
else
cout << "GLEW could not be initialised\n";
report_version();
glClearColor(0.0, 0.0, 0.0, 0.0);
//
// setup "sun" VBO and VAO object
//
setupSunVAO();
//
// load shader program
//
myShaderProgram = setupShaders(string("Resources\\Shaders\\basic_vertex_shader.txt"), string("Resources\\Shaders\\basic_fragment_shader.txt"));
// get the index / location of the uniform variables "T" and "R" in shader program "myShaderProgram"
locT = glGetUniformLocation(myShaderProgram, "T");
locR = glGetUniformLocation(myShaderProgram, "R");
// "plug-in" shader into GPU pipeline
glUseProgram(myShaderProgram); // we're in the driving seat!!!!! Our shaders now intercept and process our vertices as part of the GPU rendering pipeline (as shown in the lecture notes)
}
// Example rendering functions - draw objects in local, or modelling coordinates
void drawSun(void) {
glBindVertexArray(sunVAO);
glDrawElements(GL_TRIANGLE_STRIP, 3, GL_UNSIGNED_BYTE, (GLvoid*)0);
}
void drawShape()
{
glColor3f(0.0f, 0.6f, 0.2f);
glBegin(GL_POLYGON);
glVertex2f(-1.0f, -1.0f); // Left
glVertex2f(-1.0f, -0.1f);
glVertex2f(-0.9f, -0.05f);
glVertex2f(-0.55f, -0.045f);
glVertex2f(-0.49f, -0.06f);
glVertex2f(-0.4f, -0.055f);
glVertex2f(-0.2f, -0.052f);
glVertex2f(0.0f, -0.02f); // Middle
glVertex2f(0.3f, -0.085f);
glVertex2f(0.5f, -0.08f);
glVertex2f(0.8f, -0.088f);
glVertex2f(1.0f, -0.1f);
glVertex2f(1.0f, -1.0f); // Right
glEnd();
}
//
//
void drawScene()
{
drawSun();
drawShape();
}
void display(void) {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Setup translation matrix and store in T. Pass this over the the shader with the function glUniformMatrix4fv
GUMatrix4 T = GUMatrix4::translationMatrix(0.01f, 0.01f, 0.0f);
glUniformMatrix4fv(locT, 1, GL_FALSE, (GLfloat*)&T);
// Setup rotation matrix and store in R. Pass this over the the shader with the function glUniformMatrix4fv
GUMatrix4 R = GUMatrix4::rotationMatrix(0.0f, 0.0f, theta);
glUniformMatrix4fv(locR, 1, GL_FALSE, (GLfloat*)&R);
// Draw the scene (the above transformations will be applied to each vertex in the vertex shader)
drawScene();
glutSwapBuffers();
}
void mouseButtonDown(int button_id, int state, int x, int y) {
if (button_id==GLUT_LEFT_BUTTON) {
if (state==GLUT_DOWN) {
mouse_x = x;
mouse_y = y;
mDown = true;
} else if (state == GLUT_UP) {
mDown = false;
}
}
}
void mouseMove(int x, int y) {
if (mDown) {
int dx = x - mouse_x;
int dy = y - mouse_y;
float delta_theta = (float)dy * (3.142f * 0.01f);
theta += delta_theta;
mouse_x = x;
mouse_y = y;
glutPostRedisplay();
}
}
void keyDown(unsigned char key, int x, int y) {
if (key=='r') {
theta = 0.0f;
glutPostRedisplay();
}
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
initCOM();
glutInitContextVersion(3, 3);
glutInitContextProfile (GLUT_COMPATIBILITY_PROFILE);
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(800, 800);
glutInitWindowPosition(0, 0);
glutCreateWindow("Combining Transforms");
glutDisplayFunc(display);
glutKeyboardFunc(keyDown);
glutMouseFunc(mouseButtonDown);
glutMotionFunc(mouseMove);
init();
glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_GLUTMAINLOOP_RETURNS);
glutMainLoop();
shutdownCOM();
return 0;
}
EDIT
I have an array of x,y vertices and am trying to draw them alongside the above code. For some reason this seems to take vertex data from the sunVAO.
Is there some kind of cache that needs to be cleared? I've searched google and I can't seem to find anyone else who has conflicting VAO and vertex arrays.
(Also, I have checked my code and the vertex data supplied in the array of vertices is correct, they're just not displayed correctly.)
Code:
static GLfloat bottomMarkerVertices[] = {
-0.045f, -0.75f,
0.045f, -0.75f,
-0.07f, -1.0f,
0.07f, -1.0f
};
glVertexPointer(2, GL_FLOAT, 0, bottomMarkerVertices);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
note: vertex arrays have been enabled.
Assuming you're defining your coordinates in normalized device space (suggested by the apparent absence of a projection matrix), the rendering loop needs to look a little like this:
void drawScene()
{
//update shader parameters for the sun shader if necessary
drawSun();
glUseProgram(0);
// at this point, the PROJECTION and MODELVIEW matrices are both the identity
// so the shape is expected to be in NDCs and is not to be transformed
// at all
drawShape();
glUseProgram(progForSun);
}
Note that I don't advise to mix legacy and modern OpenGL like that. The results of vertex processing triggered by drawShape() are only defined because you're using a compatibility profile context.
The two elements of your scene move together because they are both using the same transformation matrices, specificed by these lines:
// Setup translation matrix and store in T. Pass this over the the shader with the function glUniformMatrix4fv
GUMatrix4 T = GUMatrix4::translationMatrix(0.01f, 0.01f, 0.0f);
glUniformMatrix4fv(locT, 1, GL_FALSE, (GLfloat*)&T);
// Setup rotation matrix and store in R. Pass this over the the shader with the function glUniformMatrix4fv
GUMatrix4 R = GUMatrix4::rotationMatrix(0.0f, 0.0f, theta);
glUniformMatrix4fv(locR, 1, GL_FALSE, (GLfloat*)&R);
If you want drawShape() not to move with the mouse, you need to reset locR with a fixed theta value before you call it.
drawSun();
GUMatrix4 R = GUMatrix4::rotationMatrix(0.0f, 0.0f, 0.0f);
glUniformMatrix4fv(locR, 1, GL_FALSE, (GLfloat*)&R);
drawShape();