Hello,
I want to draw N*N squares. In order to do so, I draw 2 triangles by using 2 for loops which update coordinates following i and j. here is the whole code :
Note 1 : Those points are using 3D coordinates, because I will need to use 3D coordinate later.
Note 2 : I will also need a second VAO, that is why g_vertex_buffer_data_1 is being initialized but is not used.
#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <unistd.h>
using namespace std;
#include <stdlib.h>
#include <string.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#ifdef __APPLE__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
using namespace glm;
#define GLM_FORCE_RADIANS
const int N = 10;
GLint uniform_proj, uniform_view, uniform_model;
GLuint LoadShaders(const char * vertex_file_path,const char * fragment_file_path){
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file
std::string VertexShaderCode;
std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
if(VertexShaderStream.is_open()){
std::string Line = "";
while(getline(VertexShaderStream, Line))
VertexShaderCode += "
" + Line;
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !
", vertex_file_path);
getchar();
return 0;
}
// Read the Fragment Shader code from the file
std::string FragmentShaderCode;
std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
if(FragmentShaderStream.is_open()){
std::string Line = "";
while(getline(FragmentShaderStream, Line))
FragmentShaderCode += "
" + Line;
FragmentShaderStream.close();
}
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
printf("Compiling shader : %s
", vertex_file_path);
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
printf("%s
", &VertexShaderErrorMessage[0]);
}
// Compile Fragment Shader
printf("Compiling shader : %s
", fragment_file_path);
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
printf("%s
", &FragmentShaderErrorMessage[0]);
}
// Link the program
printf("Linking program
");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
uniform_proj = glGetUniformLocation(ProgramID, "projectionMatrix");
uniform_view = glGetUniformLocation(ProgramID, "viewMatrix");
uniform_model = glGetUniformLocation(ProgramID, "modelMatrix");
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
printf("%s
", &ProgramErrorMessage[0]);
}
glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
}
int main(){
// Initialises GLFW
if( !glfwInit() ) {
fprintf( stderr, "Failed to initialize GLFW
" );
return -1;
}
GLfloat g_vertex_buffer_data[N*N*18];
GLfloat g_vertex_color_data[N*N*18];
GLfloat g_vertex_buffer_data_1[9*5*N];
GLfloat g_vertex_color_data_1[9*5*N];
for (int j=0; j<N; j++){
for(int i=0; i<N; i++){
//Triangle1
g_vertex_buffer_data[ 0+i*j*18] = i;
g_vertex_buffer_data[ 1+i*j*18] = j;
g_vertex_buffer_data[ 2+i*j*18] = 0.0f;
g_vertex_buffer_data[ 3+i*j*18] = i;
g_vertex_buffer_data[ 4+i*j*18] = j+1;
g_vertex_buffer_data[ 5+i*j*18] = 0.0f;
g_vertex_buffer_data[ 6+i*j*18] = i+1;
g_vertex_buffer_data[ 7+i*j*18] = j;
g_vertex_buffer_data[ 8+i*j*18] = 0.0f;
//Triangle2
g_vertex_buffer_data[ 9+i*j*18] = i;
g_vertex_buffer_data[10+i*j*18] = j+1;
g_vertex_buffer_data[11+i*j*18] = 0.0;
g_vertex_buffer_data[12+i*j*18] = i+1;
g_vertex_buffer_data[13+i*j*18] = j;
g_vertex_buffer_data[14+i*j*18] = 0.0f;
g_vertex_buffer_data[15+i*j*18] = i+1;
g_vertex_buffer_data[16+i*j*18] = j+1;
g_vertex_buffer_data[17+i*j*18] = 0.0f;
//colors
g_vertex_color_data[ 0+i*j*18] = 0.0;
g_vertex_color_data[ 1+i*j*18] = 0.0;
g_vertex_color_data[ 2+i*j*18] = 1.0;
g_vertex_color_data[ 3+i*j*18] = 0.0;
g_vertex_color_data[ 4+i*j*18] = 1.0;
g_vertex_color_data[ 5+i*j*18] = 0.0;
g_vertex_color_data[ 6+i*j*18] = 1.0;
g_vertex_color_data[ 7+i*j*18] = 0.0;
g_vertex_color_data[ 8+i*j*18] = 0.0;
g_vertex_color_data[ 9+i*j*18] = 0.0;
g_vertex_color_data[10+i*j*18] = 0.0;
g_vertex_color_data[11+i*j*18] = 1.0;
g_vertex_color_data[12+i*j*18] = 0.0;
g_vertex_color_data[13+i*j*18] = 1.0;
g_vertex_color_data[14+i*j*18] = 0.0;
g_vertex_color_data[15+i*j*18] = 1.0;
g_vertex_color_data[16+i*j*18] = 0.0;
g_vertex_color_data[17+i*j*18] = 0.0;
}
}
glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // On veut OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_DEPTH_BITS, 24);
GLFWwindow* window;
window = glfwCreateWindow( 1024, 768, "Tutorial 01", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.
" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
glewExperimental=true;
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW
");
return -1;
}
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
glDepthRange(-1, 1);
// modern OpenGL do not have a default VAO anymore. Even if we don't want to use it
// we have a create and bind one before playing with buffers !
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// This will identify our vertex buffer
GLuint vertexbuffer;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer);
//The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
// Only allocqte memory. Do not send yet our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data)+sizeof(g_vertex_color_data), 0, GL_STATIC_DRAW);
// send vertices in the first part of the buffer
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(g_vertex_buffer_data), g_vertex_buffer_data);
// send vertices in the second part of the buffer
glBufferSubData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), sizeof(g_vertex_color_data), g_vertex_color_data);
// ici les commandes stockees "une fois pour toute" dans le VAO
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(0);
glVertexAttribPointer( // same thing for the colors
1,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)sizeof(g_vertex_buffer_data));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
// on desactive le VAO a la fin de l'initialisation
glBindVertexArray (0);
GLuint VertexArrayID_1;
glGenVertexArrays(1, &VertexArrayID_1);
glBindVertexArray(VertexArrayID_1);
// This will identify our vertex buffer
GLuint vertexbuffer_1;
// Generate 1 buffer, put the resulting identifier in vertexbuffer
glGenBuffers(1, &vertexbuffer_1);
//The following commands will talk about our 'vertexbuffer' buffer
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer_1);
// Only allocate memory. Do not send yet our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data_1)+sizeof(g_vertex_color_data_1), 0, GL_STATIC_DRAW);
// send vertices in the first part of the buffer
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(g_vertex_buffer_data_1), g_vertex_buffer_data_1);
// send vertices in the second part of the buffer
glBufferSubData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data_1), sizeof(g_vertex_color_data_1), g_vertex_color_data_1);
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(0);
glVertexAttribPointer( // same thing for the colors
1,
3,
GL_FLOAT,
GL_FALSE,
0,
(void*)sizeof(g_vertex_buffer_data));
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray (0);
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
GLuint programID = LoadShaders( "SimpleVertexShader5.vertexshader", "SimpleFragmentShader5.fragmentshader" );
float angle = 0.0f;
do{
angle = (angle+M_PI/200);
// clear before every draw 1
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(programID);
// onchange de matrice de projection : la projection orthogonale est plus propice a la visualization !
//glm::mat4 projectionMatrix = glm::perspective(45.0f, 1024.0f / 768.0f, 0.0f, 200.0f);
glm::mat4 projectionMatrix = glm::ortho( -60.0f, 40.0f, -20.0f, 20.0f, -200.f, 20.f );
glm::mat4 viewMatrix = glm::lookAt(
vec3(1.5*cos(1.5*M_PI), 1.5*sin(1.5*M_PI), -0.5), // where is the camera
vec3(0,0,0.5), //where it looks
vec3(0,0, 1) // head is up
);
mat4 modelMatrix = glm::mat4(1.0);
mat4 modelMatrix_1 = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 0.5f));
glUniformMatrix4fv(uniform_proj, 1, GL_FALSE, glm::value_ptr(projectionMatrix));
glUniformMatrix4fv(uniform_view, 1, GL_FALSE, glm::value_ptr(viewMatrix));
glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(modelMatrix));
glBindVertexArray(VertexArrayID);
// Draw the triangle(s) !
glDrawArrays(GL_TRIANGLES, 0, sizeof(g_vertex_buffer_data)/(3*sizeof(float))); // Starting from vertex 0; 6 vertices total -> 2 triangles
glBindVertexArray (0);
glBindVertexArray(VertexArrayID_1);
//glUniformMatrix4fv(uniform_model, 1, GL_FALSE, glm::value_ptr(modelMatrix_1));
glDrawArrays(GL_TRIANGLES, 0, sizeof(g_vertex_buffer_data_1)/(3*sizeof(float))); // Starting from vertex 0; 6 vertices total -> 2 triangles
glBindVertexArray (0);
glUseProgram(0);
// Swap buffers
glfwSwapBuffers(window);
glfwPollEvents();
}while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
}
}
}
Where j represents the number of columns and i represents the number of rows. I expect this program to draw N squares, but it only draws a some of them. In fact, the amount of columns and rows are respected but there are also a lot of black space between some squares. Here is what I get for N = 10 :
[ATTACH=CONFIG]1628[/ATTACH]
I am not getting NN squares, so I do not know why this algorithm is not working. I tried to replace ij by i+j, the program drew something that does not correspond to a square. I also tried to replace 0+ij18 with i+j*18, but in this case, I only get a black screen. So I do not know where are the issues.
Thanks for reading.