OpenGL Transform Feedback not returning anything - c++

I am working on a Project to create Geometry by using a Geometry Shader and Transform Feedback.
I am currently trying to have the Geometry Shader return its input (1 triangle) without changing/adding anything, but its not working.
I would appreciate any help/advice I can get. Here are parts of my code:
The creation of the Program for Transform Feedback:
//==========================================
// Create the Transform Program
//==========================================
int check = LoadShader("Shaders//transformVS.glsl", GL_VERTEX_SHADER, transformVS);
//TODO: check for fail
check = LoadShader("Shaders//transformGS.glsl", GL_GEOMETRY_SHADER, transformGS);
//TODO: check for fail
transformProgram = glCreateProgram();
glAttachShader(transformProgram, transformVS);
glAttachShader(transformProgram, transformGS);
glBindAttribLocation(transformProgram, 0, "position_in");
glBindAttribLocation(transformProgram, 1, "normal_in");
glBindAttribLocation(transformProgram, 2, "length_in");
static const char* varyings[] = { "position_out", "normal_out", "length_out" };
glTransformFeedbackVaryings(transformProgram, 3, varyings, GL_INTERLEAVED_ATTRIBS);
glLinkProgram(transformProgram);
if (CheckProgram(transformProgram) == -1){
glDetachShader(transformProgram, transformVS);
glDetachShader(transformProgram, transformGS);
glDeleteShader(transformVS);
transformVS = 0;
glDeleteShader(transformGS);
transformGS = 0;
glDeleteProgram(transformProgram);
transformProgram = 0;
return -1;
}
error = glGetError();
The Creation of the VBOs, VAOs and TFOs:
//=====================================
// Create VBOs
//=====================================
glGenBuffers(2, VBOID);
glBindBuffer(GL_ARRAY_BUFFER, VBOID[0]);
glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(TVertex_VNL), vertices, GL_DYNAMIC_COPY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
error = glGetError();
glBindBuffer(GL_ARRAY_BUFFER, VBOID[1]);
glBufferData(GL_ARRAY_BUFFER, 3 * sizeof(TVertex_VNL), NULL, GL_DYNAMIC_COPY);
glBindBuffer(GL_ARRAY_BUFFER, 0);
error = glGetError();
//=====================================
// Create VAOs
//=====================================
glGenVertexArrays(2, VAOID);
glBindVertexArray(VAOID[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBOID[0]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(0)); //position
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(sizeof(float) * 3)); //normal
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(sizeof(float) * 6)); //length
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glBindVertexArray(0);
error = glGetError();
glBindVertexArray(VAOID[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBOID[1]);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(0)); //position
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(sizeof(float) * 3)); //normal
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(TVertex_VNL), BUFFER_OFFSET(sizeof(float) * 6)); //length
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glBindVertexArray(0);
error = glGetError();
//=====================================
// Create TFOs
//=====================================
glGenTransformFeedbacks(2, TFOID);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TFOID[0]);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, VBOID[0]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
error = glGetError();
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TFOID[1]);
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, VBOID[1]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
error = glGetError();
The render Method:
//=========================================
// Clear Screen
//=========================================
//Clear all the buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
//========================================
// Transform Feedback
//========================================
glEnable(GL_RASTERIZER_DISCARD);
glUseProgram(transformProgram);
glBindVertexArray(VAOID[0]);
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, TFOID[1]);
glBeginTransformFeedback(GL_TRIANGLES);
glDrawArrays(GL_TRIANGLES, 0, 3);
glEndTransformFeedback();
glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
glDisable(GL_RASTERIZER_DISCARD);
//========================================
// Draw Triangle
//========================================
//Bind the shader that we want to use
glUseProgram(renderProgram);
//Setup all uniforms for your shader
glUniformMatrix4fv(renderMVP, 1, FALSE, &MVP[0][0]);
//Bind the VAO
glBindVertexArray(VAOID[1]);
glDrawArrays(GL_TRIANGLES, 0, 3);
//glDrawTransformFeedback(GL_TRIANGLES, TFOID[1]);
//========================================
// Swap Buffers
//========================================
glutSwapBuffers();
The Vertex Shader:
#version 330
in vec3 position_in;
in vec3 normal_in;
in float length_in;
out vec3 vs_position;
out vec3 vs_normal;
out float vs_length;
void main()
{
vs_position = position_in;
vs_normal = normal_in;
vs_length = length_in;
}
The Geometry Shader:
#version 330
layout(triangles) in;
layout(triangle_strip, max_vertices = 3) out;
in vec3 vs_position[];
in vec3 vs_normal[];
in float vs_length[];
out vec3 position_out;
out vec3 normal_out;
out float length_out;
void main()
{
for(int i = 0; i < 3; i++){
position_out = vs_position[i];
normal_out = vs_normal[i];
length_out = vs_length[i];
EmitVertex();
}
EndPrimitive();
}

Your geometry shader is not emitting any vertices because the for loop body is never entered:
for(int i = 0; i >= 3; i++){

Related

Why is glreadpixels only working in certain cases?

If I try to read the screen with glreadpixels and then draw the same thing again using gldrawpixels it works, BUT if and only if I use anything else to draw than gldrawarrays and gldrawelements (gluSphere/gluCylinder work just fine). I'm trying to draw an object to the screen and save the pixels in an array.
I tried reading/writing to front/back buffers, reading after I swap buffers, all to no avail.
here is the code that I use to draw the object: (please note that I do not use any kind of buffers outside of this scope).
void CCssample5View::DrawCylinder(Model obj)
{
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
Shader castingShader("casting.vs", "casting.fs");
Shader lightShader("light.vs", "light.fs");
GLuint MatrixID = glGetUniformLocation(castingShader.ID, "MVP");
GLuint ViewMatrixID = glGetUniformLocation(castingShader.ID, "V");
GLuint ModelMatrixID = glGetUniformLocation(castingShader.ID, "M");
GLuint textur = loadBMP_custom("flower.bmp");
GLuint TextureID = glGetUniformLocation(castingShader.ID , "myTextureSampler");
indexVBO(obj.vertices, obj.uvs, obj.normals, obj.indices, obj.indexed_vertices, obj.indexed_uvs, obj.indexed_normals);
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, obj.indexed_vertices.size() * sizeof(glm::vec3), &obj.indexed_vertices[0], GL_STATIC_DRAW);
GLuint uvbuffer;
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, obj.indexed_uvs.size() * sizeof(glm::vec2), &obj.indexed_uvs[0], GL_STATIC_DRAW);
GLuint normalbuffer;
glGenBuffers(1, &normalbuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, obj.indexed_normals.size() * sizeof(glm::vec3), &obj.indexed_normals[0], GL_STATIC_DRAW);
GLuint elementbuffer;
glGenBuffers(1, &elementbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, obj.indices.size() * sizeof(unsigned short), &obj.indices[0], GL_STATIC_DRAW);
castingShader.use();
GLuint LightID = glGetUniformLocation(castingShader.ID, "LightPosition_worldspace");
computeMatricesFromInputs();
GLfloat gProjectionMatrix[16];
glGetFloatv(GL_PROJECTION_MATRIX, gProjectionMatrix);
glm::mat4 ProjectionMatrix = glm::make_mat4(gProjectionMatrix);// = glm::mat4(gProjectionMatrix);
GLfloat gViewMatrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, gViewMatrix);
glm::mat4 ViewMatrix = glm::make_mat4(gViewMatrix);// = glm::mat4(gProjectionMatrix);
glm::vec3 lightPos = glm::vec3(4, 4, 4);
glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z);
glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);
glm::mat4 ModelMatrix1 = glm::mat4(1.0);
glm::mat4 MVP1 = ProjectionMatrix * ViewMatrix * ModelMatrix1;
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, textur);
glUniform1i(TextureID, 0);
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP1[0][0]);
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix1[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(
1, // attribute
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 3rd attribute buffer : normals
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(
2, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
// Draw the triangles !
glDrawElements(
GL_TRIANGLES, // mode
obj.indices.size(), // count
GL_UNSIGNED_SHORT, // type
(void*)0 // element array buffer offset
);
//glFlush(); glFinish(); readScreen(screen, GL_RGB, true);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &uvbuffer);
glDeleteBuffers(1, &normalbuffer);
glDeleteBuffers(1, &elementbuffer);
glDeleteProgram(castingShader.ID);
glDeleteTextures(1, &textur);
glDeleteVertexArrays(1, &VertexArrayID);
}
These are my read and draw screen functions:
void CCssample5View::readScreen(GLubyte* screen, GLenum format, bool back)
{
check();
if (format == GL_RGB) {
check();
if (back) {
glReadBuffer(GL_BACK);
check();
}
else {
glReadBuffer(GL_FRONT);
check();
}
}
//glRasterPos2i(00, 00);
//glDisable(GL_DEPTH_TEST);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glReadPixels(0, 0, w, h, format, GL_UNSIGNED_BYTE, screen);
glFlush();
glFinish();
bool found = false;
for (size_t u = 0; u <= w * h * 4; u++) {
if (screen[u] != 0) {
found = true;
break;
}
}
assert(found);
check();
}
void CCssample5View::drawScreen(GLubyte *screen, GLenum format, bool back)
{
glClear(GL_COLOR_BUFFER_BIT);
//glGetIntegerv(GL_CURRENT_RASTER_POSITION, rasterpos);
if (back) {
glDrawBuffer(GL_BACK);
}
else {
glDrawBuffer(GL_FRONT);
}
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glDrawPixels(w, h, format, GL_UNSIGNED_BYTE, screen);
check();
glFlush();
glFinish();
}
Can not seem to figure out whats wrong when the drawing is perfect except the reading screen part..
I figured it out. All I had to do was add glUseProgram(0) at the very end of the draw cylinder function. After more than 3 weeks of looking into this.

OpenGL Widget on QT doesn't display primitives

The class copied below serve to create an OpenGL context in a QT widget.
However it doesn't display any point while it works well when I use GLFW...
#include "glwidget.h"
#include "shader.hpp"
GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent) {
}
GLWidget::~GLWidget() {
// Cleanup VBO
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &colorbuffer);
glDeleteBuffers(1, &elementbuffer);
glDeleteProgram(programID);
glDeleteVertexArrays(1, &VertexArrayID);
}
void GLWidget::initializeGL()
{
glewInit();
// Dark blue background
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
// Cull triangles which normal is not towards the camera
glEnable(GL_CULL_FACE);
// Create and compile our GLSL program from the shaders
programID = LoadShaders("SimpleVertexShader.vertexshader", "ColorFragmentShader.fragmentshader");
// Get a handle for our "MVP" uniform
MatrixID = glGetUniformLocation(programID, "MVP");
ModelMatrixID = glGetUniformLocation(programID, "M");
// Get a handle for our buffers
vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Temporary code for vertices and their color generation
vertices.push_back(glm::vec3(0,0,0)); // A point situated at 0,0,0 for test
color.push_back(glm::vec3(1.0, 0.0, 0.0));
index.push_back(0);
int size = 1000;
for (int i = 1; i < size; ++i) {
vertices.push_back(glm::vec3((rand() % 100) / 10, (rand() % 100) / 10, (rand() % 100) / 10));
color.push_back(glm::vec3(1.0, 0.0, 0.0));
index.push_back(i);
}
/*Computing the points centroid */
for (int i = 0; i < vertices.size(); i++)
{
mx += vertices[i][0];
my += vertices[i][1];
mz += vertices[i][2];
}
mx = mx / vertices.size(); my = my / vertices.size(); mz = mz / vertices.size();
for (int i = 0; i < vertices.size(); i++)
{
vertices[i][0] = vertices[i][0] - mx;
vertices[i][1] = vertices[i][1] - my;
vertices[i][2] = vertices[i][2] - mz;
}
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, color.size() * sizeof(glm::vec3), &color[0], GL_STATIC_DRAW);
glGenBuffers(1, &elementbuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index.size() * sizeof(unsigned int), &index[0], GL_STATIC_DRAW);
/* Line indexing, not in use actually....
unsigned int indexL[] = { 1550, vertices.size() - 1300 };
GLuint elementbufferLine;
glGenBuffers(1, &elementbufferLine);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbufferLine);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2 * sizeof(unsigned int), &indexL[0], GL_STATIC_DRAW); */
}
void GLWidget::resizeGL(int w, int h)
{
//glViewport(0, 0, w, h);
ViewMatrix = glm::lookAt(
glm::vec3(-5, -5, -5), // Camera is here
glm::vec3(mx, my, mz), // and looks here
glm::vec3(0, 1, 0) // Head is up (set to 0,-1,0 to look upside-down)
);
ModelMatrix = glm::mat4(1.0f);
ProjectionMatrix = glm::perspective(glm::radians(80.0f), float(w) /float(h), 0.1f, 100.0f);
MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
}
void GLWidget::paintGL()
{
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Using shaders */
glUseProgram(programID);
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
1, // attribute. No particular reason for 1, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
// Draw the point cloud !
glPointSize(5);
glDrawElements(
GL_POINTS, // mode
index.size(), // count
GL_UNSIGNED_INT, // type
(void*)0 // element array buffer offset
);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
I believe with your math, all vertices are created in a (0,0,0)-(9.9, 9.9, 9.9) range. Then you compute the centroid and subtract. lets say your mx, my, mz is (5.0, 5.0, 5.0). Now if you subtract the centroid, all your points are now in the range (-5.0, -5.0, -5.0) and (4.9, 4.9, 4.9).
In other words all you have done is center all your points to the origin. I believe you should be looking at the origin (0, 0, 0) not (5, 5, 5).

OpenGL send color to shader

I'm following the tutorials from: http://www.opengl-tutorial.org and trying a few things by my self.
At the moment my program can create triangles as class objects, transform their size and positions, and animate them (very simple code I just play around with). But when I'm trying to pass color value with Buffer Array to the Shaders, my triangles are not rendering.
I'll pass the relevant code here and try to make it understandble, hope someone can help me out here!
CODE:
#include <stdio.h>
#include <stdlib.h>
#include <iomanip>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <glm/glm.hpp>
#include <glm/gtx/transform.hpp>
using namespace glm;
#include "loadShader.h"
#include "model.h"
int _screenWidth = 1024;
int _screenHeight = 768;
int main()
{
//START GLFW
if (!glfwInit())
{
fprintf(stderr, "Failed to initialize GLFW\n");
return -1;
}
//GLFW SETTINGS
glfwWindowHint(GLFW_SAMPLES, 4); //4x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); //OPENGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); //Mac compatible?
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//open window
GLFWwindow* window;
window = glfwCreateWindow(_screenWidth, _screenHeight, "Tutorial 01", NULL, NULL);
if (window == NULL) {
fprintf(stderr, "Failed to open GLFW window. Make sure your GPU is openGL 3.3 compatible!\n");
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
//INITIALIZE GLEW
glewExperimental = true; //needed in core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW.\n");
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
glClearColor(0.125f, 0.0f, 0.3725f, 0.0f);
//Enable Depth test
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Create and compile GLSL program from the shaders
GLuint programID = LoadShaders("Shaders/vertexShaders.vert", "Shaders/fragmentShaders.frag");
//get handle for MVP uniform
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
/////////////////////
//MODEL//////////////
/////////////////////
//two triangles
int nVertices = 6;
//created through model class
model object1, object2;
object1.createTriangle();
object2.createTriangle();
//initialize buffer data arrays
GLfloat g_vertex_buffer_data[12*3];
// One color for each vertex
static const GLfloat g_color_buffer_data[] = {
0.583f, 0.771f, 0.014f,
0.609f, 0.115f, 0.436f,
0.327f, 0.483f, 0.844f,
0.822f, 0.569f, 0.201f,
0.435f, 0.602f, 0.223f,
0.310f, 0.747f, 0.185f };
//////////////////////////
//////////////////////////
//////////////////////////
//CREATE BUFFER
//This will identify our vertex and color buffer
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
//counters
float time = 0.0f;
int counter = 0;
int counterStep = 100;
do {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
time = time + 0.01;
counter = counter + 1;
//TRANSFORM MY TRIANGLES (its working)
glm::vec3 rotationAxis(0.0f, 0.0f, 1.0f);
glm::vec3 translation(0.0f, 0.0f, 0.025f);
float rotationAngle = 0.25f;
object1.rotate(rotationAngle, rotationAxis);
//object2.rotate(0.5*rotationAngle, rotationAxis);
object1.translate(translation);
//Update coordinates in vertex buffer (both triangles)
for (int i = 0; i < 3; i++)
{
g_vertex_buffer_data[i * 3] = object1.transformedPosition[i].x;
g_vertex_buffer_data[i * 3 + 1] = object1.transformedPosition[i].y;
g_vertex_buffer_data[i * 3 + 2] = object1.transformedPosition[i].z;
}
for (int i = 0; i < 3; i++)
{
g_vertex_buffer_data[i * 3 + 9] = object2.transformedPosition[i].x;
g_vertex_buffer_data[i * 3 + 10] = object2.transformedPosition[i].y;
g_vertex_buffer_data[i * 3 + 11] = object2.transformedPosition[i].z;
}
//Model matrix
glm::mat4 modelM = glm::mat4(1.0f);
//Projection matrix:
glm::mat4 projectionM = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
//Camera matrix:
glm::mat4 viewM = lookAt(
glm::vec3(8, 2, 2+10*time),
glm::vec3(0, 0, 0),
glm::vec3(0, 1, 0));
//MODEL VIEW PROJECTION MATRIX:
glm::mat4 mvpM = projectionM * viewM * modelM;
//Give our vertices and colors to OpenGL
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
/////////////////////////////////////////////
//USE SHADERS
glUseProgram(programID);
//Send our transformation to the currently bound shader, MVP uniform
glUniformMatrix4fv(MatrixID, 1, 0, &mvpM[0][0]);
//1rst attribute buffer: vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, //attribute 0, no particular reason, but must match the layout in the shader
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
(void*)0 //array buffer offset
);
//2nd attribute buffer: colors
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
1, //attribute number
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
(void*)0 //array buffer offset
);
//Draw the triangle
glDrawArrays(GL_TRIANGLES, 0, nVertices); //Starting from vertex 0; 3 vertices total
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
}
// Check if the ESC key was pressed or the window was closed
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);
// Cleanup VBO
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &colorbuffer);
glDeleteProgram(programID);
glDeleteVertexArrays(1, &VertexArrayID);
// Close OpenGL window and terminate GLFW
glfwTerminate();
return 0;
}
Vertexshader:
#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;
uniform mat4 MVP;
out vec3 fragmentColor;
void main(){
gl_Position = MVP * vec4(vertexPosition_modelspace,1.0);
fragmentColor = vertexColor;
}
Fragmentshder:
#version 330 core
in vec3 fragmentColor;
out vec3 color;
void main(){
color = fragmentColor;
}
If I remove:
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
and:
//2nd attribute buffer: colors
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
1, //attribute number
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
(void*)0 //array buffer offset
);
from the main function, the triangles renders.
EDIT
Here is only the relevant code which is where I think there is a problem:
//FIRST DO THIS: (but not sure why..)
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
//initialize buffer data arrays
GLfloat g_vertex_buffer_data[] = { something };
GLfloat g_color_buffer_data[] = { something };
//CREATE BUFFER
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
GLuint colorbuffer;
glGenBuffers(1, &colorbuffer);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
//LOOP
do {
//UPDATE BUFFER DATA
GLfloat g_vertex_buffer_data[] = { something new };
GLfloat g_color_buffer_data[] = { something new };
//SEND NEW BUFFER DATA TO SHADERS
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
//USE SHADERS
glUseProgram(programID);
//1rst attribute buffer: vertices positions
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, //attribute 0, no particular reason, but must match the layout in the shader
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
(void*)0 //array buffer offset
);
//2nd attribute buffer: colors
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glVertexAttribPointer(
1, //attribute number
3, //size
GL_FLOAT, //type
GL_FALSE, //normalized?
0, //stride
(void*)0 //array buffer offset
);
//Draw the triangles
glDrawArrays(GL_TRIANGLES, 0, nVertices); //Starting from vertex 0; 3 vertices total
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
}
// Check if the ESC key was pressed or the window was closed
while (glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0);
// Cleanup VBO
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &colorbuffer);
glDeleteProgram(programID);
glDeleteVertexArrays(1, &VertexArrayID);
// Close OpenGL window and terminate GLFW
glfwTerminate();
return 0;
}
SOLUTION
I sort off solved my problem by looking at this tutorial https://www.opengl.org/wiki/Tutorial2%3a_VAOs,_VBOs,_Vertex_and_Fragment_Shaders_%28C_/_SDL%29 .
Basically I just moved the bufferBinding and bufferData functions outside the loop. Somehow that was ok before with the vertex positions, but not the vertex colors...
I read and learned more and changed some of the code and it's working now and I'm happy with it now:)
Before you bufferdata, you should bind the buffer that you want send data in.
it should be
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data), g_color_buffer_data, GL_STATIC_DRAW);
Your code send did,not send any data to vertex position buffer.
Ps. for efficiency you should generate buffer, and submit the data before the loop.

glReadPixels returning incorrect values

I am trying to implement picking via following an opengl tutorial, I have a mesh with 6000 vertices and I wish to pick particular ones; I have chosen to do by redering uniquely coloured boxes at each vertex point, read the pixel on my mouse click at that point and that should return to me the ID of the closest vertex. The background is rendered as white so if I miss I get nothing.
However I have a problem, it only works most of the time; there are certain areas that if I click there I get white returned even though its clearly a vertex, and when rendering the colorized scene clearly has a redish box at the point I clicked.
Then there are white areas near the mesh, to the bottom left and at some random point away from it, returns me a hit.
I do not understand at all why this is happening, it should work.
void Display() {
Controls->setVector(indexed_vertices);
if (Controls->getPicking()) {
// Clear the screen in white
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
for ( int i=0; i< indexed_vertices.size(); i++) {
// use shaders
glUseProgram(pickingProgramID);
// Get a handle for our "MVP" uniform
GLuint PickingMatrixID = glGetUniformLocation(pickingProgramID, "MVP");
glm::mat4 RotationMatrix = glm::toMat4(orientations);
glm::mat4 btTranslationMatrix = glm::translate(glm::mat4(1.0f), indexed_vertices[i]);
glm::mat4 myModelMatrix = ModelMatrix * Controls->getTranslationMatrix() * Controls->getRotationMatrix() * btTranslationMatrix;
MVP = ProjectionMatrix * ViewMatrix * myModelMatrix;
Controls->setCntrlsViewMatrix(ViewMatrix);
Controls->setCntrlsProjectionMatrix(ProjectionMatrix);
glUniformMatrix4fv(PickingMatrixID, 1, GL_FALSE, &MVP[0][0]);
// Convert "i", the integer mesh ID, into an RGB color
int r = (i & 0x000000FF) >> 0;
int g = (i & 0x0000FF00) >> 8;
int b = (i & 0x00FF0000) >> 16;
// OpenGL expects colors to be in [0,1], so divide by 255.
glUniform4f(pickingColorID, r/255.0f, g/255.0f, b/255.0f, 1.0f);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, gvertexbuffer);
glVertexAttribPointer(
0, // attribute. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
// Draw the triangles !
glDrawElements(
GL_TRIANGLES, // mode
indices.size(), // count
GL_UNSIGNED_SHORT, // type
(void*)0 // element array buffer offset
);
// OpenGL expects colors to be in [0,1], so divide by 255.
}
glDisableVertexAttribArray(0);
glFlush();
glFinish();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
// Read the pixel at the center of the screen.
// You can also use glfwGetMousePos().
// Ultra-mega-over slow too, even for 1 pixel,
// because the framebuffer is on the GPU.
unsigned char data[4];
glReadPixels(Controls->get_mx_cur(), Controls->get_my_cur(),1,1, GL_RGBA, GL_UNSIGNED_BYTE, data);
std::cout << "MX: " << Controls->get_mx_cur() << " MY: " << Controls->get_my_cur() << std::endl;
// Convert the color back to an integer ID
int pickedID =
data[0] +
data[1] * 256 +
data[2] * 256*256;
//std::cout << std::hex << pickedID << std::dec<<std::endl;
if (pickedID == 0x00ffffff) { // Full white, must be the background !
printf("Miss\n");
}
else {
std::cout << "mesh " << pickedID << std::endl;
}
// Uncomment these lines to see the picking shader in effect
glutSwapBuffers();
skip = true;
Controls->setPicking(false);
}
if (!skip) {
// White background
glClearColor(0.2f, 0.25f, 0.5f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//glEnable(GL_CULL_FACE);
glUseProgram(ShaderIDs[0]);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture);
glUniform1i(TextureID, 0);
glm::mat4 myModelMatrix = ModelMatrix * Controls->getTranslationMatrix() * Controls->getRotationMatrix();
MVP = ProjectionMatrix * ViewMatrix * myModelMatrix;
// The inverse transpose of the View Model Matrix will re-normalize the normals if there's
// been any scaling. Otherwise you don't need it.
glm::mat3 NormalMatrix = glm::mat3( glm::transpose(glm::inverse(ViewMatrix * myModelMatrix)));
Controls->setCntrlsViewMatrix(ViewMatrix);
Controls->setCntrlsProjectionMatrix(ProjectionMatrix);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &myModelMatrix[0][0]);
// Notice we're passing a 3 by 3 matrix here.
glUniformMatrix3fv(NormalMatrixID, 1, GL_FALSE, &NormalMatrix[0][0]);
glUniform3f(CameraID, cameraLoc.x, cameraLoc.y, cameraLoc.z);
glUniform3f(LightPosID, lightPosition.x, lightPosition.y, lightPosition.z);
// VBO buffer: vertices
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(
1, // attribute
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 2rd attribute buffer : normals
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(
2, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
if ( Controls->getRenderingMode() == 0 ) {
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//glDisable(GL_POLYGON_OFFSET_FILL);
}
else if (Controls->getRenderingMode() == 1 ) {
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDisable(GL_CULL_FACE);
//glDisable(GL_POLYGON_OFFSET_FILL);
glUseProgram(ShaderIDs[1]);
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &myModelMatrix[0][0]);
// Notice we're passing a 3 by 3 matrix here.
glUniformMatrix3fv(NormalMatrixID, 1, GL_FALSE, &NormalMatrix[0][0]);
glUniform3f(CameraID, cameraLoc.x, cameraLoc.y, cameraLoc.z);
glUniform3f(LightPosID, lightPosition.x, lightPosition.y, lightPosition.z);
}
else if (Controls->getRenderingMode() == 2 ) {
glUseProgram(ShaderIDs[1]);
//
glm::mat4 MyOffsetMatrix = glm::scale(glm::mat4(1.0f), glm::vec3(1.025,1.025,1.025));
MyOffsetMatrix = glm::mat4(1.0f);
glm::mat4 myModelMatrix2 = ModelMatrix * Controls->getTranslationMatrix() *
Controls->getRotationMatrix()*MyOffsetMatrix;
glm::mat3 NormalMatrix2 = glm::mat3( glm::transpose(glm::inverse(ViewMatrix *
myModelMatrix2)));
glm::mat4 MVP2 = ProjectionMatrix * ViewMatrix * myModelMatrix2;
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP2[0][0]);
glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &myModelMatrix2[0][0]);
// Notice we're passing a 3 by 3 matrix here.
glUniformMatrix3fv(NormalMatrixID, 1, GL_FALSE, &NormalMatrix2[0][0]);
glUniform3f(CameraID, cameraLoc.x, cameraLoc.y, cameraLoc.z);
glUniform3f(LightPosID, lightPosition.x, lightPosition.y, lightPosition.z);
// The rest is exactly the same as the first object
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);
// 3rd attribute buffer : normals
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
// Index buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementbuffer);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glDisable(GL_CULL_FACE);
glEnable(GL_POLYGON_OFFSET_FILL);
// Draw the triangles !
glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, (void*)0);
glEnable(GL_POLYGON_OFFSET_FILL);
glDisable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glPolygonOffset(2.0f, 2.0f);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
//glDisable(GL_POLYGON_OFFSET_FILL);
glUseProgram(ShaderIDs[0]);
}
//glUseProgram(ShaderIDs[1]);
// Draw the triangles !
glDrawElements(
GL_TRIANGLES, // mode
indices.size(), // count
GL_UNSIGNED_SHORT, // type
(void*)0 // element array buffer offset
);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
glutSwapBuffers();
}
}
The problem was two-fold: Crazy numbers returned is a result of improper multisampling enabled when I wanted specific colour values (how to have my cake and eat it might need a bit of work but right now I don't care), and secondly because glReadPixels() inverts the Y axis and needed to do Height - Current_Mouse_Position for the Y value.
Perhaps glPoints would be faster means of doing what I'm doing, I'll need to look into it.

Drawing multiple object with texture doesn't work

I'm working on a 3D model loader. It can loads my own format. I wrote my own exporter for Blender, it works well. The model format can handle multiple meshes(objects) in one model. Each mesh can have a different texture. I've already written a loader which is working well, but doesn't use shaders.
I switched to shaders, but something is going wrong, the textures aren't appear correctly. Here is my drawing function, I'm sure the mistake is somewhere here:
void CModel::draw(glm::mat4 &MVP)
{
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
for(unsigned int i=0; i<m_numObjects; i++)
{
glUseProgram(m_programID);
glUniformMatrix4fv(m_matrixUniform, 1, GL_FALSE, &MVP[0][0]);
glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]);
glUniform1i(m_textureUniform, 0);
glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
// vertices
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0, // must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
sizeof(float)*8, // stride
(void*)0 // array buffer offset
);
// UVs
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
2,
GL_FLOAT,
GL_FALSE,
sizeof(float)*8,
(void*)6
);
glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisable(GL_TEXTURE_2D);
}
The vertex and fragment shaders are also working well.
The previous version (without shaders) was this (this worked well):
void CModel::draw()
{
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
for(unsigned int i=0; i<m_numObjects; i++)
{
glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]);
glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
glTexCoordPointer(2, GL_FLOAT, sizeof(float)*8, (float*)(sizeof(float)*6));
glNormalPointer( GL_FLOAT, sizeof(float)*8, (float*)(sizeof(float)*3));
glVertexPointer( 3, GL_FLOAT, sizeof(float)*8, 0);
glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisable(GL_TEXTURE_2D);
}
Here is the entire class:
#include "global.h"
#include "CModel.h"
#include "CModelLoader.h"
#include "CShaderLoader.h"
CModel::CModel(){}
CModel::~CModel()
{
// TODO free memory
}
/** #brief Load mbm file
*
* #fileName: mdm model file name we want to load and draw
*/
void CModel::init(char *fileName)
{
CModelLoader loader;
CShaderLoader shaders;
loader.loadData(fileName);
loader.createDataArray( m_dataArray,
m_dataArraySizes,
m_numObjects,
m_numElements,
m_textureIDs );
glGenVertexArrays(1, &m_vertexArrayID);
glBindVertexArray(m_vertexArrayID);
m_programID = shaders.loadShaders("vertexshader.vert", "fragmentshader.frag");
m_bufferIDs = new unsigned int[m_numObjects];
glGenBuffers(m_numObjects, m_bufferIDs);
for(unsigned int i=0; i<m_numObjects; i++)
{
glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float)*m_dataArraySizes[i], m_dataArray[i], GL_STATIC_DRAW);
}
}
/** #brief Drawing the mdm model
*
*/
void CModel::draw(glm::mat4 &MVP)
{
glEnable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
for(unsigned int i=0; i<m_numObjects; i++)
{
glUseProgram(m_programID);
unsigned int matrixUniform = glGetUniformLocation(m_programID, "MVP");
unsigned int textureUniform = glGetUniformLocation(m_programID, "myTextureSampler");
glUniformMatrix4fv(matrixUniform, 1, GL_FALSE, &MVP[0][0]);
glUniform1i(textureUniform, 0);
glBindTexture(GL_TEXTURE_2D, m_textureIDs[i]);
glBindBuffer(GL_ARRAY_BUFFER, m_bufferIDs[i]);
// vertices
glEnableVertexAttribArray(0);
glVertexAttribPointer(
0, // must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
sizeof(float)*8, // stride
(void*)0 // array buffer offset
);
// UVs
glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
2,
GL_FLOAT,
GL_FALSE,
sizeof(float)*8,
(void*)6
);
glDrawArrays(GL_TRIANGLES, 0, m_numElements[i]);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glUseProgram(0);
}
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisable(GL_TEXTURE_2D);
}
Finally I solved it. The problem was that I used one array for vertices, normals and texture coordinates instead of storing in separate arrays and bind them separately.