Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 3 FirstFirst 123 LastLast
Results 11 to 20 of 26

Thread: Texture Mapping Issue

  1. #11
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,856
    Quote Originally Posted by devmane144 View Post
    I actually am not using quads. I use triangles because
    In which case, the issue wasn't what I suggested. For a triangle the mapping is automatically affine; it cannot be otherwise.

  2. #12
    Intern Newbie
    Join Date
    Jun 2015
    Posts
    38
    Quote Originally Posted by GClements View Post
    In which case, the issue wasn't what I suggested. For a triangle the mapping is automatically affine; it cannot be otherwise.
    So if I changed all of my geometry to quads, would it stop warping the textures?

  3. #13
    Intern Contributor
    Join Date
    Jun 2012
    Posts
    75
    No, GClements was saying that if the geometry were quads, it could be causing the problem. If it's all tris the mapping shouldn't be non-affine.

  4. #14
    Intern Newbie
    Join Date
    Jun 2015
    Posts
    38
    Quote Originally Posted by fiodis View Post
    No, GClements was saying that if the geometry were quads, it could be causing the problem. If it's all tris the mapping shouldn't be non-affine.
    So I used some other UVs from here to see if it was something to do with my obj loader. The UV's aren't loaded incorrectly. Also adding
    Code :
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    didn't work either. I keep on seeing the affine problem. But if you're correct the triangles I'm rendering shouldn't have that problem, correct? So my second find was that projection matrices can mess this up, but I was under the impression that GLM was pretty stable. I looked into 4d texture mapping, but I'm not quite sure where to even begin to try to use that.

    Devmane144

  5. #15
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,856
    Quote Originally Posted by devmane144 View Post
    So I used some other UVs from here to see if it was something to do with my obj loader. The UV's aren't loaded incorrectly.
    It shouldn't matter if they were. So long as the data is constant, and the geometry consists of triangles, there really isn't anything which should cause the texture to warp like that.

    Quote Originally Posted by devmane144 View Post
    Also adding
    Code :
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    didn't work either.
    .
    In theory, that setting could be relevant. In practice, every OpenGL implementation does perspective-correct interpolation (unless you're using a shader which specifically uses the "noperspective" qualifier).

    Quote Originally Posted by devmane144 View Post
    So my second find was that projection matrices can mess this up,
    Just be be sure, try changing the transpose parameter in the glUniformMatrix4fv() call to GL_TRUE (a typical perspective projection is close to being symmetric about the main diagonal, so it's possible that a transposed matrix could result in something that was merely "odd" rather than completely unrecognisable).

    Quote Originally Posted by devmane144 View Post
    I looked into 4d texture mapping, but I'm not quite sure where to even begin to try to use that.
    It's not useful unless you're performing texture projection (e.g. trying to re-create the effect of a projector or a flashlight).

  6. #16
    Intern Newbie
    Join Date
    Jun 2015
    Posts
    38
    Quote Originally Posted by GClements View Post
    (unless you're using a shader which specifically uses the "noperspective" qualifier)
    I don't even think I can possibly do this using glsl 120 can I? Unless of course I did some voodoo black magic. I've read that using the varying keyword might bug it out but I don't really think that plays a big role in this.

    Quote Originally Posted by GClements View Post
    try changing the transpose parameter in the glUniformMatrix4fv() call to GL_TRUE
    I'd have to say that this did indeed turn out "odd"

    I'm just not sure where to go from here to be honest, I've done a lot of searching. I'm not thinking it's the filtering of the textures at all; that only affects the clarity of the image as far as I can see. Do you think it could be a driver issue that's fixable without buying new hardware?

  7. #17
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,856
    Quote Originally Posted by devmane144 View Post
    I'm just not sure where to go from here to be honest, I've done a lot of searching. I'm not thinking it's the filtering of the textures at all; that only affects the clarity of the image as far as I can see.
    You could try disabling filtering (i.e. setting both the min/mag filters to GL_NEAREST), just to check.

    Quote Originally Posted by devmane144 View Post
    Do you think it could be a driver issue that's fixable without buying new hardware?
    I would assume that it's an issue in your code. You don't appear to be doing anything unusual, yet the driver presumably works with other OpenGL programs.

    Try to simplify your program to the bare minimum amount of code which still exhibits the problem (in particular, get rid of all of the OOP stuff), then post the complete code. When the issue isn't apparent, often it's because it's not actually in the portion of the code which was posted.

  8. #18
    Intern Newbie
    Join Date
    Jun 2015
    Posts
    38
    Quote Originally Posted by GClements View Post
    You could try disabling filtering (i.e. setting both the min/mag filters to GL_NEAREST), just to check.


    I would assume that it's an issue in your code. You don't appear to be doing anything unusual, yet the driver presumably works with other OpenGL programs.

    Try to simplify your program to the bare minimum amount of code which still exhibits the problem (in particular, get rid of all of the OOP stuff), then post the complete code. When the issue isn't apparent, often it's because it's not actually in the portion of the code which was posted.
    Okay, so I took an hour or two today to isolate the code with my OpenGL involved. I also decided that it was best to just hard code the attribute coordinates rather than include all of the OBJ loader code. Here's the code:

    Vertex Shader

    Code :
    #version 120
    attribute vec3 verPos;
    attribute vec2 UV;
     
    varying vec2 f_UV;
     
    uniform mat4 MVP;
     
    void main()
    {     
        vec4 v = vec4(verPos, 1.0);
    	v = MVP * v;
        gl_Position = v;
        f_UV = UV;
    }

    Fragment Shader
    Code :
    #version 120
     
    uniform sampler2D TextSamp2D;
    varying vec2 f_UV;
     
    void main()
    {
        gl_FragColor = texture2D(TextSamp2D, f_UV);
    }

    And here is the major bulky code that is the main file. In the zip I've included it's example.cpp:

    Code :
    #include <fstream>
    #include <string>
    #include <vector>
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    #include <cmath>
    #define GLM_FORCE_RADIANS
    #include <glm/gtc/matrix_transform.hpp>
    #include <glm/gtx/transform.hpp>
    #include <glm/vec3.hpp>
    #include <glm/vec2.hpp>
    #include <glm/gtx/euler_angles.hpp>
    #include <glm/gtc/quaternion.hpp>
    #include <glm/gtx/quaternion.hpp>
     
    #include <SDL2/SDL.h>
    #include <GL/glew.h>
    #include <GL/glu.h>
    #include <SDL2/SDL_opengl.h>
    #include "SDL2/SDL_image.h"
    #include "SOIL/SOIL.h"
     
    bool initGL();
    void close();
    void Move();
    GLuint loadImage(const char*);
    GLuint LoadShaders(const char*, const char*);
     
    //The window we'll be rendering to
    SDL_Window* window = NULL;
     
    SDL_GLContext glContext;
     
    //Screen dimension constants
    bool gameRunning = true;                       
    bool arrows[] = {0, 0, 0, 0};
     
    GLuint programID;
     
    glm::vec3 direction;
    glm::vec3 myPos;
    glm::vec3 myAngle;
    glm::vec3 forwardVec;
     
    glm::mat4 projectionMatrix = glm::perspective(glm::radians(45.0f), 4.0f / 3.0f, 0.1f, 1000.0f);
    glm::mat4 viewMatrix = glm::mat4(1.0f);
     
    int main(int argc, char* args[]){
        if(SDL_Init(SDL_INIT_VIDEO) < 0){
    		std::cout << "Init Error: " << SDL_GetError() << std::endl;
            gameRunning = false;
    	}
     
        window = SDL_CreateWindow("Eximius", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
     
    	if(window == NULL){
    	    printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
            gameRunning = false;
    	}
    	if(!initGL()){
    		std::cout << "OpenGL Init Failed" << std::endl;
            gameRunning = false;
    	}
     
        SDL_Event e;
     
        programID = LoadShaders("vshade.txt", "fshade.txt");
     
        myPos.y = 0.0f;
     
        static const GLfloat g_vertex_buffer_data[] = { 
    		-1.0f,-1.0f,-1.0f,
    		-1.0f,-1.0f, 1.0f,
    		-1.0f, 1.0f, 1.0f,
    		 1.0f, 1.0f,-1.0f,
    		-1.0f,-1.0f,-1.0f,
    		-1.0f, 1.0f,-1.0f,
    		 1.0f,-1.0f, 1.0f,
    		-1.0f,-1.0f,-1.0f,
    		 1.0f,-1.0f,-1.0f,
    		 1.0f, 1.0f,-1.0f,
    		 1.0f,-1.0f,-1.0f,
    		-1.0f,-1.0f,-1.0f,
    		-1.0f,-1.0f,-1.0f,
    		-1.0f, 1.0f, 1.0f,
    		-1.0f, 1.0f,-1.0f,
    		 1.0f,-1.0f, 1.0f,
    		-1.0f,-1.0f, 1.0f,
    		-1.0f,-1.0f,-1.0f,
    		-1.0f, 1.0f, 1.0f,
    		-1.0f,-1.0f, 1.0f,
    		 1.0f,-1.0f, 1.0f,
    		 1.0f, 1.0f, 1.0f,
    		 1.0f,-1.0f,-1.0f,
    		 1.0f, 1.0f,-1.0f,
    		 1.0f,-1.0f,-1.0f,
    		 1.0f, 1.0f, 1.0f,
    		 1.0f,-1.0f, 1.0f,
    		 1.0f, 1.0f, 1.0f,
    		 1.0f, 1.0f,-1.0f,
    		-1.0f, 1.0f,-1.0f,
    		 1.0f, 1.0f, 1.0f,
    		-1.0f, 1.0f,-1.0f,
    		-1.0f, 1.0f, 1.0f,
    		 1.0f, 1.0f, 1.0f,
    		-1.0f, 1.0f, 1.0f,
    		 1.0f,-1.0f, 1.0f
    	};
     
        static const GLfloat g_uv_buffer_data[] = { 
    		0.000059f, 1.0f-0.000004f, 
    		0.000103f, 1.0f-0.336048f, 
    		0.335973f, 1.0f-0.335903f, 
    		1.000023f, 1.0f-0.000013f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.999958f, 1.0f-0.336064f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.336024f, 1.0f-0.671877f, 
    		0.667969f, 1.0f-0.671889f, 
    		1.000023f, 1.0f-0.000013f, 
    		0.668104f, 1.0f-0.000013f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.000059f, 1.0f-0.000004f, 
    		0.335973f, 1.0f-0.335903f, 
    		0.336098f, 1.0f-0.000071f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.335973f, 1.0f-0.335903f, 
    		0.336024f, 1.0f-0.671877f, 
    		1.000004f, 1.0f-0.671847f, 
    		0.999958f, 1.0f-0.336064f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.668104f, 1.0f-0.000013f, 
    		0.335973f, 1.0f-0.335903f, 
    		0.667979f, 1.0f-0.335851f, 
    		0.335973f, 1.0f-0.335903f, 
    		0.668104f, 1.0f-0.000013f, 
    		0.336098f, 1.0f-0.000071f, 
    		0.000103f, 1.0f-0.336048f, 
    		0.000004f, 1.0f-0.671870f, 
    		0.336024f, 1.0f-0.671877f, 
    		0.000103f, 1.0f-0.336048f, 
    		0.336024f, 1.0f-0.671877f, 
    		0.335973f, 1.0f-0.335903f, 
    		0.667969f, 1.0f-0.671889f, 
    		1.000004f, 1.0f-0.671847f, 
    		0.667979f, 1.0f-0.335851f
    	};
        GLuint vBuffer;
    	glGenBuffers(1, &vBuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, vBuffer);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
     
    	GLuint uvBuffer;
    	glGenBuffers(1, &uvBuffer);
    	glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
    	glBufferData(GL_ARRAY_BUFFER, sizeof(g_uv_buffer_data), g_uv_buffer_data, GL_STATIC_DRAW);
     
        GLuint tex;
        tex = loadImage("uvtemplate.tga");
     
        GLuint verPosAttrib = glGetAttribLocation(programID, "verPos");
    	GLuint UVAttrib = glGetAttribLocation(programID, "UV");
        GLuint sampID = glGetAttribLocation(programID, "TextSamp2D");
        GLuint mvpID = glGetUniformLocation(programID, "MVP");
        float i = 0.0f;
     
        myPos.z = 20.0f;
        while(gameRunning){
            Move();
     
            forwardVec = glm::vec3(-sin(glm::radians(myAngle.y)), 0.0f, -cos(glm::radians(myAngle.y)));
            glUseProgram(programID);
     
            viewMatrix = glm::lookAt(myPos, myPos + forwardVec, glm::vec3(0,1,0));
     
            glDepthMask(GL_TRUE);
     
            glUniform1i(sampID, 0);
     
            glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);     
     
            //Just the scale of the model matrix
            glm::mat4 modelScale = glm::scale(glm::vec3(5.0f, 5.0f, 5.0f));
            i += 0.01f;
            glm::quat myQuat;
            myQuat = glm::quat(myAngle);
            glm::mat4 modelRot = glm::eulerAngleYXZ(i, 0.0f, 0.0f);
     
            glm::mat4 model = modelScale * modelRot;
            glm::mat4 MVP = projectionMatrix * viewMatrix * model;
            glUniformMatrix4fv(mvpID, 1, GL_FALSE, &MVP[0][0]);
     
            glEnableVertexAttribArray(verPosAttrib);
            glBindBuffer(GL_ARRAY_BUFFER, vBuffer);
            glVertexAttribPointer(
                verPosAttrib, 
                3, 
                GL_FLOAT,
                GL_FALSE,
                0, 
                (GLvoid*)0
            );
     
            glEnableVertexAttribArray(UVAttrib);
            glBindBuffer(GL_ARRAY_BUFFER, uvBuffer);
            glVertexAttribPointer(
                UVAttrib,
                2, 
                GL_FLOAT,
                GL_FALSE,
                0, 
                (GLvoid*)0
            );
     
            glActiveTexture(GL_TEXTURE0 + 0);
            glBindTexture(GL_TEXTURE_2D, tex);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     
            glDrawArrays(GL_TRIANGLES, 0, 36);
     
            SDL_GL_SwapWindow(window);
     
            glDisableVertexAttribArray(verPosAttrib);
            glDisableVertexAttribArray(UVAttrib);
     
            while(SDL_PollEvent(&e) != 0){
                if(e.type == SDL_QUIT){
                    gameRunning = false;
                }
                else if(e.type == SDL_KEYDOWN){
                    switch(e.key.keysym.sym){
                        case SDLK_DOWN:
                            arrows[3] = true;
                        break;
                        case SDLK_LEFT:
                            arrows[2] = true;
                        break;
                        case SDLK_RIGHT:
                            arrows[0] = true;
                        break;
                        case SDLK_UP:
                            arrows[1] = true;
                        break;
                    }
                }
                else if(e.type == SDL_KEYUP){
                    switch(e.key.keysym.sym){
                        case SDLK_DOWN:
                            arrows[3] = false;
                        break;
                        case SDLK_LEFT:
                            arrows[2] = false;
                        break;
                        case SDLK_RIGHT:
                            arrows[0] = false;
                        break;
                        case SDLK_UP:
                            arrows[1] = false;
                        break;
                    }
                }
            }
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        }
    	close();
    	return 0;
    }
    bool initGL(){
    	glContext = SDL_GL_CreateContext(window);
     
        if(glContext == NULL){
            std::cout << "OpenGL context Failed: " << SDL_GetError() << std::endl;
    		return false;
        }
     
        glewExperimental = GL_TRUE;
        GLenum err = glewInit();
        if(GLEW_OK != err){
            std::cout << "GLEW FAILED" << glewGetErrorString(err) << std::endl;
            return false;
        }
        if(glewIsSupported("GL_VERSION_4_0")){
            printf("Ready for OpenGL 4.0\n");
        }
     
        GLuint vaID;
        glGenVertexArrays(1, &vaID);
        glBindVertexArray(vaID);
     
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
        SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
     
        SDL_GL_SetSwapInterval(1);
        SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
     
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
     
        glEnable(GL_DEPTH_TEST);
        glShadeModel(GL_SMOOTH);
        glDepthFunc(GL_LEQUAL);
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
     
    	return true;
    }
    void close(){
        //Destroy window
    	SDL_DestroyWindow(window);
        SDL_GL_DeleteContext(glContext);
    	//IMG_Quit();
    	SDL_Quit();
    }
    GLuint loadImage(const char * image){
        GLuint texID;
        glActiveTexture(GL_TEXTURE_2D);
     
        texID = SOIL_load_OGL_texture(image, SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB);
        glBindTexture(GL_TEXTURE_2D, texID);
     
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     
        if(texID == 0){
            std::cout << "FAILED TO LOAD TEXTURE" << std::endl;
        }
        else return texID;
    }
     
    GLuint LoadShaders(const char * vertexFPath, const char * fragmentFPath){
        GLuint vSID = glCreateShader(GL_VERTEX_SHADER);
        GLuint fSID = glCreateShader(GL_FRAGMENT_SHADER);
     
        std::string VertexShaderCode;
        std::ifstream VertexShaderStream(vertexFPath, std::ios::in);
        if(VertexShaderStream.is_open()){
            std::string Line = "";
            while(getline(VertexShaderStream, Line))
                VertexShaderCode += "\n" + Line;
            VertexShaderStream.close();
        }
        std::string FragmentShaderCode;
        std::ifstream FragmentShaderStream(fragmentFPath, 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;
     
        std::cout << "Compiling Shader: " << vertexFPath << std::endl;
        char const * VSource = VertexShaderCode.c_str();
        glShaderSource(vSID, 1, &VSource, NULL);
        glCompileShader(vSID);
     
        glGetShaderiv(vSID, GL_COMPILE_STATUS, &Result);
        glGetShaderiv(vSID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        std::vector<char> VertexShaderErrorMessage(InfoLogLength);
        glGetShaderInfoLog(vSID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
        fprintf(stdout, "%s\n", &VertexShaderErrorMessage[0]);
     
     
        std::cout << "Compiling Shader: " << fragmentFPath << std::endl;
        char const * FSource = FragmentShaderCode.c_str();
        glShaderSource(fSID, 1, &FSource, NULL);
        glCompileShader(fSID);
     
        glGetShaderiv(fSID, GL_COMPILE_STATUS, &Result);
        glGetShaderiv(fSID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        std::vector<char> FragmentShaderErrorMessage(InfoLogLength);
        glGetShaderInfoLog(fSID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
        fprintf(stdout, "%s\n", &FragmentShaderErrorMessage[0]);
     
        std::cout << "Linking Program" << std::endl;
        GLuint ProgramID = glCreateProgram();
        glAttachShader(ProgramID, vSID);
        glAttachShader(ProgramID, fSID);
        glLinkProgram(ProgramID);
     
        glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
        glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
        std::vector<char> ProgramErrorMessage(std::max(InfoLogLength, int(1)));
        glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
        fprintf(stdout, "%s\n", &ProgramErrorMessage[0]);
     
        glDeleteShader(vSID);
        glDeleteShader(fSID);
        return ProgramID;
    }
     
    void Move(){
        if(arrows[0]){
            myAngle -= glm::radians(45.f);
        }
        if(arrows[1]){
            myPos = myPos + forwardVec * 0.2f;
        }
        if(arrows[2]){
           myAngle.y += glm::radians(45.f);
        }
        if(arrows[3]){
            myPos = myPos - forwardVec * 0.2f;
        }
    }

    And now that we've reached the end of that nightmare of a copy and paste.......

    All of the code files and a makefile are included with this zip. It should run on Linux as long as all of the libraries it needs are there. It should include SOIL, OpenGL, SDL, GLM, SDL_image, GLEW, and GLU.
    Attached Files Attached Files

  9. #19
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,856
    Quote Originally Posted by devmane144 View Post
    Okay, so I took an hour or two today to isolate the code with my OpenGL involved.
    That works fine for me (Linux/x86-64, Mesa 10.3.7). You're getting texture warping?

  10. #20
    Intern Newbie
    Join Date
    Jun 2015
    Posts
    38
    Quote Originally Posted by GClements View Post
    That works fine for me (Linux/x86-64, Mesa 10.3.7). You're getting texture warping?
    I am. However, have you used the arrow keys to move around at all? If you get a bit closer, the issue is more apparent. If you just tap the forward arrow a bit it'll get you close enough. (Depending on hardware you might overshoot it by like 3000 miles....) It's really subtle with that particular texture. With other ones I've had "lava" effects as my friend told me.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •