简体   繁体   中英

OpenGL Core Profile won't texture quad

I wrote the following code to display two images on two different monitors using GLFW. When I try running OPENGL_CORE_PROFILE it screws up and my image doesn't appear.

Instead the screen just stays black. But when I don't use core profile the image shows up on the screen just fine. I need to use core profile so I can use OpenGL 3.3 and 330 shaders.

Is my current method I'm using to texture a quad is wrong what would be the best approach to display and image using OpenGL 3.3?

#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>

static GLuint tex_lite;
static GLuint tex_dark;

static GLuint tex_front;
static GLuint tex_back;

float ratio;
int width, height;

char *textFileRead(char *fn) {


    FILE *fp;
    char *content = NULL;

    int count=0;

    if (fn != NULL) {
        fp = fopen(fn,"rt");

        if (fp != NULL) {

      fseek(fp, 0, SEEK_END);
      count = ftell(fp);
      rewind(fp);

            if (count > 0) {
                content = (char *)malloc(sizeof(char) * (count+1));
                count = fread(content,sizeof(char),count,fp);
                content[count] = '\0';
            }
            fclose(fp);
        }
    }
    return content;
}

void printLog(GLuint obj)
{
    int infologLength = 0;
    int maxLength;

    if(glIsShader(obj))
        glGetShaderiv(obj,GL_INFO_LOG_LENGTH,&maxLength);
    else
        glGetProgramiv(obj,GL_INFO_LOG_LENGTH,&maxLength);

    char infoLog[maxLength];

    if (glIsShader(obj))
        glGetShaderInfoLog(obj, maxLength, &infologLength, infoLog);
    else
        glGetProgramInfoLog(obj, maxLength, &infologLength, infoLog);

    if (infologLength > 0)
        printf("%s\n",infoLog);
}

void image2texture(cv::Mat Image,GLuint &texName, int i)
{
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel(GL_FLAT);
    glEnable(GL_DEPTH_TEST);

    glActiveTexture(GL_TEXTURE0+i);
    glGenTextures(1, &texName);
    glBindTexture(GL_TEXTURE_2D, texName);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    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, 3, Image.cols, Image.rows, 0, GL_BGR,
                 GL_UNSIGNED_BYTE, Image.data);
}

static void error_callback(int error, const char* description)
{
    fputs(description, stderr);
}

GLuint linkShader(char* vert, char* frag)
{
    GLuint v,f,p;

    char *vs = NULL,*fs = NULL;

    v = glCreateShader(GL_VERTEX_SHADER);
    f = glCreateShader(GL_FRAGMENT_SHADER);

    vs = textFileRead(vert);
    fs = textFileRead(frag);

    const char * ff = fs;
    const char * vv = vs;

    glShaderSource(v, 1, &vv,NULL);
    glShaderSource(f, 1, &ff,NULL);

    free(vs);free(fs);

    glCompileShader(v);
    glCompileShader(f);

    p = glCreateProgram();
    glAttachShader(p,f);
    glAttachShader(p,v);

    glLinkProgram(p);

    return p;
}

static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
        glfwSetWindowShouldClose(window, GL_TRUE);
}

void checkWindow(GLFWwindow* window)
{
    if (!window)
    {
        glfwTerminate();
        exit(EXIT_FAILURE);
    }
}

int main(void)
{
    GLFWwindow* window_back;
    GLFWwindow* window_front;

    glfwSetErrorCallback(error_callback);

    if ( !glfwInit() )
    {
        exit(EXIT_FAILURE);
    }

    cv::Mat image_lite = cv::imread("lena.tiff");
    cv::Mat image_dark = cv::imread("lena.tiff");

    cv::flip(image_lite, image_lite, 0);
    cv::flip(image_dark, image_dark, 0);

    int count;
    GLFWmonitor** monitors = glfwGetMonitors(&count);

    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    if (count >= 2)
    {
        window_front = glfwCreateWindow(1680,1050,"Front Screen",monitors[0],NULL);
        window_back = glfwCreateWindow(1280,800,"Back Screen",monitors[1],NULL);
        glewInit();
    }
    else
    {
        exit(EXIT_FAILURE);
    }

    checkWindow(window_front);
    checkWindow(window_back);

    glfwMakeContextCurrent(window_front);
    glfwSetKeyCallback(window_front, key_callback);

    glewExperimental = GL_TRUE;
    GLenum err = glewInit();
    if(err!=GLEW_OK)
    {
        std::cout<<"glewInit failed, aborting."<<std::endl;
    }

    std::cout << glGetString(GL_RENDERER) << std::endl;
    std::cout << glGetString(GL_VENDOR) << std::endl;
    std::cout << glGetString(GL_VERSION) << std::endl;
    std::cout << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;

    while (!glfwWindowShouldClose(window_front) && !glfwWindowShouldClose(window_back))
    {

        glfwMakeContextCurrent(window_front);
        glfwSetKeyCallback(window_front, key_callback);

        glfwGetFramebufferSize(window_front, &width, &height);
        ratio = width / (float) height;
        glViewport(0,0,width,height);

        image2texture(image_lite, tex_lite,0);

        // GLuint prg = linkShader("toon.vert","toon.frag");

        glClear(GL_COLOR_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio,ratio,-1.f,1.f,-1.f,1.f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glActiveTexture(GL_TEXTURE0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_TEXTURE_2D);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
        glBindTexture(GL_TEXTURE_2D, tex_lite);

        glBegin(GL_QUADS);
            glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,-1.0,0.0);
            glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,1.0,0.0);
            glTexCoord2f(1.0, 1.0); glVertex3f(1.0,1.0,0.0);
            glTexCoord2f(1.0, 0.0); glVertex3f(1.0,-1.0,0.0);
        glEnd();     
        glFlush();
        glfwSwapBuffers(window_front);
        glfwPollEvents();

        glfwMakeContextCurrent(window_back);
        glfwSetKeyCallback(window_back, key_callback);

        glfwGetFramebufferSize(window_back, &width, &height);
        ratio = width / (float) height;
        glViewport(0,0,width,height);

        image2texture(image_dark, tex_dark,1);

        glClear(GL_COLOR_BUFFER_BIT);
        glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
        glOrtho(-ratio,ratio,-1.f,1.f,-1.f,1.f);
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        glActiveTexture(GL_TEXTURE0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glEnable(GL_TEXTURE_2D);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
        glBindTexture(GL_TEXTURE_2D, tex_lite);

        glBegin(GL_QUADS);
            glTexCoord2f(0.0, 0.0); glVertex3f(-1.0,-1.0,0.0);
            glTexCoord2f(0.0, 1.0); glVertex3f(-1.0,1.0,0.0);
            glTexCoord2f(1.0, 1.0); glVertex3f(1.0,1.0,0.0);
            glTexCoord2f(1.0, 0.0); glVertex3f(1.0,-1.0,0.0);
        glEnd();
        glFlush();
        glfwSwapBuffers(window_back);
        glfwPollEvents();
    }
    glfwMakeContextCurrent(window_front);
    glfwDestroyWindow(window_front);
    glfwMakeContextCurrent(window_back);
    glfwDestroyWindow(window_back);

    glfwTerminate();
    exit(EXIT_SUCCESS);
}

Your code is totally invalid in a core profile. In core profiles, all the old functionality which has been declared "deprecated" many years ago is actrually removed . GL_QUADS primitive types are not supported, immediate mode rendering with glBegin()/glEnd() is not supported, glEnable(GL_TEXTURE_2D); is not supported, builtin vertex attributes like the texcoord and vertex position are not supported and GL_TEXTURE_ENV_MODE is not supported, rendering without shaders ("fixed-function pipeline") in not supported. The same goes for glMatrixMode() , glLoadIdentity , glOrtho() and all other matrix and matrix stack related functions. The internal format "3" is also not supported for glTexImage2D() , you should use GL_RGB (which you should have used before, too).

When you want to use a modern core profile, you have to use the programmable pipeline with shaders and without all the builtin attributes. You have vo define your own generic attributes instead. You have to use VBOs for your geometry and VAOs for the vertex pointers instead of immediate mode. You also have to replace quad primitves by triangle-based primitives. You will have to use your own matrix functions, or use some library for that.

You might want to have a look at tutorials like arcsynthesis or open.gl which exclusively deal with modern OpenGL.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM