PDA

View Full Version : How can i write vertex and fragment shader program to draw image from texture?



colagl
06-06-2016, 07:55 AM
Hi,

Code:


#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;

#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>
#include<GLFW/glfw3.h>
#include<GL/glu.h>

typedef struct __attribute__((__packed__)) {
unsigned short type;
unsigned long size;
unsigned short reserved1;
unsigned short reserved2;
unsigned long offsetbits;
} BITMAPFILEHEADER1;

typedef struct __attribute__((__packed__)) {
unsigned long size;
unsigned long width;
unsigned long height;
unsigned short planes;
unsigned short bitcount;
unsigned long compression;
unsigned long sizeimage;
long xpelspermeter;
long ypelspermeter;
unsigned long colorsused;
unsigned long colorsimportant;
} BITMAPINFOHEADER1;

typedef struct {
unsigned char blue;
unsigned char green;
unsigned char red;
} SINGLE_PIXEL1;


GLFWwindow* window;

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 += "\n" + Line;
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", 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 += "\n" + Line;
FragmentShaderStream.close();
}

GLint Result = GL_FALSE;
int InfoLogLength;


// Compile Vertex Shader
printf("Compiling shader : %s\n", 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\n", &VertexShaderErrorMessage[0]);
}



// Compile Fragment Shader
printf("Compiling shader : %s\n", 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\n", &FragmentShaderErrorMessage[0]);
}



// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);

// 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\n", &ProgramErrorMessage[0]);
}


glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);

glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);

return ProgramID;
}


int main( void )
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
return -1;
}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);


// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Tutorial 02 - Red triangle", 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.\n" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

// Initialize GLEW
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}

// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

FILE *fp;
unsigned char p;
int x=0,y=0,c=0;
float r,g,b;
float rowsize,pixelarraysize;

int datasize;

BITMAPFILEHEADER1 bitmp;
BITMAPINFOHEADER1 bitm;

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

fp = fopen("free.bmp","rb");//Filename is given

fread(&bitmp,14,1,fp);

fread(&bitm,40,1,fp);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,bitm.width,0.0,bitm.height);
glViewport(10,10,bitm.width,bitm.height);

vector<float> v_data;
int width,height;

width=bitm.width;
height=bitm.height;

rowsize=((bitm.bitcount*bitm.width+31)/32)*4;
pixelarraysize=rowsize*bitm.height;
datasize=(bitm.bitcount/8.0)*bitm.width;

int padding;
padding = rowsize - (width * 3);
while(!feof(fp))
{
fread(&p,1,1,fp);
b = p/255.0;
fread(&p,1,1,fp);
g = p/255.0;
fread(&p,1,1,fp);
r = p/255.0;

v_data.push_back(r);
v_data.push_back(g);
v_data.push_back(b);
x++;
if(x == bitm.width)
{
fseek(fp,padding,SEEK_CUR);
x = 0;
y++;
}

}

unsigned int texture;

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0 ,GL_RGB,GL_FLOAT,&v_data[0]);

glEnable(GL_TEXTURE_2D);
//glActiveTexture(GL_TEXTURE);

// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );

printf("programID: %u\n",programID);

// Get a handle for our buffers
GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");

printf("vertexPosition_modelspaceID: %u\n",vertexPosition_modelspaceID);

static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 0.7f, 0.0f,
};

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

// do{

// Clear the screen
glClear( GL_COLOR_BUFFER_BIT );

// Use our shader
glUseProgram(programID);

GLint myUniformLocation = glGetUniformLocation(programID, "myUniform");
glUniform3f(myUniformLocation, 1.0,0.0,0.0);

// 1rst attribute buffer : vertices
glEnableVertexAttribArray(vertexPosition_modelspac eID);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
vertexPosition_modelspaceID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);

// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle

glDisableVertexAttribArray(vertexPosition_modelspa ceID);

while (!glfwWindowShouldClose(window))
{
/* Render here */
//draw_all();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}

// 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);
glDeleteProgram(programID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}



Vertax shader:


#version 120
// Input vertex data, different for all executions of this shader.
attribute vec3 vertexPosition_modelspace;

void main() {
gl_Position = vec4(vertexPosition_modelspace, 1.0);
}


Fragment shader:


#version 120

uniform vec3 myUniform;

void main()
{

// Output color = red
//gl_FragColor = vec4(myUniform,0,0,1);
gl_FragColor = vec4(myUniform,1);

}




g++ program.cpp -o program -lglfw -lGL -lGLU -lGLEW
./program

This draws a rectangle.
I followed this tutorial: http://www.opengl-tutorial.org/download/ (OpenGL-tutorial_v0015_21 The OpenGL 2.1 port)

I don't understand glsl shader program completely. I'm reading tutorial for glsl programming.

The bitmap image data is passed in this way:


glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0 ,GL_RGB,GL_FLOAT,&v_data[0]);

How can i write vertex and fragment shader program to draw the bitmap image from texture?
Can anyone write vertex and fragment shader program and post here?

Any answer will be highly appreciated.
Thanks in advance.

colagl
06-06-2016, 08:00 AM
You can download the bitmap image from http://www3.zippyshare.com/v/WcDwm6pm/file.html (free.bmp)

Hermannicus
06-06-2016, 04:46 PM
But it's part of the tutorial, you linked: http://www.opengl-tutorial.org/beginners-tutorials/tutorial-5-a-textured-cube/

john_connor
06-06-2016, 06:20 PM
to be able to draw a texture appropriately, you have to submit texture coordinates for each vertex (corner of the quad)

then add in your vertexshader:
attribute vec2 in_texcoords;

out vec2 out_texcoords;
// after setting gl_Position in main(), pass through to fragmentshader the texcoords like that:
out_texcoords = in_texcoords;

then add in your fragmentshader:
in vec2 out_texcoords;
uniform sampler2D tex;

// in main();
vec4 colorfromtexture = texture(tex, out_texcoords);
// then assign that color to gl_FragColor

that's all regarding the shader, but you should also change your buffer:


static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f, 0, 0,
1.0f, -1.0f, 0.0f, 1, 0,
0.0f, 0.7f, 0.0f, 0, 1,
};

and then you have to correct the vertex attrib pointers:

0, // stride
thats wrong anyway, in your case (without my suggestions), it should be

(sizeof(float) * 3), // stride because 1 vertex has 3 floats

with my suggestions, 1vertex has now 5 floats

(sizeof(float) * 5), // stride
in addition to that, you have to add 1 extra pointer for the texture coords


glVertexAttribPointer(
1, // attrib location of texture coords
2, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)(sizeof(float) * 3) // offset, texture coords begin after 3 floats (vertex position)
);

colagl
06-06-2016, 08:27 PM
@john_connor,

It doesn't draw anything, it's white window.

Code:


#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;

#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>
#include<GLFW/glfw3.h>
#include<GL/glu.h>

typedef struct __attribute__((__packed__)) {
unsigned short type;
unsigned long size;
unsigned short reserved1;
unsigned short reserved2;
unsigned long offsetbits;
} BITMAPFILEHEADER1;

typedef struct __attribute__((__packed__)) {
unsigned long size;
unsigned long width;
unsigned long height;
unsigned short planes;
unsigned short bitcount;
unsigned long compression;
unsigned long sizeimage;
long xpelspermeter;
long ypelspermeter;
unsigned long colorsused;
unsigned long colorsimportant;
} BITMAPINFOHEADER1;

typedef struct {
unsigned char blue;
unsigned char green;
unsigned char red;
} SINGLE_PIXEL1;


GLFWwindow* window;

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 += "\n" + Line;
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", 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 += "\n" + Line;
FragmentShaderStream.close();
}

GLint Result = GL_FALSE;
int InfoLogLength;


// Compile Vertex Shader
printf("Compiling shader : %s\n", 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\n", &VertexShaderErrorMessage[0]);
}



// Compile Fragment Shader
printf("Compiling shader : %s\n", 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\n", &FragmentShaderErrorMessage[0]);
}



// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);

// 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\n", &ProgramErrorMessage[0]);
}


glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);

glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);

return ProgramID;
}


int main( void )
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
return -1;
}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);


// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Tutorial 02 - Red triangle", 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.\n" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

// Initialize GLEW
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}

// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

FILE *fp;
unsigned char p;
int x=0,y=0,c=0;
float r,g,b;
float rowsize,pixelarraysize;

int datasize;

BITMAPFILEHEADER1 bitmp;
BITMAPINFOHEADER1 bitm;

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

fp = fopen("free.bmp","rb");//Filename is given

fread(&bitmp,14,1,fp);

fread(&bitm,40,1,fp);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,bitm.width,0.0,bitm.height);
glViewport(10,10,bitm.width,bitm.height);

vector<float> v_data;
int width,height;

width=bitm.width;
height=bitm.height;

rowsize=((bitm.bitcount*bitm.width+31)/32)*4;
pixelarraysize=rowsize*bitm.height;
datasize=(bitm.bitcount/8.0)*bitm.width;

int padding;
padding = rowsize - (width * 3);
while(!feof(fp))
{
fread(&p,1,1,fp);
b = p/255.0;
fread(&p,1,1,fp);
g = p/255.0;
fread(&p,1,1,fp);
r = p/255.0;

v_data.push_back(r);
v_data.push_back(g);
v_data.push_back(b);
x++;
if(x == bitm.width)
{
fseek(fp,padding,SEEK_CUR);
x = 0;
y++;
}

}

unsigned int texture;

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0 ,GL_RGB,GL_FLOAT,&v_data[0]);

glEnable(GL_TEXTURE_2D);
//glActiveTexture(GL_TEXTURE);

// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );

printf("programID: %u\n",programID);

// Get a handle for our buffers
GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");

printf("vertexPosition_modelspaceID: %u\n",vertexPosition_modelspaceID);

/*
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 0.7f, 0.0f,
};
*/

static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f, 0.0, 0.0,
1.0f, -1.0f, 0.0f, 1.0, 0.0,
0.0f, 0.7f, 0.0f, 0.0, 1.0,
};

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

// do{

// Clear the screen
glClear( GL_COLOR_BUFFER_BIT );

// Use our shader
glUseProgram(programID);

GLint myUniformLocation = glGetUniformLocation(programID, "myUniform");
glUniform3f(myUniformLocation, 1.0,0.0,0.0);

// 1rst attribute buffer : vertices
glEnableVertexAttribArray(vertexPosition_modelspac eID);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
/*
glVertexAttribPointer(
vertexPosition_modelspaceID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
*/
glVertexAttribPointer(
1, // attrib location of texture coords
2, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)(sizeof(float) * 3) // offset, texture coords begin after 3 floats (vertex position)
);

// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle

glDisableVertexAttribArray(vertexPosition_modelspa ceID);

while (!glfwWindowShouldClose(window))
{
/* Render here */
//draw_all();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}

// 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);
glDeleteProgram(programID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}


Vertex shader:


#version 120
// Input vertex data, different for all executions of this shader.
attribute vec3 vertexPosition_modelspace;

attribute vec2 in_texcoords;
out vec2 out_texcoords;


void main() {
gl_Position = vec4(vertexPosition_modelspace, 1.0);
out_texcoords = in_texcoords;
}

Fragment shader:


#version 120

uniform vec3 myUniform;

in vec2 out_texcoords;
uniform sampler2D tex;

void main()
{

// Output color = red
//gl_FragColor = vec4(myUniform,0,0,1);
//gl_FragColor = vec4(myUniform,1);
vec4 colorfromtexture = texture(tex, out_texcoords);
gl_FragColor = colorfromtexture;
}


What should i do? I think, parameters are not passed in glVertexAttribPointer() perfectly. And it tries to draw triangle not quad.


glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle

GClements
06-06-2016, 08:47 PM
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,bitm.width,0.0,bitm.height);


This does nothing, as you're using a vertex shader rather than the fixed-function pipeline.

Your vertex shader needs to explicitly transform the vertex position, either by gl_ProjectionMatrix or by a user-defined uniform variable (which you'll need to set, rather than using the legacy matrix functions).





glEnable(GL_TEXTURE_2D);


Again, this does nothing if you're using a fragment shader rather than the fixed-function pipeline.





glEnableVertexAttribArray(vertexPosition_modelspac eID);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
/*
glVertexAttribPointer(
vertexPosition_modelspaceID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
*/
glVertexAttribPointer(
1, // attrib location of texture coords
2, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)(sizeof(float) * 3) // offset, texture coords begin after 3 floats (vertex position)
);

// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle


You've commented out the call which specifies the position, which is the one attribute you really need. The call which specifies the texture coordinates is present, but you aren't bothering to query the attribute index (it isn't guaranteed to be 1) and you aren't enabling the attribute array. You need to call glGetAttribLocation(), glVertexAttribPointer() and glEnableVertexAttribArray() for both the position and the texture coordinates. glVertexAttribPointer() needs a stride of 5*sizeof(GLfloat) in both cases.

Also, you don't appear to be calling glGetError() anywhere, so you're missing out on the main source of information regarding any problems.

colagl
06-09-2016, 08:22 PM
I'm getting some error while running the program. And it's not drawing anything, it's white window.
Error:


Compiling shader : SimpleVertexShader.vertexshader
0:7(1): error: `out' qualifier in declaration of `out_texcoords' only valid for function parameters in GLSL 1.20

Compiling shader : SimpleFragmentShader.fragmentshader
0:6(1): error: `in' qualifier in declaration of `out_texcoords' only valid for function parameters in GLSL 1.20
0:15(26): error: no matching function for call to `texture(sampler2D, vec2)'; candidates are:

Linking program
error: linking with uncompiled shadererror: linking with uncompiled shader

Opengl version:


server glx version string: 1.4
client glx version string: 1.4
GLX version: 1.4
OpenGL version string: 2.1 Mesa 10.3.2
OpenGL shading language version string: 1.20
OpenGL ES profile version string: OpenGL ES 2.0 Mesa 10.3.2
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 1.0.16


Code:


#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;

#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>
#include<GLFW/glfw3.h>
#include<GL/glu.h>

typedef struct __attribute__((__packed__)) {
unsigned short type;
unsigned long size;
unsigned short reserved1;
unsigned short reserved2;
unsigned long offsetbits;
} BITMAPFILEHEADER1;

typedef struct __attribute__((__packed__)) {
unsigned long size;
unsigned long width;
unsigned long height;
unsigned short planes;
unsigned short bitcount;
unsigned long compression;
unsigned long sizeimage;
long xpelspermeter;
long ypelspermeter;
unsigned long colorsused;
unsigned long colorsimportant;
} BITMAPINFOHEADER1;

typedef struct {
unsigned char blue;
unsigned char green;
unsigned char red;
} SINGLE_PIXEL1;


GLFWwindow* window;

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 += "\n" + Line;
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", 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 += "\n" + Line;
FragmentShaderStream.close();
}

GLint Result = GL_FALSE;
int InfoLogLength;


// Compile Vertex Shader
printf("Compiling shader : %s\n", 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\n", &VertexShaderErrorMessage[0]);
}



// Compile Fragment Shader
printf("Compiling shader : %s\n", 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\n", &FragmentShaderErrorMessage[0]);
}



// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);

// 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\n", &ProgramErrorMessage[0]);
}


glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);

glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);

return ProgramID;
}


int main( void )
{
GLenum err;
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
return -1;
}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);


// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Tutorial 02 - Red triangle", 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.\n" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

// Initialize GLEW
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}

// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

FILE *fp;
unsigned char p;
int x=0,y=0,c=0;
float r,g,b;
float rowsize,pixelarraysize;

int datasize;

BITMAPFILEHEADER1 bitmp;
BITMAPINFOHEADER1 bitm;

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

fp = fopen("free.bmp","rb");//Filename is given

fread(&bitmp,14,1,fp);

fread(&bitm,40,1,fp);
/*
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,bitm.width,0.0,bitm.height);
glViewport(10,10,bitm.width,bitm.height);
*/

vector<float> v_data;
int width,height;

width=bitm.width;
height=bitm.height;

rowsize=((bitm.bitcount*bitm.width+31)/32)*4;
pixelarraysize=rowsize*bitm.height;
datasize=(bitm.bitcount/8.0)*bitm.width;

int padding;
padding = rowsize - (width * 3);
while(!feof(fp))
{
fread(&p,1,1,fp);
b = p/255.0;
fread(&p,1,1,fp);
g = p/255.0;
fread(&p,1,1,fp);
r = p/255.0;

v_data.push_back(r);
v_data.push_back(g);
v_data.push_back(b);
x++;
if(x == bitm.width)
{
fseek(fp,padding,SEEK_CUR);
x = 0;
y++;
}

}

unsigned int texture;

glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0 ,GL_RGB,GL_FLOAT,&v_data[0]);


glEnable(GL_TEXTURE_2D);
//glActiveTexture(GL_TEXTURE);

// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );

printf("programID: %u\n",programID);
err = glGetError();
printf("OpenGL error: %x\n",err);

// Get a handle for our buffers
GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");

printf("vertexPosition_modelspaceID: %u\n",vertexPosition_modelspaceID);

/*
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 0.7f, 0.0f,
};
*/

static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f, 0.0, 0.0,
1.0f, -1.0f, 0.0f, 1.0, 0.0,
0.0f, 0.7f, 0.0f, 0.0, 1.0,
//0.0f, 0.7f, 0.0f, 0.0, 1.0,
};

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

// do{

// Clear the screen
glClear( GL_COLOR_BUFFER_BIT );

// Use our shader
glUseProgram(programID);

GLint myUniformLocation = glGetUniformLocation(programID, "myUniform");
glUniform3f(myUniformLocation, 1.0,0.0,0.0);

// 1rst attribute buffer : vertices
glEnableVertexAttribArray(vertexPosition_modelspac eID);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
/*
glVertexAttribPointer(
vertexPosition_modelspaceID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
*/
glVertexAttribPointer(
1, // attrib location of texture coords
2, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)(sizeof(float) * 3) // offset, texture coords begin after 3 floats (vertex position)
);

// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle
//glDrawArrays(GL_QUADS, 0, 3); // 3 indices starting at 0 -> 1 triangle

glDisableVertexAttribArray(vertexPosition_modelspa ceID);

while (!glfwWindowShouldClose(window))
{
/* Render here */
//draw_all();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}

// 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);
glDeleteProgram(programID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}

Vertex shader:


#version 120
// Input vertex data, different for all executions of this shader.
attribute vec3 vertexPosition_modelspace;

attribute vec2 in_texcoords;
out vec2 out_texcoords;


void main() {
gl_Position = vec4(vertexPosition_modelspace, 1.0);
out_texcoords = in_texcoords;
}

Fragment shader:


#version 120

uniform vec3 myUniform;

in vec2 out_texcoords;
uniform sampler2D tex;

void main()
{

// Output color = red
//gl_FragColor = vec4(myUniform,0,0,1);
//gl_FragColor = vec4(myUniform,1);
vec4 colorfromtexture = texture(tex, out_texcoords);
gl_FragColor = colorfromtexture;
}


Can anyone correct the code and vertex and fragment shader and post it here?

Thanks.

GClements
06-09-2016, 08:49 PM
I'm getting some error while running the program. And it's not drawing anything, it's white window.

Your shaders are failing to compile, so any drawing operations using them will fail.





Compiling shader : SimpleVertexShader.vertexshader
0:7(1): error: `out' qualifier in declaration of `out_texcoords' only valid for function parameters in GLSL 1.20

Compiling shader : SimpleFragmentShader.fragmentshader
0:6(1): error: `in' qualifier in declaration of `out_texcoords' only valid for function parameters in GLSL 1.20


In both cases, you need to use "varying" for GLSL 1.20. Using "in" and "out" is only valid for GLSL 1.30 onward.





0:15(26): error: no matching function for call to `texture(sampler2D, vec2)'; candidates are:


In GLSL 1.20, you need to use texture2D(). The overloaded texture() function was added in GLSL 1.30.

colagl
06-09-2016, 09:27 PM
I've changed code. Now getting a triangle but i'm not getting the triangle-shaped image.
Code:


#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;

#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>
#include<GLFW/glfw3.h>
#include<GL/glu.h>

typedef struct __attribute__((__packed__)) {
unsigned short type;
unsigned long size;
unsigned short reserved1;
unsigned short reserved2;
unsigned long offsetbits;
} BITMAPFILEHEADER1;

typedef struct __attribute__((__packed__)) {
unsigned long size;
unsigned long width;
unsigned long height;
unsigned short planes;
unsigned short bitcount;
unsigned long compression;
unsigned long sizeimage;
long xpelspermeter;
long ypelspermeter;
unsigned long colorsused;
unsigned long colorsimportant;
} BITMAPINFOHEADER1;

typedef struct {
unsigned char blue;
unsigned char green;
unsigned char red;
} SINGLE_PIXEL1;


GLFWwindow* window;

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 += "\n" + Line;
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", 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 += "\n" + Line;
FragmentShaderStream.close();
}

GLint Result = GL_FALSE;
int InfoLogLength;


// Compile Vertex Shader
printf("Compiling shader : %s\n", 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\n", &VertexShaderErrorMessage[0]);
}



// Compile Fragment Shader
printf("Compiling shader : %s\n", 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\n", &FragmentShaderErrorMessage[0]);
}



// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);

// 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\n", &ProgramErrorMessage[0]);
}


glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);

glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);

return ProgramID;
}


int main( void )
{
GLenum err;
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
return -1;
}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Tutorial 02 - Red triangle", 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.\n" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

// Initialize GLEW
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

FILE *fp;
unsigned char p;
int x=0,y=0,c=0;
float r,g,b;
float rowsize,pixelarraysize;

int datasize;

BITMAPFILEHEADER1 bitmp;
BITMAPINFOHEADER1 bitm;

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

fp = fopen("free.bmp","rb");//Filename is given

fread(&bitmp,14,1,fp);

fread(&bitm,40,1,fp);
/*
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,bitm.width,0.0,bitm.height);
glViewport(10,10,bitm.width,bitm.height);
*/

vector<float> v_data;
int width,height;

width=bitm.width;
height=bitm.height;

rowsize=((bitm.bitcount*bitm.width+31)/32)*4;
pixelarraysize=rowsize*bitm.height;
datasize=(bitm.bitcount/8.0)*bitm.width;

int padding;
padding = rowsize - (width * 3);
while(!feof(fp))
{
fread(&p,1,1,fp);
b = p/255.0;
fread(&p,1,1,fp);
g = p/255.0;
fread(&p,1,1,fp);
r = p/255.0;

v_data.push_back(r);
v_data.push_back(g);
v_data.push_back(b);
x++;
if(x == bitm.width)
{
fseek(fp,padding,SEEK_CUR);
x = 0;
y++;
}

}
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0 ,GL_RGB,GL_FLOAT,&v_data[0]);
glEnable(GL_TEXTURE_2D);
//glActiveTexture(GL_TEXTURE);

// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
printf("programID: %u\n",programID);

// Get a handle for our buffers
GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");
printf("vertexPosition_modelspaceID: %u\n",vertexPosition_modelspaceID);
/*
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 0.7f, 0.0f,
};
*/
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f, 0.0, 0.0,
1.0f, -1.0f, 0.0f, 1.0, 0.0,
0.0f, 0.7f, 0.0f, 0.0, 1.0,
//0.0f, 0.7f, 0.0f, 0.0, 1.0,
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);


// do{
glClear( GL_COLOR_BUFFER_BIT );
glUseProgram(programID);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(vertexPosition_modelspac eID);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
/*
glVertexAttribPointer(
vertexPosition_modelspaceID, // The attribute we want to configure
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
*/
glVertexAttribPointer(
vertexPosition_modelspaceID, // attrib location of texture coords
3, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)(sizeof(float) * 3) // offset, texture coords begin after 3 floats (vertex position)
);
//err = glGetError();
//printf("OpenGL error: %x\n",err);
// Draw the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle

glDisableVertexAttribArray(vertexPosition_modelspa ceID);

while (!glfwWindowShouldClose(window))
{
/* Render here */
//draw_all();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}

// 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);
glDeleteProgram(programID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}

Vertex shader:


#version 120
// Input vertex data, different for all executions of this shader.
attribute vec3 vertexPosition_modelspace;

attribute vec2 in_texcoords;
//out vec2 out_texcoords;
varying vec2 out_texcoords;

void main() {
gl_Position = vec4(vertexPosition_modelspace, 1.0);
out_texcoords = in_texcoords;
}

Fragment shader:


#version 120

//in vec2 out_texcoords;
varying vec2 out_texcoords;
uniform sampler2D tex;

void main()
{
vec4 colorfromtexture = texture2D(tex, out_texcoords);
gl_FragColor = colorfromtexture;
}

Output:
http://imgur.com/yrtXH0Z

http://www43.zippyshare.com/v/yN62XZD0/file.html

What should i do to get triangle shaped bitmap image or the full image?

Thanks.

GClements
06-10-2016, 07:06 AM
I've changed code. Now getting a triangle but i'm not getting the triangle-shaped image.
You aren't providing texture coordinates (and you're using the texture coordinates as vertex coordinates).

As I said in my earlier post:


You need to call glGetAttribLocation(), glVertexAttribPointer() and glEnableVertexAttribArray() for both the position and the texture coordinates

colagl
06-10-2016, 08:10 AM
Thanks GClements. It looks that it works.
Here is the changed code:


#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;

#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>
#include<GLFW/glfw3.h>
#include<GL/glu.h>

typedef struct __attribute__((__packed__)) {
unsigned short type;
unsigned long size;
unsigned short reserved1;
unsigned short reserved2;
unsigned long offsetbits;
} BITMAPFILEHEADER1;

typedef struct __attribute__((__packed__)) {
unsigned long size;
unsigned long width;
unsigned long height;
unsigned short planes;
unsigned short bitcount;
unsigned long compression;
unsigned long sizeimage;
long xpelspermeter;
long ypelspermeter;
unsigned long colorsused;
unsigned long colorsimportant;
} BITMAPINFOHEADER1;

typedef struct {
unsigned char blue;
unsigned char green;
unsigned char red;
} SINGLE_PIXEL1;


GLFWwindow* window;

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 += "\n" + Line;
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", 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 += "\n" + Line;
FragmentShaderStream.close();
}

GLint Result = GL_FALSE;
int InfoLogLength;


// Compile Vertex Shader
printf("Compiling shader : %s\n", 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\n", &VertexShaderErrorMessage[0]);
}



// Compile Fragment Shader
printf("Compiling shader : %s\n", 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\n", &FragmentShaderErrorMessage[0]);
}



// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);

// 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\n", &ProgramErrorMessage[0]);
}


glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);

glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);

return ProgramID;
}


int main( void )
{
GLenum err;
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
return -1;
}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Tutorial 02 - Red triangle", 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.\n" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

// Initialize GLEW
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

FILE *fp;
unsigned char p;
int x=0,y=0,c=0;
float r,g,b;
float rowsize,pixelarraysize;

int datasize;

BITMAPFILEHEADER1 bitmp;
BITMAPINFOHEADER1 bitm;

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

fp = fopen("free.bmp","rb");//Filename is given

fread(&bitmp,14,1,fp);

fread(&bitm,40,1,fp);
/*
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,bitm.width,0.0,bitm.height);
glViewport(10,10,bitm.width,bitm.height);
*/

vector<float> v_data;
int width,height;

width=bitm.width;
height=bitm.height;

rowsize=((bitm.bitcount*bitm.width+31)/32)*4;
pixelarraysize=rowsize*bitm.height;
datasize=(bitm.bitcount/8.0)*bitm.width;

int padding;
padding = rowsize - (width * 3);
while(!feof(fp))
{
fread(&p,1,1,fp);
b = p/255.0;
fread(&p,1,1,fp);
g = p/255.0;
fread(&p,1,1,fp);
r = p/255.0;

v_data.push_back(r);
v_data.push_back(g);
v_data.push_back(b);
x++;
if(x == bitm.width)
{
fseek(fp,padding,SEEK_CUR);
x = 0;
y++;
}

}
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0 ,GL_RGB,GL_FLOAT,&v_data[0]);
glEnable(GL_TEXTURE_2D);
//glActiveTexture(GL_TEXTURE);

// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
printf("programID: %u\n",programID);

// Get a handle for our buffers
GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");
printf("vertexPosition_modelspaceID: %u\n",vertexPosition_modelspaceID);
GLuint in_texcoords = glGetAttribLocation(programID,"in_texcoords");

static const GLfloat g_vertex_buffer_data[] = {
-.9f, -.7f, 0.0f, 0.0, 0.0,
.9f, -.70f, 0.0f, 1.0, 0.0,
.9f, .7f, 0.0f, 1.0, 1.0,
-.9f, .7f, 0.0f, 0.0, 1.0
};
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

// do{
glClear( GL_COLOR_BUFFER_BIT );
glUseProgram(programID);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(vertexPosition_modelspac eID);
glEnableVertexAttribArray(in_texcoords);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
vertexPosition_modelspaceID, // attrib location of texture coords
3, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)0 // offset, texture coords begin after 3 floats (vertex position)
);
glVertexAttribPointer(
in_texcoords, // attrib location of texture coords
2, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)(sizeof(float)*3) // offset, texture coords begin after 3 floats (vertex position)
);
//glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle
glDrawArrays(GL_QUADS, 0, 4);
glDisableVertexAttribArray(vertexPosition_modelspa ceID);
glDisableVertexAttribArray(in_texcoords);

while (!glfwWindowShouldClose(window))
{
/* Render here */
//draw_all();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}

// 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);
glDeleteProgram(programID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}

Vertex shader:


#version 120
// Input vertex data, different for all executions of this shader.
attribute vec3 vertexPosition_modelspace;

attribute vec2 in_texcoords;
//out vec2 out_texcoords;
varying vec2 out_texcoords;

void main() {
gl_Position = vec4(vertexPosition_modelspace, 1.0);
out_texcoords = in_texcoords;
}

Fragment shader:


#version 120

//uniform vec3 myUniform;

//in vec2 out_texcoords;
varying vec2 out_texcoords;
uniform sampler2D tex;

void main()
{
vec4 colorfromtexture = texture2D(tex, out_texcoords);
gl_FragColor = colorfromtexture;
}

free.bmp = http://www3.zippyshare.com/v/WcDwm6pm/file.html
Output = http://www53.zippyshare.com/v/2VcnTp6X/file.html
Now do i have to change anything else in code?
Also how can i use this coordinate system like from the (0,0) to (width,height) of the image?


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,bitm.width,0.0,bitm.height);
glViewport(10,10,bitm.width,bitm.height);

The current coordinate system from (-1,-1) to (1,1) doesn't look good or not convenient.

GClements
06-10-2016, 08:51 AM
Thanks GClements. It looks that it works.
Also how can i use this coordinate system like from the (0,0) to (width,height) of the image?


glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,bitm.width,0.0,bitm.height);
glViewport(10,10,bitm.width,bitm.height);

The current coordinate system from (-1,-1) to (1,1) doesn't look good or not convenient.

The legacy OpenGL matrix functions only affect the fixed-function pipeline. They don't have any effect if you're using a vertex shader. Instead you need to create a uniform variable for the matrix, e.g.

Vertex shader:


#version 120

uniform mat4 proj_matrix;

attribute vec3 vertexPosition_modelspace;
attribute vec2 in_texcoords;
varying vec2 out_texcoords;

void main() {
gl_Position = proj_matrix * vec4(vertexPosition_modelspace, 1.0);
out_texcoords = in_texcoords;
}


Application code:


GLfloat proj_matrix[4][4] = {
{2.0/bitm.width, 0, 0, -1},
{0, 2.0/bitm.height, 0, -1},
{0, 0, -1, 0},
{0, 0, 0, 1}
};
GLint location = glGetUniformLocation(programID, "proj_matrix");
glUniformMatrix4fv(location, 1, GL_TRUE, &proj_matrix[0][0]);


You can find the matrices used by the legacy matrix functions from the OpenGL 2.1 reference pages (https://www.opengl.org/sdk/docs/man2/), e.g. for glOrtho (https://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml). Or you can use a library such as GLM to generate the matrices.

colagl
06-10-2016, 10:20 AM
What is fixed-function pipeline and fixed-function?
Why/how did you set matrix like that:


GLfloat proj_matrix[4][4] = {
{2.0/bitm.width, 0, 0, -1},
{0, 2.0/bitm.height, 0, -1},
{0, 0, -1, 0},
{0, 0, 0, 1}
};

Why 2.0/bitm.width and 2.0/bitm.height? And why 0,-1 and 0,-1 and -1,0 and 0,1 at last two column? How did you calculate these?
What are OpenGL matrix functions?

Instead you need to create a uniform variable for the matrix, e.g. Which matrix?
And what does this following code do?


gl_Position = proj_matrix * vec4(vertexPosition_modelspace, 1.0);


Is it possible to draw vertices? We draw triangles with "glDrawArrays(GL_TRIANGLES, 0, 3);" and rectangles with "glDrawArrays(GL_QUADS, 0, 4);"

If i use (-1,-1) to (1,1) coordinate system, then what is the difference between two vertices position? That means, how many vertices can be there in between (0,0) to (0,1) ?

That's why using coordinate system like (0,0) to (width,height) is easier because we can increment one to get the next vertex position. For example: (0,0), (0,1), (0,2), (0,3) and so on.In this way what will be the next vertex position in (-1,-1) to (1,1) coordinate system?

If i use vertex shader how can i convert the (-1,-1) to (1,1) coordinate system to (0,0) to (width,height) coordinate system?

Thanks.

john_connor
06-10-2016, 11:33 AM
What is fixed-function pipeline and fixed-function?

fixed-function means that you (the developer) cant modify the way the graphics is calculated
it is relatiivley outdated, in "modern openGL" you use shaders (small programs on the gpu) that process all the vertices/data, and those shaders aren't "fixed" in any way/shape/form




Why/how did you set matrix like that:


GLfloat proj_matrix[4][4] = {
{2.0/bitm.width, 0, 0, -1},
{0, 2.0/bitm.height, 0, -1},
{0, 0, -1, 0},
{0, 0, 0, 1}
};

Why 2.0/bitm.width and 2.0/bitm.height? And why 0,-1 and 0,-1 and -1,0 and 0,1 at last two column? How did you calculate these?
What are OpenGL matrix functions?
Which matrix?
And what does this following code do?


gl_Position = proj_matrix * vec4(vertexPosition_modelspace, 1.0);



by multiplying a vertex with such a (transformation) matrix, you "put" that verex into another "space"
or more explicit: you transform that vertex into another coordinate system
http://www.songho.ca/opengl/gl_transform.html



Is it possible to draw vertices? We draw triangles with "glDrawArrays(GL_TRIANGLES, 0, 3);" and rectangles with "glDrawArrays(GL_QUADS, 0, 4);"

If i use (-1,-1) to (1,1) coordinate system, then what is the difference between two vertices position? That means, how many vertices can be there in between (0,0) to (0,1) ?


a "vertex" is just a data point, it has a position (1D, 2D or 3D, .. doesnt matter)
in addition to its position, it can contain some further information, e.g. some texture coordinates or color values etc
vertices (= multiple vertex) are described in "local space"
to put a model in a world/room/scene/location you want to draw, you have to transform all its vertices with a "model matrix"
that puts that model (triangle or what have you ..) in that "world"
to be able to see that world from a view point (e.g. "camera"), you have to multiply the result of the former transformation ("model matrix") with an additional matrix, called "view matrix"
last but not least, IF you want your scene to look like "real 3D", you have to multiply all the former stuff with a matrix called "projection matrix", a.k.a "perspective"
now, your triangle appears on your screen in a 3D space
fortunately, you can simplify those 3 transformation into 1 step
http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/
of course, you dont have to implement all the math behind the scenes yourself, GLM has already everything you need therefore
http://glm.g-truc.net/0.9.7/index.html

GClements
06-10-2016, 11:46 AM
What is fixed-function pipeline and fixed-function?
The fixed-function pipeline is what is used if no shader program is used. It behaves like a generic, relatively complex shader program which is controlled by a large number of variables. Fixed-function vertex processing includes transforming vertex coordinates by the current model-view and projection matrices, calculating vertex colours via lighting (if enabled), and generation of texture coordinates (if enabled, see glTexGen). Fixed-function fragment processing includes texturing (if enabled; see glTexEnv), alpha testing and fog.

Most of the functions which exist in OpenGL 2.1 (http://www.opengl.org/sdk/docs/man2/) but not in OpenGL 4 (http://www.opengl.org/sdk/docs/man4/) control the fixed-function pipeline, and aren't relevant when shaders are used. That includes the matrix functions.



Why/how did you set matrix like that:

That's the matrix which glOrtho (https://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml) would create



What are OpenGL matrix functions?

Anything which modifies the current matrix as set by glMatrixMode(). That includes glLoadIdentity, glLoadMatrix, glMultMatrix, glPushMatrix, glPopMatrix, glTranslate, glScale, glRotate, glOrtho, and glFrustum, as well as the GLU functions gluPerspective and gluOrtho2D (which just call glFrustum or glOrtho respectively) and gluPickMatrix.



And what does this following code do?


gl_Position = proj_matrix * vec4(vertexPosition_modelspace, 1.0);


It transforms the vertex position by the projection matrix. In the fixed-function pipeline, vertex positions are automatically transformed by the model-view and projection matrices. If you use a vertex shader, it has to perform such transformations explicitly.



Is it possible to draw vertices? We draw triangles with "glDrawArrays(GL_TRIANGLES, 0, 3);" and rectangles with "glDrawArrays(GL_QUADS, 0, 4);"

You can draw points using GL_POINTS.



If i use (-1,-1) to (1,1) coordinate system, then what is the difference between two vertices position? That means, how many vertices can be there in between (0,0) to (0,1) ?

As many as you like. Coordinates aren't restricted to integers.

colagl
06-10-2016, 10:47 PM
The legacy OpenGL matrix functions only affect the fixed-function pipeline. They don't have any effect if you're using a vertex shader. Instead you need to create a uniform variable for the matrix, e.g.

Vertex shader:


#version 120

uniform mat4 proj_matrix;

attribute vec3 vertexPosition_modelspace;
attribute vec2 in_texcoords;
varying vec2 out_texcoords;

void main() {
gl_Position = proj_matrix * vec4(vertexPosition_modelspace, 1.0);
out_texcoords = in_texcoords;
}


Application code:


GLfloat proj_matrix[4][4] = {
{2.0/bitm.width, 0, 0, -1},
{0, 2.0/bitm.height, 0, -1},
{0, 0, -1, 0},
{0, 0, 0, 1}
};
GLint location = glGetUniformLocation(programID, "proj_matrix");
glUniformMatrix4fv(location, 1, GL_TRUE, &proj_matrix[0][0]);


You can find the matrices used by the legacy matrix functions from the OpenGL 2.1 reference pages (https://www.opengl.org/sdk/docs/man2/), e.g. for glOrtho (https://www.opengl.org/sdk/docs/man2/xhtml/glOrtho.xml). Or you can use a library such as GLM to generate the matrices.
I've changed the code adding "proj_matrix", but this time it doesn't draw anything. It's white window.
Code:


#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;

#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>
#include<GLFW/glfw3.h>
#include<GL/glu.h>

typedef struct __attribute__((__packed__)) {
unsigned short type;
unsigned long size;
unsigned short reserved1;
unsigned short reserved2;
unsigned long offsetbits;
} BITMAPFILEHEADER1;

typedef struct __attribute__((__packed__)) {
unsigned long size;
unsigned long width;
unsigned long height;
unsigned short planes;
unsigned short bitcount;
unsigned long compression;
unsigned long sizeimage;
long xpelspermeter;
long ypelspermeter;
unsigned long colorsused;
unsigned long colorsimportant;
} BITMAPINFOHEADER1;

typedef struct {
unsigned char blue;
unsigned char green;
unsigned char red;
} SINGLE_PIXEL1;


GLFWwindow* window;

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 += "\n" + Line;
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", 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 += "\n" + Line;
FragmentShaderStream.close();
}

GLint Result = GL_FALSE;
int InfoLogLength;


// Compile Vertex Shader
printf("Compiling shader : %s\n", 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\n", &VertexShaderErrorMessage[0]);
}



// Compile Fragment Shader
printf("Compiling shader : %s\n", 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\n", &FragmentShaderErrorMessage[0]);
}



// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);

// 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\n", &ProgramErrorMessage[0]);
}


glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);

glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);

return ProgramID;
}


int main( void )
{
GLenum err;
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
return -1;
}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Tutorial 02 - Red triangle", 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.\n" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

// Initialize GLEW
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

FILE *fp;
unsigned char p;
int x=0,y=0,c=0;
float r,g,b;
float rowsize,pixelarraysize;

int datasize;

BITMAPFILEHEADER1 bitmp;
BITMAPINFOHEADER1 bitm;

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

fp = fopen("free2.bmp","rb");//Filename is given

fread(&bitmp,14,1,fp);

fread(&bitm,40,1,fp);
/*
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,bitm.width,0.0,bitm.height);
glViewport(10,10,bitm.width,bitm.height);
*/

vector<float> v_data;
int width,height;

width=bitm.width;
height=bitm.height;

rowsize=((bitm.bitcount*bitm.width+31)/32)*4;
pixelarraysize=rowsize*bitm.height;
datasize=(bitm.bitcount/8.0)*bitm.width;

int padding;
padding = rowsize - (width * 3);
while(!feof(fp))
{
fread(&p,1,1,fp);
b = p/255.0;
fread(&p,1,1,fp);
g = p/255.0;
fread(&p,1,1,fp);
r = p/255.0;

v_data.push_back(r);
v_data.push_back(g);
v_data.push_back(b);
x++;
if(x == bitm.width)
{
fseek(fp,padding,SEEK_CUR);
x = 0;
y++;
}

}
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0 ,GL_RGB,GL_FLOAT,&v_data[0]);
glEnable(GL_TEXTURE_2D);
//glActiveTexture(GL_TEXTURE);

static const GLfloat g_vertex_buffer_data[] = {
-.7f, -.7f, 0.0f, 0.0, 0.0,
.7f, -.70f, 0.0f, 1.0, 0.0,
.7f, .7f, 0.0f, 1.0, 1.0,
-.7f, .7f, 0.0f, 0.0, 1.0
};

/*
static const GLfloat g_vertex_buffer_data[] = {
0.0f, 0.0f, 0.0f, 0.0, 0.0,
100.0f, 0.0f, 0.0f, 1.0, 0.0,
100.0f, 100.0f, 0.0f, 1.0, 1.0,
0.0f, 100.0f, 0.0f, 0.0, 1.0
};
*/

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

GLfloat proj_matrix[4][4] = {
{2.0/bitm.width, 0, 0, -1},
{0, 2.0/bitm.height, 0, -1},
{0, 0, -1, 0},
{0, 0, 0, 1}
};

GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");
GLuint in_texcoords = glGetAttribLocation(programID,"in_texcoords");

GLint location = glGetUniformLocation(programID, "proj_matrix");
glUniformMatrix4fv(location, 1, GL_TRUE, &proj_matrix[0][0]);

// do{
glClear( GL_COLOR_BUFFER_BIT );
glUseProgram(programID);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(vertexPosition_modelspac eID);
glEnableVertexAttribArray(in_texcoords);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
vertexPosition_modelspaceID, // attrib location of texture coords
3, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)0 // offset, texture coords begin after 3 floats (vertex position)
);
glVertexAttribPointer(
in_texcoords, // attrib location of texture coords
2, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)(sizeof(float)*3) // offset, texture coords begin after 3 floats (vertex position)
);
//glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle
glDrawArrays(GL_QUADS, 0, 4);
glDisableVertexAttribArray(vertexPosition_modelspa ceID);
glDisableVertexAttribArray(in_texcoords);

while (!glfwWindowShouldClose(window))
{
/* Render here */
//draw_all();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}

// 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);
glDeleteProgram(programID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}

Vertex shader:


#version 120
// Input vertex data, different for all executions of this shader.
attribute vec3 vertexPosition_modelspace;

attribute vec2 in_texcoords;
//out vec2 out_texcoords;
varying vec2 out_texcoords;

uniform mat4 proj_matrix;

void main() {
//gl_Position = vec4(vertexPosition_modelspace, 1.0);
gl_Position = proj_matrix * vec4(vertexPosition_modelspace, 1.0);
out_texcoords = in_texcoords;
}

Fragment shader:


#version 120

//uniform vec3 myUniform;

//in vec2 out_texcoords;
varying vec2 out_texcoords;
uniform sampler2D tex;

void main()
{
vec4 colorfromtexture = texture2D(tex, out_texcoords);
gl_FragColor = colorfromtexture;
}

Do i have to change the value of "static const GLfloat g_vertex_buffer_data[]"? Is the "GLfloat proj_matrix[4][4]" correct?

Thanks.

GClements
06-10-2016, 11:12 PM
I've changed the code adding "proj_matrix", but this time it doesn't draw anything. It's white window.



Do i have to change the value of "static const GLfloat g_vertex_buffer_data[]"?

You need to use the version which is currently commented. Adding the proj_matrix transformation means that the coordinate system is (0,0) to (bitm.width,bitm.height) rather than (-1,-1) to (1,1), so the version with .7f is creating a quad 1.5 pixels across in the bottom-left corner (and three quarters of it will be outside the viewport).

One other point: you need to call glUseProgram(programID) before calling glUniformMatrix4fv(). The latter sets a uniform variable in the current program, so the program must be current when you call it.

colagl
06-11-2016, 12:03 AM
You need to use the version which is currently commented. Adding the proj_matrix transformation means that the coordinate system is (0,0) to (bitm.width,bitm.height) rather than (-1,-1) to (1,1), so the version with .7f is creating a quad 1.5 pixels across in the bottom-left corner (and three quarters of it will be outside the viewport).

One other point: you need to call glUseProgram(programID) before calling glUniformMatrix4fv(). The latter sets a uniform variable in the current program, so the program must be current when you call it.
Which version are you talking about?
This time I've used this vertex buffer:


static const GLfloat g_vertex_buffer_data[] = {
0.0f, 0.0f, 0.0f, 0.0, 0.0,
100.0f, 0.0f, 0.0f, 1.0, 0.0,
100.0f, 100.0f, 0.0f, 1.0, 1.0,
0.0f, 100.0f, 0.0f, 0.0, 1.0
};

And changed this:


GLint location = glGetUniformLocation(programID, "proj_matrix");
glUseProgram(programID);
glUniformMatrix4fv(location, 1, GL_TRUE, &proj_matrix[0][0]);

It still doesn't draw anything, it's white window. Is it a problem with "GLfloat proj_matrix[4][4]" ?

https://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml
Here for glUniformMatrix4fv, transpose parameter must be GL_FALSE, I tried with this, still not getting expected result.


transpose Specifies whether to transpose the matrix as the values are loaded into the uniform variable. Must be GL_FALSE.

Full code:


#include <stdio.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;

#include <stdlib.h>
#include <string.h>

#include <GL/glew.h>
#include<GLFW/glfw3.h>
#include<GL/glu.h>

typedef struct __attribute__((__packed__)) {
unsigned short type;
unsigned long size;
unsigned short reserved1;
unsigned short reserved2;
unsigned long offsetbits;
} BITMAPFILEHEADER1;

typedef struct __attribute__((__packed__)) {
unsigned long size;
unsigned long width;
unsigned long height;
unsigned short planes;
unsigned short bitcount;
unsigned long compression;
unsigned long sizeimage;
long xpelspermeter;
long ypelspermeter;
unsigned long colorsused;
unsigned long colorsimportant;
} BITMAPINFOHEADER1;

typedef struct {
unsigned char blue;
unsigned char green;
unsigned char red;
} SINGLE_PIXEL1;


GLFWwindow* window;

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 += "\n" + Line;
VertexShaderStream.close();
}else{
printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", 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 += "\n" + Line;
FragmentShaderStream.close();
}

GLint Result = GL_FALSE;
int InfoLogLength;


// Compile Vertex Shader
printf("Compiling shader : %s\n", 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\n", &VertexShaderErrorMessage[0]);
}



// Compile Fragment Shader
printf("Compiling shader : %s\n", 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\n", &FragmentShaderErrorMessage[0]);
}



// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);

// 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\n", &ProgramErrorMessage[0]);
}


glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);

glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);

return ProgramID;
}


int main( void )
{
GLenum err;
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
getchar();
return -1;
}

glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);

// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Tutorial 02 - Red triangle", 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.\n" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);

// Initialize GLEW
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
getchar();
glfwTerminate();
return -1;
}
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);

FILE *fp;
unsigned char p;
int x=0,y=0,c=0;
float r,g,b;
float rowsize,pixelarraysize;

int datasize;

BITMAPFILEHEADER1 bitmp;
BITMAPINFOHEADER1 bitm;

glClearColor(1.0,1.0,1.0,0.0);

glClear(GL_COLOR_BUFFER_BIT);

fp = fopen("free2.bmp","rb");//Filename is given

fread(&bitmp,14,1,fp);

fread(&bitm,40,1,fp);
/*
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0.0,bitm.width,0.0,bitm.height);
glViewport(10,10,bitm.width,bitm.height);
*/

vector<float> v_data;
int width,height;

width=bitm.width;
height=bitm.height;

rowsize=((bitm.bitcount*bitm.width+31)/32)*4;
pixelarraysize=rowsize*bitm.height;
datasize=(bitm.bitcount/8.0)*bitm.width;

int padding;
padding = rowsize - (width * 3);
while(!feof(fp))
{
fread(&p,1,1,fp);
b = p/255.0;
fread(&p,1,1,fp);
g = p/255.0;
fread(&p,1,1,fp);
r = p/255.0;

v_data.push_back(r);
v_data.push_back(g);
v_data.push_back(b);
x++;
if(x == bitm.width)
{
fseek(fp,padding,SEEK_CUR);
x = 0;
y++;
}

}
unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,width,height,0 ,GL_RGB,GL_FLOAT,&v_data[0]);
glEnable(GL_TEXTURE_2D);
//glActiveTexture(GL_TEXTURE);
/*
static const GLfloat g_vertex_buffer_data[] = {
-.7f, -.7f, 0.0f, 0.0, 0.0,
.7f, -.70f, 0.0f, 1.0, 0.0,
.7f, .7f, 0.0f, 1.0, 1.0,
-.7f, .7f, 0.0f, 0.0, 1.0
};
*/

static const GLfloat g_vertex_buffer_data[] = {
0.0f, 0.0f, 0.0f, 0.0, 0.0,
100.0f, 0.0f, 0.0f, 1.0, 0.0,
100.0f, 100.0f, 0.0f, 1.0, 1.0,
0.0f, 100.0f, 0.0f, 0.0, 1.0
};

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

GLfloat proj_matrix[4][4] = {
{2.0/bitm.width, 0, 0, -1},
{0, 2.0/bitm.height, 0, -1},
{0, 0, -1, 0},
{0, 0, 0, 1}
};

GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");
GLuint in_texcoords = glGetAttribLocation(programID,"in_texcoords");

GLint location = glGetUniformLocation(programID, "proj_matrix");
glUseProgram(programID);
glUniformMatrix4fv(location, 1, GL_TRUE, &proj_matrix[0][0]);

// do{
glClear( GL_COLOR_BUFFER_BIT );
glUseProgram(programID);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(vertexPosition_modelspac eID);
glEnableVertexAttribArray(in_texcoords);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
vertexPosition_modelspaceID, // attrib location of texture coords
3, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)0 // offset, texture coords begin after 3 floats (vertex position)
);
glVertexAttribPointer(
in_texcoords, // attrib location of texture coords
2, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)(sizeof(float)*3) // offset, texture coords begin after 3 floats (vertex position)
);
//glDrawArrays(GL_TRIANGLES, 0, 3); // 3 indices starting at 0 -> 1 triangle
glDrawArrays(GL_QUADS, 0, 4);
glDisableVertexAttribArray(vertexPosition_modelspa ceID);
glDisableVertexAttribArray(in_texcoords);

while (!glfwWindowShouldClose(window))
{
/* Render here */
//draw_all();
/* Swap front and back buffers */
glfwSwapBuffers(window);
/* Poll for and process events */
glfwPollEvents();
}

// 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);
glDeleteProgram(programID);

// Close OpenGL window and terminate GLFW
glfwTerminate();

return 0;
}

Vertex shader:


#version 120
// Input vertex data, different for all executions of this shader.
attribute vec3 vertexPosition_modelspace;

attribute vec2 in_texcoords;
//out vec2 out_texcoords;
varying vec2 out_texcoords;

uniform mat4 proj_matrix;

void main() {
//gl_Position = vec4(vertexPosition_modelspace, 1.0);
gl_Position = proj_matrix * vec4(vertexPosition_modelspace, 1.0);
out_texcoords = in_texcoords;
}

Fragment shader:


#version 120

//uniform vec3 myUniform;

//in vec2 out_texcoords;
varying vec2 out_texcoords;
uniform sampler2D tex;

void main()
{
vec4 colorfromtexture = texture2D(tex, out_texcoords);
gl_FragColor = colorfromtexture;
}

john_connor
06-11-2016, 02:52 AM
check this out:







#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include <fstream>
#include <string>


std::string LoadTextFile(const std::string& path)
{
std::string result, line;

std::fstream f(path, std::ios::in);
if (f.is_open())
{
while (!f.eof())
{
std::getline(f, line);
result += line + "\n";
}
f.close();
}

return result;
}


GLuint LoadShaders(const std::string& vertex_file_path, const std::string& fragment_file_path) {

std::string VertexShaderCode = LoadTextFile(vertex_file_path);
std::string FragmentShaderCode = LoadTextFile(fragment_file_path);

if (VertexShaderCode.empty() || FragmentShaderCode.empty())
{
std::cout << "error while reading shader source" << std::endl;
std::cin.get();
return 0;
}


GLint Result = GL_FALSE;
int InfoLogLength;

// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

// Compile Vertex Shader
printf("Compiling shader : %s\n", 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) {
char buffer[1024];
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, buffer);
std::cout << buffer << std::endl;
}



// Compile Fragment Shader
printf("Compiling shader : %s\n", 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) {
char buffer[1024];
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, buffer);
std::cout << buffer << std::endl;
}



// Link the program
printf("Linking program\n");
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);

// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) {
char buffer[1024];
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, buffer);
std::cout << buffer << std::endl;
}


glDetachShader(ProgramID, VertexShaderID);
glDetachShader(ProgramID, FragmentShaderID);

glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);

return ProgramID;
}


int main(void)
{
/* Initialize the library */
if (!glfwInit())
return -1;

/* Create a windowed mode window and its OpenGL context */
GLFWwindow* window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
if (!window)
{
glfwTerminate();
return -1;
}

/* Make the window's context current */
glfwMakeContextCurrent(window);

// init opengl
if (glewInit() != GLEW_OK)
{
glfwTerminate();
return -2;
}

glfwSetWindowTitle(window, (char*)glGetString(GL_VERSION));

//----------------------------------------------------------------

GLuint program = LoadShaders("vertexshader.txt", "fragmentshader.txt");

const GLfloat g_vertex_buffer_data[] = {
0.0f, 0.0f, 0.0f, 0.0, 0.0,
100.0f, 0.0f, 0.0f, 1.0, 0.0,
100.0f, 100.0f, 0.0f, 1.0, 1.0,
0.0f, 100.0f, 0.0f, 0.0, 1.0
};

GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
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, 0);

unsigned int vertexPosition_modelspaceID = 0;
unsigned int in_texcoords = 1;

const unsigned int width(200), height(100);
struct pixel { float r, g, b; } texturedata[width][height];

for (unsigned int w = 0; w < width; w++)
{
for (unsigned int h = 0; h < height; h++)
{
texturedata[w][h].r = w > 50 ? 1.0f : 0.0f;
texturedata[w][h].g = h > 50 ? 1.0f : 0.0f;
texturedata[w][h].b = 0;
}
}

GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_FLOAT, texturedata);
glBindTexture(GL_TEXTURE_2D, 0);

const GLfloat proj_matrix[4][4] = {
{ 2.0 / width, 0, 0, -1 },
{ 0, 2.0 / height, 0, -1 },
{ 0, 0, -1, 0 },
{ 0, 0, 0, 1 }
};

//----------------------------------------------------------------

/* Loop until the user closes the window */
while (!glfwWindowShouldClose(window))
{
/* Render here */
//----------------------------------------------------------------
glClearColor(0, 0, 1, 0);
glClear(GL_COLOR_BUFFER_BIT);

glUseProgram(program); // turn on

// set uniform matrix
glUniformMatrix4fv(glGetUniformLocation(program, "proj_matrix"), 1, false, &proj_matrix[0][0]);

glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
vertexPosition_modelspaceID, // attrib location of texture coords
3, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)0 // offset, texture coords begin after 3 floats (vertex position)
);
glVertexAttribPointer(
in_texcoords, // attrib location of texture coords
2, // it has 2 components
GL_FLOAT, // both are float
GL_FALSE, // normalized? no ..
(sizeof(float) * 5), // stride,
(void*)(sizeof(float) * 3) // offset, texture coords begin after 3 floats (vertex position)
);

glEnableVertexAttribArray(vertexPosition_modelspac eID);
glEnableVertexAttribArray(in_texcoords);

glBindTexture(GL_TEXTURE_2D, texture);

glDrawArrays(GL_QUADS, 0, 4);

glBindTexture(GL_TEXTURE_2D, 0);

glDisableVertexAttribArray(vertexPosition_modelspa ceID);
glDisableVertexAttribArray(in_texcoords);

glUseProgram(0); // turn off

//----------------------------------------------------------------

/* Swap front and back buffers */
glfwSwapBuffers(window);

/* Poll for and process events */
glfwPollEvents();
}

glfwTerminate();
return 0;
}


vertexshader


#version 120

attribute vec3 vertexPosition_modelspace;
attribute vec2 in_texcoords;

varying vec2 out_texcoords;

uniform mat4 proj_matrix;

void main() {
gl_Position = proj_matrix * vec4(vertexPosition_modelspace, 1.0);
out_texcoords = in_texcoords;
}


fragmentshader


#version 120

varying vec2 out_texcoords;
uniform sampler2D tex;

void main()
{
vec3 colorfromtexture = texture2D(tex, out_texcoords).rgb;
gl_FragColor = vec4(colorfromtexture, 1);
}

GClements
06-11-2016, 09:29 AM
https://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml
Here for glUniformMatrix4fv, transpose parameter must be GL_FALSE, I tried with this, still not getting expected result.

For the matrix I gave, transpose must be GL_TRUE. OpenGL uses column-major order, C uses row-major order. So it's necessary to transpose the matrix, either in its definition in the code (which affects legibility, as the matrix in the code no longer resembles what you'll find in a textbook or the reference page), or when calling glUniformMatrix().