GLSL/OpenGL/C++ - Normal Mapping Issues - c++

As the title says, I've been having troubles with normal mapping. First, a bit of background...
I was following TheCPlusPlusGuy's tutorials, using LWJGL, and ran into errors. I put a post on here, but it got no replies. I then moved into C++, and, once again, got back into normal mapping, and found more issues. The problem is, that when I move in the X-axis, the light appears to move as though I'm moving in the Y-axis. I've rendered the normal map texture, as a regular texture, and it works normally, so the bug therefore should be in the shaders.
I made a video of the bug, on YouTube here.
Here's the code:
vertex.vert:
#version 120
precision highp float;
varying vec2 texCoord;
varying vec3 position;
varying vec3 normal;
uniform vec3 lightPos;
varying vec3 tangentSurface2light;
varying vec3 tangentSurface2view;
mat3 getTangentMatrix(){
vec3 tangent;
vec3 v1 = cross(gl_Normal, vec3(0.0, 1.0, 0.0));
vec3 v2 = cross(gl_Normal, vec3(0.0, 0.0, 1.0));
if(length(v1) > length(v2)){
tangent = v1;
}else{
tangent = v2;
}
vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * tangent);
vec3 b = cross(n, t);
mat3 mat = mat3(t.x, b.x, n.x,
t.y, b.y, n.y,
t.z, b.x, n.z);
return transpose(mat);
}
void main(){
mat3 tangent = getTangentMatrix();
texCoord = gl_MultiTexCoord0.xy;
gl_Position = ftransform();
position = vec3(gl_ModelViewMatrix * gl_Vertex);
normal = gl_NormalMatrix * gl_Normal;
vec3 vector = normalize(lightPos - position);
tangentSurface2light = tangent * vector;
vector = normalize(-position);
tangentSurface2view = tangent * vector;
}
fragment.frag:
#version 120
precision highp float;
varying vec2 texCoord;
uniform sampler2D texture;
uniform sampler2D normalMap;
varying vec3 position;
varying vec3 normal;
varying vec3 tangentSurface2light;
varying vec3 tangentSurface2view;
uniform vec3 lightPos;
uniform vec3 mambient;
uniform vec3 mdiffuse;
uniform vec3 mspecular;
uniform float shininess;
uniform vec3 lambient;
uniform vec3 ldiffuse;
uniform vec3 lspecular;
void main(){
float dist = length(position - lightPos);
float att = 1.0/(0.005*dist*dist);
vec3 tdiffuse = vec3(texture2D(texture, texCoord)) * mdiffuse;
vec3 ambient = mambient * lambient;
vec3 surf2light = normalize(tangentSurface2light);
vec3 norm = normalize(texture2D(normalMap, texCoord).xyz * 2.0 - 1.0);
float dcont = max(0.0, dot(norm, surf2light));
vec3 diffuse = dcont * tdiffuse * ldiffuse;
vec3 surf2view = normalize(tangentSurface2view);
vec3 reflection = reflect(-surf2light, norm);
float scont = pow(max(0.0, dot(surf2view, reflection)), shininess);
scont = max(0.0, dot(surf2view, reflection));
vec3 specular = scont * mspecular * lspecular;
gl_FragColor=vec4((ambient + diffuse + specular )* att, 1.0);
}
And just in case, main.cpp (Note functions.h is just the first person camera):
#include <iostream>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include "GLee.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL_opengl.h>
#include <SDL/SDL_mouse.h>
#include <math.h>
#include <SDL/SDL_opengl.h>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
#include <cstdio>
#include <cstdlib>
#include "functions.h"
//#include <SDL/SDL_video.h>
#define PI 3.14159265358979323846264338327
using namespace std;
unsigned int frame, texture, normalMap;
long double lPos = 0;
bool mousein = false;
#include "GLee.h"
void loadFile(const char* fn, string& str){
ifstream in(fn);
if(!in.is_open()){
cout<<"The file "<<fn<<"could not be opened!"<<endl;
return;
}
char tmp[300];
while(!in.eof()){
in.getline(tmp, 300);
str += tmp;
str += '\n';
}
}
unsigned int loadShader(string& source, unsigned int mode){
unsigned int id;
id = glCreateShader(mode);
const char* csource = source.c_str();
glShaderSource(id, 1, &csource, NULL);
glCompileShader(id);
char error[1000];
glGetShaderInfoLog(id, 1000, NULL, error);
cout<<"Compile Status: \n"<<error<<endl;
return id;
}
unsigned int vs, fs, program;
void initShader(const char* vname, const char* fname, unsigned int& program){//20:30 into vid...
string source;
loadFile(vname, source);
vs = loadShader(source, GL_VERTEX_SHADER);
source = "";
loadFile(fname, source);
fs = loadShader(source, GL_FRAGMENT_SHADER);
program = glCreateProgram();
glAttachShader(program, vs);
glAttachShader(program, fs);
glLinkProgram(program);
glUseProgram(program);
}
void clean(const int& program){
glDetachShader(program, vs);
glDetachShader(program, fs);
glDeleteShader(vs);
glDeleteShader(fs);
glDeleteProgram(program);
}
void gluPerspective( GLdouble fovY, GLdouble aspect, GLdouble zNear, GLdouble zFar ){
const GLdouble pi = 3.1415926535897932384626433832795;
GLdouble fW, fH;
fH = tan( fovY / 360 * pi ) * zNear;
fW = fH * aspect;
glFrustum( -fW, fW, -fH, fH, zNear, zFar );
}
unsigned int loadTexture(const char* fileName){
//IMG_Init(0);
GLint numberOfColours = 0;
GLenum format;
SDL_Surface* img = IMG_Load(fileName);
img = SDL_DisplayFormatAlpha(img);
cout<<IMG_GetError();
//numberOfColours = img->format->BytesPerPixel;
if(!(&img)){
cout<<"Failed To Find Image!"<<endl;
}
cout<<"Reached load!"<<endl;
if(((img->w & (img->w - 1)) != 0)){cout<<"Warning: Image width not a power of 2!"<<endl;}
if(((img->h & (img->h - 1)) != 0)){cout<<"Warning: Image height not a power of 2!"<<endl;}
if(img->format->BytesPerPixel == 4){
format = GL_RGBA;
}else{
format = GL_RGB;
}
cout<<"GL_RGB: "<<GL_RGB<<"\nFormat: "<<format<<endl;
// SDL_PixelFormat pf;
//pf.palette = 0;
//pf.BitsPerPixel = 32;
//pf.BytesPerPixel = 4;
//pf.alpha = 255;
//pf.Rshift = pf.Rloss = pf.Gloss = pf.Bloss = pf.Aloss = pf.colorkey = 0;
//pf.Rmask = 0x000000ff;
//pf.Gshift = 8;
//pf.Gmask = 0x0000ff00;
//pf.Bshift = 16;
//pf.Bmask = 0x00ff0000;
//pf.Ashift = 24;
//pf.Amask = 0xff000000;
//SDL_Surface* glSurface = SDL_ConvertSurface(img, &pf, SDL_SWSURFACE);
unsigned int id;
glGenTextures(1, &id);
cout<<"ID: "<<id<<endl;
glBindTexture(GL_TEXTURE_2D, id);
cout<<"IMG Error: "<<IMG_GetError()<<endl;
cout<<"SDL Error: "<<SDL_GetError()<<endl;
glTexImage2D(GL_TEXTURE_2D, 0, format, img->w, img->h, 0, GL_BGRA, GL_UNSIGNED_BYTE, img->pixels);
cout<<"IMG Error: "<<IMG_GetError()<<endl;
cout<<"SDL Error: "<<SDL_GetError()<<endl;
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP,GL_TRUE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16);
SDL_FreeSurface(img);
return id;
}
SDL_Surface* loadTextureData(const char* fileName){
SDL_Surface* tex;
if((tex = IMG_Load(fileName))){
cout<<"Texture Found! Tex: "<<fileName<<endl;
}
return tex;
}
void init(){
//glEnable(GL_CULL_FACE);
//glCullFace(GL_BACK);
const unsigned char* text = glGetString(GL_VERSION);
SDL_WM_GrabInput(SDL_GRAB_ON);
glEnable(GL_MULTISAMPLE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
SDL_WM_SetCaption("OGL!", "OGL!!");
//SDL_WM_IconifyWindow();
SDL_Surface* icon = loadTextureData("Logo.png");
SDL_WM_SetIcon(icon, NULL);
glClearColor(0.0, 0.0, 0.0, 1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45, 1280.0/720.0, 0.1, 5000.0);
glMatrixMode(GL_MODELVIEW);
SDL_FreeSurface(icon);
texture = loadTexture("Moon.png");
normalMap = loadTexture("Normal Map.png");
SDL_ShowCursor(false);
initShader("vertex.vert", "fragment.frag", program);
}
void display(){
//frame++;
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glUniform1i(glGetUniformLocation(program, "texture"), 0);
glUniform1i(glGetUniformLocation(program, "normalMap"), 1);
glUniform3f(glGetUniformLocation(program, "lightPos"), 0, 0, 0);
glUniform3f(glGetUniformLocation(program, "mambient"), 0.2, 0.2, 0.2);
glUniform3f(glGetUniformLocation(program, "mdiffuse"), 0.6, 0.6, 0.6);
glUniform3f(glGetUniformLocation(program, "mspecular"), 1, 1, 1);
glUniform1f(glGetUniformLocation(program, "shininess"), 0);
glUniform3f(glGetUniformLocation(program, "lambient"), 0.2, 0.2, 0.2);
glUniform3f(glGetUniformLocation(program, "ldiffuse"), 0.4, 0.4, 0.4);
glUniform3f(glGetUniformLocation(program, "lspecular"), 1, 1, 1);
glUniform3f(glGetUniformLocation(program, "lightPos"), /*lPos*/0, 0, 0);
glLoadIdentity();
control(0.2, 0.2, mousein);
updateCamera();
//glTranslatef(0.0, 0.0, -6);
//glRotatef(frame, 0, 1, 0);
//glRotatef(90, 0, 1, 0);
/*glBegin(GL_TRIANGLES);
glScalef(15, 15, 15);
glColor4f(1.0, 0.0, 0.0, 1);
glVertex3f(0.0, 2.0, 0.0);
glColor4f(0.0, 1.0, 0.0, 1);
glVertex3f(-2.0, -2.0, 0.0);
glColor4f(0.0, 0.0, 1.0, 1);
glVertex3f(2.0, -2.0, 0.0);
glEnd();*/
//glRotatef(90, 0, 1, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, normalMap);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, normalMap);
glBegin(GL_QUADS);
glNormal3f(0.0, 0.0, 1.0);
glColor4f(1.0,1.0,1.0, 1.0);
glTexCoord2i(0, 0);
glVertex3f(-2.0, 2.0, 0.0);
glTexCoord2i(1, 0);
glVertex3f(-2.0, -2.0, 0.0);
glTexCoord2i(1, 1);
glVertex3f(2.0, -2.0, 0.0);
glTexCoord2i(0, 1);
glVertex3f(2.0, 2.0, 0.0);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
}
void update(){
frame++;
lPos = sin((180/PI)*(frame/10))*5;
}
int main(int args, char* argv[]){
SDL_Init(SDL_INIT_EVERYTHING);
IMG_Init(IMG_INIT_PNG);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
SDL_Surface* screen = SDL_SetVideoMode(1280, 720, 32, SDL_SWSURFACE|SDL_OPENGL);
bool running = true;
Uint32 start;
SDL_Event event;
init();
while(running){
start = SDL_GetTicks();
while(SDL_PollEvent(&event)){
switch(event.type){
case SDL_QUIT:
running = false;
break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym){
default:
break;
case SDLK_ESCAPE:
running = false;
break;
case SDLK_p:
mousein = false;
SDL_ShowCursor(SDL_ENABLE);
break;
}
break;
case SDL_KEYUP:
break;
case SDL_MOUSEBUTTONDOWN:
mousein = true;
SDL_ShowCursor(SDL_DISABLE);
break;
}
}
update();
display();
SDL_GL_SwapBuffers();
if(1000/60 > (SDL_GetTicks() - start)){
SDL_Delay(1000/60 - (SDL_GetTicks() - start));
}
}
clean(program);
SDL_Quit();
//cout << "Hello world!" << endl;
return 0;
}

Related

Bloom strangely appears in a yellow colour

Hey,
For some reason the bloom is appearing as yellow, I am not entirely sure why the bloom is yellow, its not a blending problem and the code seems correct.
I have researched on this problem and knowone appears to have the same problem, I'm thinking it may be todo with the fbo texture filtering but I'm not to sure. I need some help.
Here is the code..
Final Gather code
#version 330 core
out vec4 FragColor;
in vec2 _texcoord;
in float color;
uniform sampler2D scene;
uniform sampler2D bloom;
uniform float bloom_intensity;
void main()
{
const float gamma = 1.3;
float exposure = 1.0;
vec3 hdrColor = texture(scene, _texcoord).rgb;
vec3 bloomColor = texture(bloom, _texcoord).rgb;
hdrColor += bloomColor; /// bloom_intensity;
// tone mapping
vec3 result = vec3(1.0) - exp(-hdrColor * exposure);
// also gamma correct while we're at it
result = pow(result, vec3(1.0 / gamma));
FragColor = vec4(result, 1.0);
}
Bloom in light fragment shader
// final lighting calculations
vec3 result = calc_directional_light(Diffuse, Specular, Metalness, AO);
for (int i = 0; i < 5; i++)
{
result += calc_point_light(pointLights[i], Diffuse, Specular);
result += calc_spot_light(spotLights[i], Diffuse, Specular);
}
float brightness = dot(result, vec3(0.2126, 0.7152, 0.0722));
if(brightness > 0.7)
BrightColor = vec4(result, 1.0);
else
BrightColor = vec4(0.0, 0.0, 0.0, 1.0);
FragColor = vec4(result, 1.0);
Bloom setup
inline void Create(std::vector<GLuint> shader_programs, size_t width, size_t height, float intensity)
{
_shader_programs = shader_programs;
_intensity = intensity;
_fbo = new Fbo(width, height, { new FboAttachment(width, height, GL_RGB16F, GL_RGB, GL_FLOAT, GL_COLOR_ATTACHMENT0),
new FboAttachment(width, height, GL_RGB16F, GL_RGB, GL_FLOAT, GL_COLOR_ATTACHMENT1) }, true);
_h_blur = new Fbo(width, height, { new FboAttachment(width, height, GL_RGB16F, GL_RGB, GL_FLOAT, GL_COLOR_ATTACHMENT0) }, false);
_v_blur = new Fbo(width, height, { new FboAttachment(width, height, GL_RGB16F, GL_RGB, GL_FLOAT, GL_COLOR_ATTACHMENT0) }, false);
_u_texturemap[0] = glGetUniformLocation(_shader_programs[0], "textureMap");
_u_texturemap[1] = glGetUniformLocation(_shader_programs[1], "textureMap");
_u_blurres[0] = glGetUniformLocation(_shader_programs[0], "blur_resolution");
_u_blurres[1] = glGetUniformLocation(_shader_programs[0], "blur_resolution");
}
Bloom Render
inline virtual void Render()
{
_h_blur->Bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(_shader_programs[0]);
glUniform1i(_u_texturemap[0], 0);
glUniform1f(_u_blurres[0], 128.0f);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _fbo->GetAttachments()[1]->_texture);
_screen_rect->Render(1);
_h_blur->Unbind();
_v_blur->Bind();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(_shader_programs[1]);
glUniform1i(_u_texturemap[1], 0);
glUniform1f(_u_blurres[1], 128.0f);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, _h_blur->GetAttachments()[0]->_texture);
_screen_rect->Render(1);
_v_blur->Unbind();
}

Why qopenglshaderprogram displaying mirror image in qt

I am rendering video using opengl in qml using QQuickFramebufferObject but output what ever i am seeing is mirror of original.
what might be the wrong.
code:
QOpenGLShaderProgram *m_Program;
glGenTextures(3, m_Texture);
m_Program = new QOpenGLShaderProgram();
m_Program->addShaderFromSourceCode(QOpenGLShader::Vertex,
"attribute vec4 a_position;"
"attribute vec2 a_texcoord;"
"varying vec2 v_texcoord;"
"void main()"
"{"
" gl_Position = a_position;"
" v_texcoord = a_texcoord;"
"}"
);
m_Program->addShaderFromSourceCode(QOpenGLShader::Fragment,
"varying vec2 v_texcoord;"
"uniform sampler2D u_Texture0;"
"uniform sampler2D u_Texture1;"
"uniform sampler2D u_Texture2;"
"uniform mat4 u_colorMatrix;"
"void main()"
"{"
" gl_FragColor = u_colorMatrix * vec4("
" texture2D(u_Texture0, v_texcoord).s,"
" texture2D(u_Texture1, v_texcoord).t,"
" texture2D(u_Texture2, v_texcoord).q,"
" 1.0);"
"}"
);
m_Program->bindAttributeLocation("a_position", 0);
m_Program->bindAttributeLocation("a_texcoord", 1);
m_Program->link();
static double prevPos = 0.0;
glDisable(GL_DEPTH_TEST);
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
if(m_PlaneWidth == -1)
{
_clearView();
return;
}
m_Program->bind();
m_Program->enableAttributeArray(0);
m_Program->enableAttributeArray(1);
setPlayerPosition();
m_pw=m_ph=1.0;
float position[] =
{
m_pw, m_ph,
m_pw, -m_ph,
-m_pw, -m_ph,
-m_pw, m_ph
};
float w =1.0-(m_PlaneWidth-float(m_ptrMediator->getWidth()))/m_PlaneWidth;
float coord[] =
{
0.0, 1.0,
0.0, 0.0,
w, 0.0,
w, 1.0
};
m_Program->setAttributeArray(0, GL_FLOAT, position, 2);
m_Program->setAttributeArray(1, GL_FLOAT, coord, 2);
const qreal zNear = 1.0, zFar = 4.0, fov = 45.0;
const qreal aspect = m_ptrMediator->getWidth()/m_ptrMediator->getHeight();
m_Projection.setToIdentity();
m_Projection.perspective(fov, aspect, zNear, zFar);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
refresh(&pFrame);
m_Program->disableAttributeArray(0);
m_Program->release();
glActiveTextureARB(GL_TEXTURE2_ARB);
glBindTexture(GL_TEXTURE_2D, m_Texture[2]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pFrame->width,
pFrame->height, GL_LUMINANCE,
GL_UNSIGNED_BYTE, pFrame->data[0]);
glActiveTextureARB(GL_TEXTURE1_ARB);
glBindTexture(GL_TEXTURE_2D, m_Texture[1]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pFrame->width/2,
pFrame->height/2, GL_LUMINANCE,
GL_UNSIGNED_BYTE, pFrame->data[1]);
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D, m_Texture[0]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, pFrame->width/2,
pFrame->height/2, GL_ALPHA,
GL_UNSIGNED_BYTE, pFrame->data[2]);
m_Program->setUniformValue("u_Texture0", 2/*m_Texture[2]-1*/);
m_Program->setUniformValue("u_Texture1", 1/*m_Texture[1]-1*/);
m_Program->setUniformValue("u_Texture2", 0/*m_Texture[0]-1*/);
m_Program->setUniformValue("u_colorMatrix", m_Conv);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if i change position i can able to see some changes but still i am not getting actual data.
Could some one help me out of this
I just modified position and texture coordinates it starting working.
m_pw=m_ph=1.0;
float position[] =
{
-m_pw, -m_ph,
m_pw, -m_ph,
m_pw, m_ph,
-m_pw, m_ph
};
float w =1.0-(m_PlaneWidth-float(m_ptrMediator->getWidth()))/m_PlaneWidth;
float coord[] =
{
0.0, 0.0,
w, 0.0,
w, 1.0,
0.0, 1.0
};

Textures not working (Black Textures) - OpenGL + GLSL

I am trying to detect silhouette edges and render some textures (varies based on the diffuse term) on these edges using OpenGL and shaders. I am rendering a quad using the geometry shader and also assign the texture coordinates here. In the fragment shader, i am trying to use the diffuse term calculated in vertex shader to render different textures based on diffTerm's value. There are two issues with my code.
1) The diffuse term should vary from (-1,1) but it seems to be stuck at 0 when i rotate the model and it reaches negative values at certain positions.
2) The textures are always black and I cant seem to find out what is causing this issue.
"MeshViewer.cpp" - The main file
Mesh* mesh;
GLuint* texID = new GLuint[5];
float rotn_x = 0.0, rotn_y = 0.0, fov;
GLuint matrixLoc1, matrixLoc2, matrixLoc3,texLoc1, texLoc2, texLoc3, texLoc4, texLoc5;
float cam_near, cam_far; //Near and far planes of the camera
const float PI = 3.14159265f;
glm::mat4 view; //View and projection matrices
void loadTextures()
{
glGenTextures(5, texID); //Generate 1 texture ID
glActiveTexture(GL_TEXTURE0); //Texture unit 0
glBindTexture(GL_TEXTURE_2D, texID[0]);
loadTGA("Pencil0.tga");
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glActiveTexture(GL_TEXTURE1); //Texture unit 0
glBindTexture(GL_TEXTURE_2D, texID[1]);
loadTGA("Pencil1.tga");
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glActiveTexture(GL_TEXTURE2); //Texture unit 0
glBindTexture(GL_TEXTURE_2D, texID[2]);
loadTGA("Pencil2.tga");
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glActiveTexture(GL_TEXTURE3); //Texture unit 0
glBindTexture(GL_TEXTURE_2D, texID[3]);
loadTGA("Brick.tga");
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glActiveTexture(GL_TEXTURE4); //Texture unit 0
glBindTexture(GL_TEXTURE_2D, texID[4]);
loadTGA("Brick.tga");
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
void initialise()
{
// --- Mesh object ---
GLuint lgtLoc;
mesh = new Mesh();
if(!mesh->loadMeshOFF("Camel.off")) cout << "Error reading mesh data file." << endl;
// --- Camera parameters ---
float win_width = (mesh->_xmax - mesh->_xmin) * 1.5f;
float win_height = (mesh->_ymax - mesh->_ymin) * 1.5f;
if(win_width > win_height) win_height = win_width; //Maintain aspect ratio = 1
cam_near = 2*(mesh->_zmax) - mesh->_zmin;
cam_far = 2*(mesh->_zmin) - mesh->_zmax;
float cam_posx = (mesh->_xmax + mesh->_xmin) * 0.5f;
float cam_posy = (mesh->_ymax + mesh->_ymin) * 0.5f;
float cam_posz = cam_near + win_height;
fov = 27.0f; //Approx. atan(0.5)
// --- Uniform locations ---
GLuint program = createShaderProg("MeshViewer.vert", "MeshViewer.frag", "MeshViewer.geom");
matrixLoc1 = glGetUniformLocation(program, "mvMatrix");
matrixLoc2 = glGetUniformLocation(program, "mvpMatrix");
matrixLoc3 = glGetUniformLocation(program, "norMatrix");
lgtLoc = glGetUniformLocation(program, "lightPos");
GLint lineWidth = glGetUniformLocation(program, "HalfWidth");
if (lineWidth > -1)
glUniform1f(lineWidth, 0.005f);
GLint overhangLength = glGetUniformLocation(program, "OverhangLength");
if (overhangLength > -1)
glUniform1f(overhangLength, 0.15f);
texLoc1 = glGetUniformLocation (program, "tex1");
glUniform1i(texLoc1, 0);
texLoc2 = glGetUniformLocation (program, "tex2");
glUniform1i(texLoc2, 1);
texLoc3 = glGetUniformLocation (program, "tex3");
glUniform1i(texLoc3, 2);
texLoc4 = glGetUniformLocation (program, "tex4");
glUniform1i(texLoc4, 3);
texLoc5 = glGetUniformLocation (program, "tex5");
glUniform1i(texLoc5, 4);
view = glm::lookAt(glm::vec3(cam_posx, cam_posy, cam_posz), glm::vec3(cam_posx, cam_posy, 0.0), glm::vec3(0.0, 1.0, 0.0)); //view matrix
glm::vec4 light = glm::vec4(100.0, 50.0, 100.0, 1.0); //Light's position
glm::vec4 lightEye = view*light; //Light position in eye coordinates
glUniform4fv(lgtLoc, 1, &lightEye[0]);
// --- OpenGL ---
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //Wireframe
mesh->setColor(0, 0, 1); //Mesh color = blue.
mesh->createVAO(); //Create buffer objects for the mesh
}
void display()
{
glm::mat4 proj;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glm::mat4 matrix = glm::mat4(1.0);
matrix = glm::rotate(matrix, rotn_x, glm::vec3(1.0, 0.0, 0.0)); //rotation about x
matrix = glm::rotate(matrix, rotn_y, glm::vec3(0.0, 1.0, 0.0)); //rotation about y
glm::mat4 prodMatrix1 = view*matrix; //Model-view matrix
proj = glm::perspective(fov, 1.0f, cam_near, cam_far); //perspective projection matrix
glm::mat4 prodMatrix2 = proj*prodMatrix1; //The model-view-projection transformation
glm::mat4 invMatrix = glm::inverse(prodMatrix1); //Inverse of model-view matrix for normal transformation
glUniformMatrix4fv(matrixLoc1, 1, GL_FALSE, &prodMatrix1[0][0]);
glUniformMatrix4fv(matrixLoc2, 1, GL_FALSE, &prodMatrix2[0][0]);
glUniformMatrix4fv(matrixLoc3, 1, GL_TRUE, &invMatrix[0][0]); //Use transpose matrix here
mesh->render();
glFlush();
}
void specialKeys(int key, int x, int y)
{
if(key == GLUT_KEY_LEFT) rotn_y -= 5.0;
else if(key == GLUT_KEY_RIGHT) rotn_y += 5.0;
else if(key == GLUT_KEY_UP) rotn_x -= 5.0;
else if(key == GLUT_KEY_DOWN) rotn_x += 5.0;
else if(key == GLUT_KEY_PAGE_UP) fov --;
else if(key == GLUT_KEY_PAGE_DOWN) fov ++;
if(fov < 1.0) fov = 1.0;
else if(fov > 80.0) fov = 80.0;
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (600, 600);
glutInitWindowPosition (20, 10);
glutCreateWindow ("Mesh Viewer");
glutInitContextVersion (4, 2);
glutInitContextProfile ( GLUT_CORE_PROFILE );
if(glewInit() == GLEW_OK)
{
cout << "GLEW initialization successful! " << endl;
cout << " Using GLEW version " << glewGetString(GLEW_VERSION) << endl;
}
else
{
cerr << "Unable to initialize GLEW ...exiting." << endl;
exit(EXIT_FAILURE);
}
initialise ();
glutDisplayFunc(display);
glutSpecialFunc(specialKeys);
glutMainLoop();
return 0;
}
Vertex Shader:
#version 330
layout (location = 0) in vec4 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec3 cols;
layout (location = 3) in vec2 texC;
uniform mat4 mvMatrix;
uniform mat4 mvpMatrix;
uniform mat4 norMatrix;
uniform vec4 lightPos;
out float diffTerm;
out vec4 vColour;
out float viewTerm;
out float silhoutte;
out vec2 TexC;
void main()
{
vec4 grey = vec4(0.2, 0.2, 0.2, 1.0);
vec4 posnEye = mvMatrix * position;
vec4 normalEye = norMatrix * vec4(normal, 0);
vec4 lgtVec = normalize(lightPos - posnEye);
vec4 viewVec = normalize(vec4(-posnEye.xyz, 0));
float viewTerm = max(dot(viewVec, normalEye),0);
vec4 material = vec4(cols, 1.0);
vec4 lgtAmb = grey * material;
diffTerm = max(dot(lgtVec, normalEye), 0);
vec4 lgtDiff = material * diffTerm;
silhoutte = dot(viewVec, normalEye);
gl_Position = mvpMatrix * position;
vColour = vec4(cols, 1);
TexC = texC;
}
Geometry Shader:
#version 430 core
layout(triangles_adjacency) in;
layout(triangle_strip, max_vertices = 6) out;
in vec2 texC[];
out vec2 TexCoord;
in vec4 vColour[];
out vec4 colorv;
in float viewTerm[];
out float viewTermg;
in float diffTerm[];
out float diffTermg;
in vec2 TexC[];
out vec2 TexCg;
uniform float HalfWidth;
uniform float OverhangLength;
out float gDist;
out vec3 gSpine;
bool IsFront(vec3 A, vec3 B, vec3 C)
{
float area = (A.x * B.y - B.x * A.y) + (B.x * C.y - C.x * B.y) + (C.x * A.y - A.x * C.y);
return area > 0;
}
void EmitEdge(vec3 P0, vec3 P1)
{
vec3 E = OverhangLength * vec3(P1.xy - P0.xy, 0);
vec2 V = normalize(E.xy);
vec3 N = vec3(-V.y, V.x, 0) * 0.005;
vec3 S = -N;
float D = HalfWidth;
gSpine = P0;
gl_Position = vec4(P0 + S - E, 1); gDist = +D; TexCoord=vec2(0.0,0.0); colorv = vColour[0]; EmitVertex();
gl_Position = vec4(P0 + N - E, 1); gDist = -D; TexCoord=vec2(1.0,0.0); colorv = vColour[1]; EmitVertex();
gSpine = P1;
gl_Position = vec4(P1 + S + E, 1); gDist = +D; TexCoord=vec2(1.0,1.0); colorv = vColour[0]; EmitVertex();
gl_Position = vec4(P1 + N + E, 1); gDist = -D; ; TexCoord=vec2(0.0,1.0); EmitVertex();
EndPrimitive();
}
void main()
{
vec3 v0 = gl_in[0].gl_Position.xyz / gl_in[0].gl_Position.w;
vec3 v1 = gl_in[1].gl_Position.xyz / gl_in[1].gl_Position.w;
vec3 v2 = gl_in[2].gl_Position.xyz / gl_in[2].gl_Position.w;
vec3 v3 = gl_in[3].gl_Position.xyz / gl_in[3].gl_Position.w;
vec3 v4 = gl_in[4].gl_Position.xyz / gl_in[4].gl_Position.w;
vec3 v5 = gl_in[5].gl_Position.xyz / gl_in[5].gl_Position.w;
if (IsFront(v0, v2, v4)) {
if (!IsFront(v0, v1, v2)) EmitEdge(v0, v2);
//if (!IsFront(v2, v3, v4)) EmitEdge(v2, v4);
//if (!IsFront(v0, v4, v5)) EmitEdge(v4, v0);
}
}
Fragment Shader:
#version 330
in vec4 vColourg;
in float diffTermg;
in float silhoutte;
in vec2 TexCg;
in vec2 TexCoord;
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform sampler2D tex3;
uniform sampler2D tex4;
uniform sampler2D tex5;
void main()
{
vec4 texColor1 = texture(tex1, TexCoord);
vec4 texColor2 = texture(tex2, TexCoord);
vec4 texColor3 = texture(tex3, TexCoord);
vec4 texColor4 = texture(tex4, TexCoord);
vec4 texColor5 = texture(tex5, TexCoord);
vec4 blue = vec4(0.0,0.0,1.0,0.0);
vec4 red = vec4(1.0,0.0,0.0,0.0);
vec4 yellow = vec4(1.0,1.0,0.0,0.0);
if (diffTermg<0)
{
gl_FragColor = blue;
}
else if (diffTermg ==0)
{
gl_FragColor = texColor5;
}
else if (diffTermg > 0 && diffTermg < 0.2)
gl_FragColor = yellow;
else if (diffTermg > 100)
gl_FragColor = blue;
}
EDIT:
Shader.h
GLuint loadShader(GLenum shaderType, string filename)
{
ifstream shaderFile(filename.c_str());
if(!shaderFile.good()) cout << "Error opening shader file." << endl;
stringstream shaderData;
shaderData << shaderFile.rdbuf();
shaderFile.close();
string shaderStr = shaderData.str();
const char* shaderTxt = shaderStr.c_str();
GLuint shader = glCreateShader(shaderType);
glShaderSource(shader, 1, &shaderTxt, NULL);
glCompileShader(shader);
GLint status;
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status == GL_FALSE)
{
GLint infoLogLength;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);
const char *strShaderType = NULL;
cerr << "Compile failure in shader: " << strInfoLog << endl;
delete[] strInfoLog;
}
return shader;
}
GLuint createShaderProg(string vertShader, string fragShader, string geomShader)
{
GLuint shaderv = loadShader(GL_VERTEX_SHADER, vertShader);
GLuint shaderf = loadShader(GL_FRAGMENT_SHADER, fragShader);
GLuint shaderg = loadShader(GL_GEOMETRY_SHADER, geomShader);
GLuint program = glCreateProgram();
glAttachShader(program, shaderv);
glAttachShader(program, shaderf);
glAttachShader(program, shaderg);
glLinkProgram(program);
GLint status;
glGetProgramiv (program, GL_LINK_STATUS, &status);
if (status == GL_FALSE)
{
GLint infoLogLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
GLchar *strInfoLog = new GLchar[infoLogLength + 1];
glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
fprintf(stderr, "Linker failure: %s\n", strInfoLog);
delete[] strInfoLog;
program = 0;
}
glUseProgram(program);
return program;
}
loadTGA.h
void loadTGA(string filename)
{
char id, cmap, imgtype, bpp, c_garb;
char* imageData, temp;
short int s_garb, wid, hgt;
int nbytes, size, indx;
ifstream file( filename.c_str(), ios::in | ios::binary);
if(!file)
{
cout << "*** Error opening image file: " << filename.c_str() << endl;
exit(1);
}
file.read (&id, 1);
file.read (&cmap, 1);
file.read (&imgtype, 1);
if(imgtype != 2 && imgtype != 3 ) //2= colour (uncompressed), 3 = greyscale (uncompressed)
{
cout << "*** Incompatible image type: " << (int)imgtype << endl;
exit(1);
}
//Color map specification
file.read ((char*)&s_garb, 2);
file.read ((char*)&s_garb, 2);
file.read (&c_garb, 1);
//Image specification
file.read ((char*)&s_garb, 2); //x origin
file.read ((char*)&s_garb, 2); //y origin
file.read ((char*)&wid, 2); //image width
file.read ((char*)&hgt, 2); //image height
file.read (&bpp, 1); //bits per pixel
file.read (&c_garb, 1); //img descriptor
nbytes = bpp / 8; //No. of bytes per pixels
size = wid * hgt * nbytes; //Total number of bytes to be read
imageData = new char[size];
file.read(imageData, size);
//cout << ">>>" << nbytes << " " << wid << " " << hgt << endl;
if(nbytes > 2) //swap R and B
{
for(int i = 0; i < wid*hgt; i++)
{
indx = i*nbytes;
temp = imageData[indx];
imageData[indx] = imageData[indx+2];
imageData[indx+2] = temp;
}
}
switch (nbytes)
{
case 1:
glTexImage2D(GL_TEXTURE_2D, 0, 1, wid, hgt, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, imageData);
break;
case 3:
glTexImage2D(GL_TEXTURE_2D, 0, 3, wid, hgt, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
break;
case 4:
glTexImage2D(GL_TEXTURE_2D, 0, 4, wid, hgt, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
break;
}
delete imageData;
}
You are requesting a core profile context:
glutInitContextProfile(GLUT_CORE_PROFILE);
But your glTexImage2D() calls are not compatible with the core profile:
glTexImage2D(GL_TEXTURE_2D, 0, 1, wid, hgt, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, imageData);
glTexImage2D(GL_TEXTURE_2D, 0, 3, wid, hgt, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
glTexImage2D(GL_TEXTURE_2D, 0, 4, wid, hgt, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
Using the number of components as the internal format (argument 3) is legacy from OpenGL 1.0, and was finally eliminated when the core profile was introduced. GL_LUMINANCE is also gone. The modern (core profile) equivalent of those calls is:
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, wid, hgt, 0, GL_RED, GL_UNSIGNED_BYTE, imageData);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, wid, hgt, 0, GL_RGB, GL_UNSIGNED_BYTE, imageData);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, wid, hgt, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
The post contains a lot of code, and I did not study it in detail to see if there are other problems. I strongly recommend the use of glGetError(), which would have reported these invalid arguments, and should also be helpful to check if there are any additional problems.

OpenGL shader compiler optimization?

I'm working on OpenGL 2.1 and have some problems with alpha value on gl_FragColor.
Whole code:
uniform sampler2D texture_0;
uniform vec3 uColor;
varying vec2 varTexCoords;
void main(void)
{
//vec4 col = texture2D(texture_0, varTexCoords);
vec4 col = vec4(0.0, 0.0, 0.0, 0.5);
gl_FragColor = col;
}
Can someone explain to me why:
Works:
vec4 col = texture2D(texture_0, varTexCoords);
//vec4 col = vec4(0.0, 0.0, 0.0, 0.5);
gl_FragColor = col;
Doesn't work:
//vec4 col = texture2D(texture_0, varTexCoords);
vec4 col = vec4(0.0, 0.0, 0.0, 0.5);
gl_FragColor = col;
Works:
vec4 col = texture2D(texture_0, varTexCoords);
col.rgb = uColor;
//col.a = 0.5;
gl_FragColor = col;
Also works:
vec4 col = texture2D(texture_0, varTexCoords);
col.rgb = uColor;
col.a *= 0.5;
gl_FragColor = col;
Doesn't work:
vec4 col = texture2D(texture_0, varTexCoords);
col.rgb = uColor;
col.a = 0.5;
gl_FragColor = col;
And this one dosen't work even though many examples seem to use it:
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
Error occurence in code is here:
glEnableVertexAttribArray(textureCoords);
CHECK_GL_ERROR("glEnableVertexAttribArrayCheck");
All code related to the shader:
inline void Renderer::renderText(float x, float y, string msg) {
mat4 proj;
Matrix::projection2D(proj,
(float) nScreenWidth_, (float) nScreenHeight_, 0.0f);
mat4 res, restmp;
mat4 pos;
mat4 rot;
mat4 scale;
//Vector3D p(72.0f, 88.0f, 1.0f);
//Vector3D p(20.0f, 20, 1.0f);
Vector3D r(0.0f, 0.0f, 0.0f);
Vector3D s(1.0f, nScreenWidth_ / nScreenHeight_, 1.0f);
//Matrix::translate(pos, p.getX(), p.getY(), p.getZ());
//Matrix::rotateZ(rot, r.getZ());
float widthMod = nScreenWidth_ / 100.0f;
float heightMod = nScreenHeight_ / 100.0f;
Matrix::translate(pos, x * widthMod, y * heightMod, 1.0f);
Matrix::rotateZ(rot, r.getZ());
//Matrix::scale(scale, s.getX() * widthMod, s.getY() * heightMod, 1.0f);
Matrix::scale(scale, 16.0f, 16.0f, 1.0f);
Matrix::multiply(proj, pos, res);
Matrix::multiply(res, rot, restmp);
Matrix::multiply(restmp, scale, res);
// Select shader program to use.
int shaderId = features_->getText()->getShaderId();
glUseProgram(shaderId);
CHECK_GL_ERROR("glUseProgram");
int matrix = glGetUniformLocation(shaderId, "uWVP");
int color = glGetUniformLocation(shaderId, "uColor");
int texture = glGetUniformLocation(shaderId, "texture_0");
CHECK_GL_ERROR("glGetUniformLocation");
int textureCoords = glGetAttribLocation(shaderId, "attrTexCoords");
int vertices = glGetAttribLocation(shaderId, "attrPos");
CHECK_GL_ERROR("glGetAttribLocation");
// Specify WVP matrix.
glUniformMatrix4fv(matrix, 1, false, res);
CHECK_GL_ERROR("glUniformMatrix4fv");
// Bind the texture.
glActiveTexture(GL_TEXTURE0);
CHECK_GL_ERROR("glActiveTexture");
glBindTexture(GL_TEXTURE_2D, features_->getText()->getFontMapId());
CHECK_GL_ERROR("glBindTexture");
glUniform1i(texture, 0);
CHECK_GL_ERROR("glUniform1i");
glEnableVertexAttribArray(vertices);
CHECK_GL_ERROR("glEnableVertexAttribArray");
glBindBuffer(GL_ARRAY_BUFFER, 0);
CHECK_GL_ERROR("glBindBuffer");
glEnable(GL_BLEND);
CHECK_GL_ERROR("glEnable");
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
CHECK_GL_ERROR("glBlendFunc");
//string text = output_;
for (unsigned int i = 0; i < msg.length(); i++) {
unsigned short l = static_cast<unsigned short>(msg[i]) - 32;
mat4 delta, resmove;
Matrix::translate(delta, 1.6f, 0.0f, 0.0f);
Matrix::multiply(res, delta, resmove);
Matrix::copy(resmove, res);
glUniformMatrix4fv(matrix, 1, false, res);
CHECK_GL_ERROR("glUniformMatrix4fv");
float col[] = {0.0f, 1.0f, 0.0f};
glUniform3fv(color, 1, col);
CHECK_GL_ERROR("glUniform3fv");
glVertexAttribPointer(vertices, 3, GL_FLOAT, GL_FALSE, 0,
features_->getText()->vertices_);
CHECK_GL_ERROR("glVertexAttribPointer");
glEnableVertexAttribArray(textureCoords);
CHECK_GL_ERROR("glEnableVertexAttribArrayCheck");
glVertexAttribPointer(textureCoords, 2, GL_FLOAT, GL_FALSE, 0,
features_->getText()->getSymbol(l));
CHECK_GL_ERROR("glVertexAttribPointer");
glDrawArrays(GL_TRIANGLES, 0, 18 / 3);
CHECK_GL_ERROR("glDrawArrays");
}
glDisable(GL_BLEND);
CHECK_GL_ERROR("glDisable");
}
The error is GL_INVALID_VALUE and only occurs after executing code, not after compiling and linking shader.
This is probably what is happening :
(I say "compiler" here, but it's probably the linker that does the actual purging)
The shader compliler drops this one :
varying vec2 varTexCoords;
If the compiler determines that a variable is not used, it will be discarded.
The last example is good :
vec4 col = texture2D(texture_0, varTexCoords);
col.rgb = uColor;
col.a = 0.5;
gl_FragColor = col;
The compiler understands that the original value in col is overwritten by the uColor uniform and the 0.5 constant. The texture read is dropped, so the varying is also dropped.
Then your attrTexCoords will also most likely be dropped, so your textureCoords variable containing the attrib locations is -1.
Here on the other hand, the compiler cannot remove the texture read because col.bg will contain values from the texture.
vec4 col = texture2D(texture_0, varTexCoords);
col.r = uColor.r;
col.a = 0.5;
gl_FragColor = col;

Why is my cube only rendering as a square?

Im having two problems but one at a time. Im attempting to render a 3d cube but it looks like just a square.
The shader is:
#version 330
uniform mat4 mvp;
layout(location=0) in vec4 vPosition;
layout(location=1) in vec4 vColor;
out vec4 color;
void main() {
color = vColor;
gl_Position = mvp * vPosition;
}
The entirety of my main:
#include "Angel.h"
#include <gl/glew.h>
#include <glut.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <iostream>
using namespace std;
#define bool int /* if system does not support bool type */
#define false 0
#define true 1
#define M_PI 3.14159265358 /* if not in math.h */
int winWidth, winHeight;
float angle = 0.0, axis[3], trans[3];
bool trackingMouse = false;
float lastPos[3] = {0.0, 0.0, 0.0};
float aspect = 1.0;
int curx, cury;
int startX, startY;
int modelInit=1;
//the program object
GLuint program = 0;
glm::mat4 model;
typedef Angel::vec4 color4;
typedef Angel::vec4 point4;
const int NumVertices = 36; //(6 faces)(2 triangles/face)(3 vertices/triangle)
point4 points[NumVertices];
color4 colors[NumVertices];
enum { Xaxis = 0, Yaxis = 1, Zaxis = 2, NumAxes = 3 };
int Axis = Xaxis;
GLuint mvpUniform;
GLuint shaderaxis;
int Index = 0;
// Vertices of a unit cube centered at origin, sides aligned with axes
point4 vertices[8]={
point4(-0.5, -0.5, 0.5, 1.0),
point4(-0.5, 0.5, 0.5, 1.0),
point4(0.5, 0.5, 0.5, 1.0),
point4(0.5, -0.5, 0.5, 1.0),
point4(-0.5, -0.5, -0.5, 1.0),
point4(-0.5, 0.5, -0.5, 1.0),
point4(0.5, 0.5, -0.5, 1.0),
point4(0.5, -0.5, -0.5, 1.0)
};
// RGBA colors
color4 vertex_colors[8] = {
color4(0.0, 0.0, 0.0, 1.0), // black
color4(1.0, 0.0, 0.0, 1.0), // red
color4(1.0, 1.0, 0.0, 1.0), // yellow
color4(0.0, 1.0, 0.0, 1.0), // green
color4(0.0, 0.0, 1.0, 1.0), // blue
color4(1.0, 0.0, 1.0, 1.0), // magenta
color4(1.0, 1.0, 1.0, 1.0), // white
color4(0.0, 1.0, 1.0, 1.0) // cyan
};
// quad generates two triangles for each face and assigns colors to the vertices
void quad(int a, int b, int c, int d) {
colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
colors[Index] = vertex_colors[b]; points[Index] = vertices[b]; Index++;
colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++;
colors[Index] = vertex_colors[a]; points[Index] = vertices[a]; Index++;
colors[Index] = vertex_colors[c]; points[Index] = vertices[c]; Index++;
colors[Index] = vertex_colors[d]; points[Index] = vertices[d]; Index++;
}
// generate 12 triangles: 36 vertices and 36 colors
void colorcube(void) {
quad(1, 0, 3, 2);
quad(2, 3, 7, 6);
quad(3, 0, 4, 7);
quad(6, 5, 1, 2);
quad(4, 5, 6, 7);
quad(5, 4, 0, 1);
}
// OpenGL initialization
void init(void) {
colorcube();
// Load shaders and use the resulting shader program
GLuint program = InitShader("vshader36.glsl", "fshader36.glsl");
glUseProgram(program);
// Create a vertex array object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create and initialize a buffer object
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(points) + sizeof(colors), NULL, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(points), points);
glBufferSubData(GL_ARRAY_BUFFER, sizeof(points), sizeof(colors), colors);
// set up vertex arrays
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
model = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, -5.0));
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(points)));
mvpUniform = glGetUniformLocation(program, "mvp");
glEnable(GL_DEPTH_TEST);
glClearColor(1.0, 1.0, 1.0, 1.0);
}
void trackball_ptov(int x, int y, int width, int height, float v[3]) {
float d, a;
/* project x, y onto a hemisphere centered within width, height , note z is up here*/
v[0] = (2.0*x - width) / width;
v[1] = (height - 2.0F*y) / height;
d = sqrt(v[0]*v[0] + v[1]*v[1]);
v[2] = cos((M_PI/2.0) * ((d < 1.0) ? d : 1.0));
a = 1.0 / sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
v[0] *= a;
v[1] *= a;
v[2] *= a;
}
void display() {
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glm::mat4 proj = glm::perspective(90.F, 1.F, 0.1F, 100.F);
glm::mat4 view = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, 0.0)); //apply mouse translation
//view = glm::rotate(view, 0.2*mousediff.x, glm::vec3(0.0, 1.0, 0.0)); //apply mouse rotation
//view = glm::rotate(view, 0.2*mousediff.y, glm::vec3(1.0, 0.0, 0.0));
//model = glm::translate(glm::mat4(1.0), glm::vec3(0.0, 0.0, -5.0));
//glUniformMatrix4fv(mvpUniform, 1, false, glm::value_ptr(proj));
glUniformMatrix4fv(mvpUniform, 1, false, glm::value_ptr(proj*view*model));
//glUniformMatrix4fv(mvpUniform, 1, false, glm::value_ptr(model*view*proj));
glDrawArrays(GL_TRIANGLES, 0, NumVertices);
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y) {
switch(key) {
case 033: // Escape Key
case 'q': case 'Q':
exit(EXIT_SUCCESS);
break;
}
}
void mouseButton(int button, int state, int x, int y) {
if(button==GLUT_RIGHT_BUTTON) exit(0);
/* holding down left button allows user to rotate cube */
if(button==GLUT_LEFT_BUTTON)
switch(state) {
case GLUT_DOWN:
trackingMouse = true;
startX = x;
startY = y;
curx = x;
cury = y;
trackball_ptov(x, y, 512, 512, lastPos);
break;
case GLUT_UP:
trackingMouse = false;
angle = 0.0;
break;
}
}
void mouseMotion(int x, int y) {
float curPos[3], dx, dy, dz;
/* compute position on hemisphere */
if(trackingMouse) {
/* compute the change in position on the hemisphere */
trackball_ptov(x, y, 512, 512, curPos);
dx = curPos[0] - lastPos[0];
dy = curPos[1] - lastPos[1];
dz = curPos[2] - lastPos[2];
if (dx || dy || dz) {
/* compute theta and cross product */
angle = 90.0 * sqrt(dx*dx + dy*dy + dz*dz);
axis[0] = lastPos[1]*curPos[2] - lastPos[2]*curPos[1];
axis[1] = lastPos[2]*curPos[0] - lastPos[0]*curPos[2];
axis[2] = lastPos[0]*curPos[1] - lastPos[1]*curPos[0];
/* update position */
lastPos[0] = curPos[0];
lastPos[1] = curPos[1];
lastPos[2] = curPos[2];
}
float w = angle;
float x = axis[0];
float y = axis[1];
float z = axis[2];
glm::mat4 xform = glm::mat4((1.F - (2.F * ( y*y + z*z ))),(2.F * ( x*y - z*w )),( x*z + y*w ),0.F,
(2.F * ( x*y + z*w )),(1.F - (2.F * ( x*x + z*z ))),(2.F * ( y*z - x*w )),0.F,
(2.F * ( x*z - y*w )),(2.F * ( y*z + x*w )),(1.F - (2.F * ( x*x + y*y ))),0.F,
0.F,0.F,0.F,1.F);
model = xform*model;
}
glutPostRedisplay();
}
int main(int argc, char **argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(512, 512);
glutCreateWindow("Color Cube");
glewInit();
init();
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
glutIdleFunc(display);
glutMouseFunc(mouseButton);
glutMotionFunc(mouseMotion);
glutMainLoop();
return 0;
}
Here is the fshader36 file that was requested.
#version 150
in vec4 color;
out vec4 fColor;
void main()
{
fColor = color;
}
here is VSHADER
#version 330
uniform mat4 mvp;
layout(location=0) in vec4 vPosition;
layout(location=1) in vec4 vColor;
out vec4 color;
void main() {
color = vColor;
gl_Position = mvp * vPosition;
}