简体   繁体   English

OpenGL核心配置文件不会纹理四边形

[英]OpenGL Core Profile won't texture quad

I wrote the following code to display two images on two different monitors using GLFW. 我编写了以下代码,以使用GLFW在两个不同的监视器上显示两个图像。 When I try running OPENGL_CORE_PROFILE it screws up and my image doesn't appear. 当我尝试运行OPENGL_CORE_PROFILE时,它拧紧了并且我的图像没有出现。

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. 我需要使用核心配置文件,以便可以使用OpenGL 3.3和330着色器。

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? 我当前使用的对四边形进行纹理化的方法是错误的,什么是使用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); 不支持GL_QUADS基本类型,不支持使用glBegin()/glEnd()即时模式渲染, 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. 不支持,不支持内置的顶点属性,例如texcoord和顶点位置,并且不支持GL_TEXTURE_ENV_MODE ,不支持不GL_TEXTURE_ENV_MODE色器的渲染(“固定功能管线”)。 The same goes for glMatrixMode() , glLoadIdentity , glOrtho() and all other matrix and matrix stack related functions. glMatrixMode()glLoadIdentityglOrtho()以及所有其他矩阵和矩阵堆栈相关的函数也是如此。 The internal format "3" is also not supported for glTexImage2D() , you should use GL_RGB (which you should have used before, too). glTexImage2D()也不支持内部格式“ 3”,您应该使用GL_RGB (之前也应该使用)。

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. 您必须将VBO用于几何图形,并将VAO用于顶点指针,而不是立即模式。 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. 您可能需要看一下专门处理现代OpenGL的教程,例如arcsynthesisopen.gl。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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