C+中的SDL-OpenGL+;,纹理着色器缺少纹理

C+中的SDL-OpenGL+;,纹理着色器缺少纹理,opengl,sdl,texture-mapping,fragment-shader,vertex-shader,Opengl,Sdl,Texture Mapping,Fragment Shader,Vertex Shader,我正在尝试创建我的第一个OpenGL着色器,但在尝试向立方体对象添加纹理时遇到了困难 是否有人有足够敏锐的眼光来发现错误?代码可能有很多错误,如果有人指出这些错误,我很感激,但我最感兴趣的是为什么我的旋转立方体是灰色而不是彩色的 (我已经跳过了所有错误处理,以保持源代码的大小较低,对此表示抱歉) **编辑发现我错过了一些UV设置,但仍然是灰色立方体 #include <windows.h> #include <SDL.h> #include <GL/glew.h&

我正在尝试创建我的第一个OpenGL着色器,但在尝试向立方体对象添加纹理时遇到了困难

是否有人有足够敏锐的眼光来发现错误?代码可能有很多错误,如果有人指出这些错误,我很感激,但我最感兴趣的是为什么我的旋转立方体是灰色而不是彩色的

(我已经跳过了所有错误处理,以保持源代码的大小较低,对此表示抱歉)

**编辑发现我错过了一些UV设置,但仍然是灰色立方体

#include <windows.h>
#include <SDL.h>

#include <GL/glew.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <math.h>
#include <string>

using namespace std;

void            initAll();
void            setupBox();
void            mainloop();
unsigned int    generateTexture();
void            handle_inputs();
void            updateScreen();
void            clean_up();

int             scrWidth, scrHeight, flags;
bool            bQuit = false;
float           angle = 0.0f;

GLuint          tex_Box, tex_Norm;

std::string     vertex_source, fragment_source;
GLuint          shader_program, vertex_shader, fragment_shader;

// vao and vbo handle
GLuint          vao, vbo;

const char      *source;
int             length;

struct sVert
{
    float x;
    float y;
    float z;
};

class cPolygon
{
public:
    int v[4];

    void fillverts(int v1, int v2, int v3, int v4) {
        v[0] = v1;
        v[1] = v2;
        v[2] = v3;
        v[3] = v4;
    }
} p[6];

sVert pv[8];

int main(int argc, char *argv[])
{
    initAll();
    mainloop();
    clean_up();
    return 0;
}

void initAll()
{
    scrWidth = 800;
    scrHeight = 600;

    vertex_source =
        "#version 330\n"
        "layout (location = 0) in vec3 Position;\n"
        "layout (location = 1) in vec2 TexCoord;\n"
        "void main() {\n"
        "   gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n" 
        "   gl_TexCoord[0] = gl_MultiTexCoord0;\n"
        "}\n";

    fragment_source =
        "#version 330\n"
        "uniform sampler2D tex;\n"
        "void main() {\n"
        "   FragColor = texture2D(tex, gl_TexCoord[0].st);\n"
        "}\n";

    SDL_InitSubSystem(SDL_INIT_VIDEO);
    SDL_GL_SetAttribute( SDL_GL_ALPHA_SIZE, 8 );
    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, 16 );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

    flags = SDL_OPENGL | SDL_ANYFORMAT ;

    SDL_SetVideoMode(scrWidth, scrHeight, 16, flags);

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity( );
    gluPerspective( 45.0f, (GLfloat)scrWidth/(GLfloat)scrHeight, 1.0f, 500.0f );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity( );

    glEnable (GL_DEPTH_TEST);
    glEnable (GL_LIGHTING);
    glEnable (GL_LIGHT0);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_COLOR, GL_ONE_MINUS_SRC_ALPHA);

    SDL_WM_SetCaption( "Texture Shader", NULL );

    glewInit();

    // Vertex shader
    vertex_shader = glCreateShader(GL_VERTEX_SHADER);
    source = vertex_source.c_str();
    length = vertex_source.size();
    glShaderSource(vertex_shader, 1, &source, &length); 
    glCompileShader(vertex_shader);

    // Fragment shader
    fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
    source = fragment_source.c_str();
    length = fragment_source.size();
    glShaderSource(fragment_shader, 1, &source, &length);
    glCompileShader(fragment_shader);

    // create program
    shader_program = glCreateProgram();
    glAttachShader(shader_program, vertex_shader);
    glAttachShader(shader_program, fragment_shader);
    glLinkProgram(shader_program);

    glGenVertexArrays(1, &vao);
    glBindVertexArray(vao);

    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    setupBox();

    GLfloat vd[6*5*6];

    for(int pi=0; pi<6; pi++)
    {
        vd[pi*30+ 0] = pv[ p[pi].v[0] ].x;
        vd[pi*30+ 1] = pv[ p[pi].v[0] ].y;
        vd[pi*30+ 2] = pv[ p[pi].v[0] ].z;

        vd[pi*30+ 3] = 0.0;
        vd[pi*30+ 4] = 1.0;

        vd[pi*30+ 5] = pv[ p[pi].v[1] ].x;
        vd[pi*30+ 6] = pv[ p[pi].v[1] ].y;
        vd[pi*30+ 7] = pv[ p[pi].v[1] ].z;

        vd[pi*30+ 8] = 0.0;
        vd[pi*30+ 9] = 0.0;

        vd[pi*30+10] = pv[ p[pi].v[2] ].x;
        vd[pi*30+11] = pv[ p[pi].v[2] ].y;
        vd[pi*30+12] = pv[ p[pi].v[2] ].z;

        vd[pi*30+13] = 1.0;
        vd[pi*30+14] = 0.0;

        vd[pi*30+15] = pv[ p[pi].v[0] ].x;
        vd[pi*30+16] = pv[ p[pi].v[0] ].y;
        vd[pi*30+17] = pv[ p[pi].v[0] ].z;

        vd[pi*30+18] = 0.0;
        vd[pi*30+19] = 1.0;

        vd[pi*30+20] = pv[ p[pi].v[2] ].x;
        vd[pi*30+21] = pv[ p[pi].v[2] ].y;
        vd[pi*30+22] = pv[ p[pi].v[2] ].z;

        vd[pi*30+23] = 1.0;
        vd[pi*30+24] = 0.0;

        vd[pi*30+25] = pv[ p[pi].v[3] ].x;
        vd[pi*30+26] = pv[ p[pi].v[3] ].y;
        vd[pi*30+27] = pv[ p[pi].v[3] ].z;

        vd[pi*30+28] = 1.0;
        vd[pi*30+29] = 1.0;
    }

    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*6*5*6, vd, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (char*)0 + 0*sizeof(GLfloat));
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), (char*)0 + 3*sizeof(GLfloat));

    tex_Box = generateTexture();
    tex_Norm = generateTexture();
}

void setupBox()
{
    for (int z=0;z<2;z++)
    for (int y=0;y<2;y++)
    for (int x=0;x<2;x++)
    {
        pv[x+y*2+z*4].x = -1.0+x;
        pv[x+y*2+z*4].y = -1.0+y;
        pv[x+y*2+z*4].z = -1.0+z;
    }

    p[0].fillverts (0, 1, 3, 2);    // above
    p[1].fillverts (4, 5, 1, 0);    // behind
    p[2].fillverts (6, 7, 3, 2);    // in front
    p[3].fillverts (5, 7, 3, 1);    // right
    p[4].fillverts (0, 2, 6, 4);    // left
    p[5].fillverts (7, 6, 4, 5);    // below
}

unsigned int generateTexture()
{
    BYTE    data[128*128*3];
    unsigned int id;

    for (int x=0;x<128;x++)
        for (int y=0;y<128;y++)
        {
            data[y*128*3+x*3+0] = x;        // Red
            data[y*128*3+x*3+1] = y;        // Green
            data[y*128*3+x*3+2] = 128-(abs(64-x)+abs(64-y));    // Blue
        }

    glGenTextures(1, &id); 
    glBindTexture(GL_TEXTURE_2D, id); 
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);

    return id;
}

void mainloop()
{
    while(bQuit == false)
    {
        handle_inputs();
        updateScreen();
        angle += 1.5f;
        Sleep(50);
    }
}

void handle_inputs()
{
    SDL_PumpEvents();
    Uint8 * keystate = SDL_GetKeyState(NULL);
    if(keystate[SDLK_ESCAPE]) bQuit = true;
}

void updateScreen()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    gluLookAt (2.0, 2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
    glUseProgram(shader_program);
    glBindVertexArray(vao);

    glRotatef(angle, 1.0, 0.0, 0.0); //rotate on the x axis
    glRotatef(angle, 0.0, 1.0, 0.0); //rotate on the y axis
    glRotatef(angle, 0.0, 0.0, 1.0); //rotate on the z axis

    glActiveTexture(GL_TEXTURE0);
    int loc = glGetUniformLocation(shader_program, "tex");
    glUniform1i(loc, 0);
    glBindTexture(GL_TEXTURE_2D, tex_Box);
    glDrawArrays(GL_TRIANGLES, 0, 6*6);
    //glutSolidTeapot(2.0);
    glUseProgram(0);
    SDL_GL_SwapBuffers();
}

void clean_up()
{
    glDeleteVertexArrays(1, &vao);
    glDeleteBuffers(1, &vbo);

    glDetachShader(shader_program, vertex_shader);
    glDetachShader(shader_program, fragment_shader);
    glDeleteShader(vertex_shader);
    glDeleteShader(fragment_shader);
    glDeleteProgram(shader_program);

    SDL_QuitSubSystem(SDL_INIT_VIDEO);
    glDeleteTextures(1, &tex_Box);
    glDeleteTextures(1, &tex_Norm);
    SDL_Quit();
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
void initAll();
void setupBox();
void mainloop();
无符号int-generateTexture();
无效句柄_输入();
void updateScreen();
无效清除();
国际跑道、跑道、旗帜;
bool bkuit=假;
浮动角度=0.0f;
胶合特克斯盒,特克斯标准;
字符串顶点源,片段源;
GLuint着色器程序、顶点着色器、片段着色器;
//vao和vbo手柄
GLuint vao,vbo;
常量字符*源;
整数长度;
结构sVert
{
浮动x;
浮动y;
浮动z;
};
类cPolygon
{
公众:
int v[4];
无效填充顶点(int v1、int v2、int v3、int v4){
v[0]=v1;
v[1]=v2;
v[2]=v3;
v[3]=v4;
}
}p[6];
sVert-pv[8];
int main(int argc,char*argv[])
{
initAll();
mainloop();
清理;
返回0;
}
void initAll()
{
scrWidth=800;
scrHeight=600;
顶点源=
“#版本330\n”
“布局(位置=0)在vec3位置;\n”
“vec2 TexCoord中的布局(位置=1);\n”
“void main(){\n”
“gl_位置=gl_模型视图投影矩阵*gl_顶点;\n”
“gl_TexCoord[0]=gl_MultiTexCoord0;\n”
“}\n”;
碎片源=
“#版本330\n”
“均匀采样2D tex;\n”
“void main(){\n”
FragColor=texture2D(tex,gl_TexCoord[0].st);\n
“}\n”;
SDL_初始化子系统(SDL_初始化视频);
SDL_GL_SetAttribute(SDL_GL_ALPHA_大小,8);
SDL_GL_设置属性(SDL_GL_红色_大小,8);
SDL_GL_设置属性(SDL_GL_绿色_大小,8);
SDL_GL_SetAttribute(SDL_GL_BLUE_大小,8);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,16);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
flags=SDL_OPENGL | SDL_ANYFORMAT;
SDL_设置视频模式(scrWidth、scrHeight、16、标志);
glMatrixMode(GL_投影);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)scrWidth/(GLfloat)scrHeight,1.0f,500.0f);
glMatrixMode(GLU模型视图);
glLoadIdentity();
glEnable(GLU深度试验);
glEnable(德国劳埃德大学照明);
glEnable(GL_LIGHT0);
glEnable(GL_混合物);
glBlendFunc(GL_SRC_COLOR,GL_ONE_减去SRC_ALPHA);
SDL_WM_SetCaption(“纹理着色器”,NULL);
glewInit();
//顶点着色器
顶点着色器=glCreateShader(GL顶点着色器);
source=vertex_source.c_str();
长度=顶点_源.size();
glShaderSource(顶点着色器,1,&源,&长度);
glCompileShader(顶点着色器);
//片段着色器
片段着色器=glCreateShader(GL片段着色器);
source=fragment_source.c_str();
长度=片段_source.size();
glShaderSource(片段着色器,1,&source,&length);
glCompileShader(片段着色器);
//创建程序
shader_program=glCreateProgram();
glAttachShader(着色器程序、顶点着色器);
glAttachShader(着色器程序,片段着色器);
GLLINK程序(shader_程序);
glGenVertexArrays(1和vao);
glBindVertexArray(vao);
glGenBuffers(1,&vbo);
glBindBuffer(GL_数组_BUFFER,vbo);
setupBox();
GLVD[6*5*6];

对于(int pi=0;pi您的片段着色器甚至不应该编译。您正在写入未解析的变量“FragColor”。您应该首先添加代码来检查编译和链接状态,并查询编译和链接日志,以便获得GLSL编译器/链接器检测到的所有错误和警告。您可以使用以下方法:

GLint status;
GLubyte log[LOG_SIZE];
// compile shader here
...
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
    // compile error
    ...
}
glGetShaderInfoLog(shader, LOG_SIZE, 0, log);
// print the log

...
// link the program here
// ...
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
    //  error
    ...
}
glGetProgramInfoLog(program, LOG_SIZE, 0, log);
// print the log
可能您只想在错误情况下打印信息日志,但即使在成功的情况下,也可能会有一些警告/提示,因此我建议您将其打印为alywas,至少在调试/开发构建中


我还建议您停止混用过时的内置软件,如
gl_TexCoord[0]
gl\u MultiTexCoord0
等等,都有现代用户定义的属性、输入和输出。目前,您没有使用您声明的
TexCoord
属性。

Yikes,我现在明白了!我完全忘记了UV coords,这是原因吗?谢谢!错误日志结合您的解释帮助我获得了它终于对了!我会接受你的答案并发布一个固定版本。投票可能会在这里,而不是在我的答案中。
GLint status;
GLubyte log[LOG_SIZE];
// compile shader here
...
glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
if (status != GL_TRUE) {
    // compile error
    ...
}
glGetShaderInfoLog(shader, LOG_SIZE, 0, log);
// print the log

...
// link the program here
// ...
glGetProgramiv(program, GL_LINK_STATUS, &status);
if (status != GL_TRUE) {
    //  error
    ...
}
glGetProgramInfoLog(program, LOG_SIZE, 0, log);
// print the log