I'm following this tutorial for shading in opengl. However I wanted to start with another shader to make things more interesting
So this gives me the following code:
// Include standard headers
#include <stdio.h>
#include <stdlib.h>
#include <vector>
// Include GLEW
#include <GL/glew.h>
// Include GLFW
#include <glfw3.h>
GLFWwindow* window;
// Include GLM
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
using namespace glm;
#include <common/shader.hpp>
#include <common/texture.hpp>
#include <common/controls.hpp>
#include <common/objloader.hpp>
#include <common/vboindexer.hpp>
int main( void )
{
// Initialise GLFW
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
return -1;
}
glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Open a window and create its OpenGL context
window = glfwCreateWindow( 1024, 768, "Tutorial 08 - Basic Shading", 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" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window);
// Initialize GLEW
glewExperimental = true; // Needed for core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
glfwSetCursorPos(window, 1024/2, 768/2);
// Dark blue background
glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
// Enable depth test
glEnable(GL_DEPTH_TEST);
// Accept fragment if it closer to the camera than the former one
glDepthFunc(GL_LESS);
// Cull triangles which normal is not towards the camera
glEnable(GL_CULL_FACE);
GLuint VertexArrayID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
// Create and compile our GLSL program from the shaders
GLuint programID = LoadShaders( "StandardShading.vertexshader", "StandardShading.fragmentshader" );
// Get a handle for our "MVP" uniform
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
GLuint ViewMatrixID = glGetUniformLocation(programID, "V");
GLuint ModelMatrixID = glGetUniformLocation(programID, "M");
// Load the texture
GLuint Texture = loadDDS("uvmap.DDS");
// Get a handle for our "myTextureSampler" uniform
GLuint TextureID = glGetUniformLocation(programID, "myTextureSampler");
// Read our .obj file
std::vector<glm::vec3> vertices;
std::vector<glm::vec2> uvs;
std::vector<glm::vec3> normals;
bool res = loadOBJ("suzanne.obj", vertices, uvs, normals);
// Load it into a VBO
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(glm::vec3), &vertices[0], GL_STATIC_DRAW);
GLuint uvbuffer;
glGenBuffers(1, &uvbuffer);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(glm::vec2), &uvs[0], GL_STATIC_DRAW);
GLuint normalbuffer;
glGenBuffers(1, &normalbuffer);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(glm::vec3), &normals[0], GL_STATIC_DRAW);
// Get a handle for our "LightPosition" uniform
glUseProgram(programID);
GLuint LightID = glGetUniformLocation(programID, "LightPosition_worldspace");
do{
// Clear the screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use our shader
glUseProgram(programID);
// Compute the MVP matrix from keyboard and mouse input
computeMatricesFromInputs();
glm::mat4 ProjectionMatrix = getProjectionMatrix();
glm::mat4 ViewMatrix = getViewMatrix();
glm::mat4 ModelMatrix = glm::mat4(1.0);
glm::mat4 MVP = ProjectionMatrix * ViewMatrix * ModelMatrix;
// Send our transformation to the currently bound shader,
// in the "MVP" uniform
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &ModelMatrix[0][0]);
glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &ViewMatrix[0][0]);
glm::vec3 lightPos = glm::vec3(4,4,4);
glUniform3f(LightID, lightPos.x, lightPos.y, lightPos.z);
// Bind our texture in Texture Unit 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Texture);
// Set our "myTextureSampler" sampler to user Texture Unit 0
glUniform1i(TextureID, 0);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 2nd attribute buffer : UVs
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, uvbuffer);
glVertexAttribPointer(
1, // attribute
2, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// 3rd attribute buffer : normals
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, normalbuffer);
glVertexAttribPointer(
2, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// Draw the triangles !
glDrawArrays(GL_TRIANGLES, 0, vertices.size() );
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
// 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 and shader
glDeleteBuffers(1, &vertexbuffer);
glDeleteBuffers(1, &uvbuffer);
glDeleteBuffers(1, &normalbuffer);
glDeleteProgram(programID);
glDeleteTextures(1, &Texture);
glDeleteVertexArrays(1, &VertexArrayID);
// Close OpenGL window and terminate GLFW
glfwTerminate();
return 0;
}
and the shader
/*
* Bo Sun, Columbia University, All rights reserved
* --------------------------------------------------------------------
* Permission to use, copy, or modify this software and its documentation
* for educational and research purposes only and without fee is hereby
* granted.
* --------------------------------------------------------------------
*
* March. 2005
*/
struct frag2app {
float4 color : COLOR;
};
/*auxiliary functions*/
float A0(float I0, float beta, float Dsv, float gamma)
{
const float PI = 3.1415926535;
return (beta*I0*exp(-beta*Dsv*cos(gamma)))/(2*PI*Dsv*sin(gamma));
}
float A1(float beta, float Dsv, float gamma)
{
return beta*Dsv*sin(gamma);
}
/*functions to compute each radiance component seperately*/
float AirLight(float lightIntensity,
float beta,
float Dsv,
float Dvp,
float gammasv,
samplerRECT F,
float f_XOffset,
float f_XScale,
float f_YOffset,
float f_YScale)
{
const float PI = 3.1415926535;
float u = A1(beta, Dsv, gammasv);
float v1 = 0.25*PI+0.5*atan((Dvp-Dsv*cos(gammasv))/(Dsv*sin(gammasv)));
float v2 = 0.5*gammasv;
float4 f_1=texRECT(F, float2((v1-f_XOffset)*f_XScale, (u-f_YOffset)*f_YScale));
float4 f_2=texRECT(F, float2((v2-f_XOffset)*f_XScale, (u-f_YOffset)*f_YScale));
return A0(lightIntensity, beta, Dsv, gammasv)*(f_1.x-f_2.x);
}
float Diffuse(float lightIntensity,
float beta,
float Kd,
float Dsp,
float Dvp,
float thetas,
samplerRECT G_0,
float g_0XOffset,
float g_0XScale,
float g_0YOffset,
float g_0YScale)
{
const float PI = 3.1415926535;
float t1 = exp(-beta*Dsp)*max(cos(thetas),0)/Dsp;
float4 t2 = beta*texRECT(G_0, float2((beta*Dsp-g_0XOffset)*g_0XScale, (thetas-g_0YOffset)*g_0YScale))/(2*PI);
return (t1+t2.x)*exp(-beta*Dvp)*Kd*lightIntensity/Dsp;
}
float Specular(float lightIntensity,
float beta,
float Ks,
float Dsp,
float Dvp,
float thetas_,
samplerRECT G_20,
float g_20XOffset,
float g_20XScale,
float g_20YOffset,
float g_20YScale)
{
const float PI=3.1415926535;
float t1 = exp(-beta*Dsp)*pow(max(cos(thetas_),0),20)/Dsp;
float4 t2 = beta*texRECT(G_20, float2((beta*Dsp-g_20XOffset)*g_20XScale, (thetas_-g_20YOffset)*g_20YScale))/(2*PI);
return (t1+t2.x)*exp(-beta*Dvp)*Ks*lightIntensity/Dsp;
}
/*main function*/
frag2app fmain( float4 objPos : TEXCOORD3,
float3 normal : TEXCOORD4,
float4 color : COLOR,
uniform float3 lightPosition,
uniform float3 viewPosition,
uniform float lightIntensity,
uniform float beta,
uniform float Kd,
uniform float Ks,
uniform samplerRECT F,
uniform float f_XOffset,
uniform float f_XScale,
uniform float f_YOffset,
uniform float f_YScale,
uniform samplerRECT G_0,
uniform float g_0XOffset,
uniform float g_0XScale,
uniform float g_0YOffset,
uniform float g_0YScale,
uniform samplerRECT G_20,
uniform float g_20XOffset,
uniform float g_20XScale,
uniform float g_20YOffset,
uniform float g_20YScale)
{
beta=4;
frag2app OUT;
const float PI = 3.1415926535;
/*preparing parameters*/
float3 N = normalize(normal);
float3 V = normalize(objPos.xyz-viewPosition);
float3 S = normalize(lightPosition-viewPosition);
float3 L = normalize(lightPosition-objPos.xyz);
float3 RV = reflect(V, N);
float Dvp = length(viewPosition-objPos.xyz);
float Dsv = length(lightPosition-viewPosition);
float Dsp = length(lightPosition-objPos.xyz);
float gamma = acos(dot(S, V));
float thetas = acos(dot(N, L));
float thetas_ = acos(dot(L, RV));
/*compute airlight, diffuse and specular color seperately using our model in the paper*/
float airlight = AirLight(lightIntensity, beta, Dsv, Dvp, gamma, F, f_XOffset,f_XScale, f_YOffset,f_YScale);
float diffuse = Diffuse(lightIntensity, beta, Kd, Dsp, Dvp, thetas, G_0, g_0XOffset,g_0XScale, g_0YOffset,g_0YScale);
float specular = Specular(lightIntensity, beta, Ks, Dsp, Dvp, thetas_, G_20, g_20XOffset, g_20XScale, g_20YOffset, g_20YScale);
/*diffuse color-red, airlight color-white, specular color-white*/
OUT.color = float4(diffuse+airlight+specular,specular+airlight,specular+airlight, 0);
return OUT;
}
However this shader does not compile with the following log:
Compiling shader : StandardShading.vertexshader
Compiling shader : StandardShading.fragmentshader
0:14(2): error: syntax error, unexpected NEW_IDENTIFIER
Linking program
error: linking with uncompiled shader
And what's also unclear to me is how I can later chance the Beta value used in the shader? Any ideas?
vec4
for it's 4 component float variable, – ratchet freak Feb 24 at 16:43