GLSL / OpenGL / C ++ - 正常映射问题

时间:2014-02-18 20:35:44

标签: c++ opengl glsl sdl

正如标题所说,我遇到了正常映射的麻烦。首先,有点背景......

我正在使用LWJGL关注TheCPlusPlusGuy的教程,并遇到了错误。我在这里贴了一篇帖子,但没有回复。然后我转入C ++,再次回到正常映射,发现更多问题。问题是,当我在X轴上移动时,光看起来像是在Y轴上移动一样移动。我已经将常规地图纹理渲染为常规纹理,并且它正常工作,因此错误应该在着色器中。

我在YouTube here上制作了一个关于该错误的视频。

以下是代码:

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);
}

以防万一,main.cpp(注意functions.h只是第一人称相机):

#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;
}

And the normal map I'm using (shrunk down)

0 个答案:

没有答案