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 += "
" + 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);
// 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( void )
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW
" );
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.
" );
getchar();
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW
");
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
",programID);
// Get a handle for our buffers
GLuint vertexPosition_modelspaceID = glGetAttribLocation(programID, "vertexPosition_modelspace");
printf("vertexPosition_modelspaceID: %u
",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_modelspaceID);
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_modelspaceID);
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: 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.