【问题标题】:The file is loaded but the texture is not displayed文件已加载,但未显示纹理
【发布时间】:2021-05-03 12:47:42
【问题描述】:

我正在尝试制作 3D 射击游戏。我认为图像正在加载,因为它的尺寸已显示,但它没有显示为纹理。该程序编译并运行没有错误,但没有纹理。我不知道我在哪里做错了。

main.cpp:

#include "Functions.h"

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(wnd_width, wnd_height);
    glutInitWindowPosition(300, 100);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_NORMALIZE);
    glutCreateWindow("OpenGL my");
    glutDisplayFunc(display);
    glutIdleFunc(Idle);
    glutSpecialFunc(KeyPressed);
    TextureInit();
    glutMainLoop();
    return 0;
}

函数.h

#define STB_IMAGE_IMPLEMENTATION

#include <GL/glut.h>
#include <stb_image.h>
#include <iostream>
#include "point.h"
#include "camera.h"

int wnd_width=1300;
int wnd_height=900;
GLdouble aspect = wnd_width/wnd_height;
Camera cam;
unsigned int texture;
float text_coords[] = {0,0, 1,0, 1,1, 0,1};

void DrawFloor();
void DrawWall(float x, float width, float height);
void KeyPressed(int key, int x, int y);
void TextureInit();
void display();
void Idle();



void display(){
    glClearColor(0.6, 0.8, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90, aspect, 0.1, 3);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
              cam.view.x, cam.view.y, cam.view.z,
              0, 0.5, 0);

    glBegin(GL_QUADS);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, 0, text_coords);
    //glColor3f(0, 0, 0.7);
    DrawFloor();
    //glColor3f(0, 0.8, 0.1);
    DrawWall(-0.5, 2, 0.7);
    DrawWall(0.5, 2, 0.7);
    glEnd();
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glutSwapBuffers();
}

void Idle(){

}

void DrawFloor(){
    glVertex3d(1, 0, 2.5);
    glVertex3d(1, 0, 0);
    glVertex3d(-1, 0, 0);
    glVertex3d(-1, 0, 2.5);
}

void DrawWall(float x, float width, float height){
    glVertex3f(x, height, 0);
    glVertex3f(x, height, width);
    glVertex3f(x, 0, width);
    glVertex3f(x, 0, 0);
}

void KeyPressed(int key, int x, int y){
    switch (key) {
    case GLUT_KEY_UP: { cam.MoveForward(); break; }
    case GLUT_KEY_DOWN: { cam.MoveBack(); break; }
    case GLUT_KEY_LEFT: {cam.TurnLeft(); break; }
    case GLUT_KEY_RIGHT: {cam.TurnRight(); break; }
    }
    cam.PrintPosition();
    glutPostRedisplay();
}

void TextureInit(){
    int width, height, cnt;
    unsigned char* data = stbi_load("whitemarble.jpg", &width, &height, &cnt, 0);
    if(data==nullptr) std::cout<< "NO\n";
    else std::cout<<width<<'\t'<<height<<'\n';
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    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_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height,
                 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glBindTexture(GL_TEXTURE_2D, 0);
    stbi_image_free(data);
}

重做。现在它起作用了。谢谢。但是画面很拉长。

#define STB_IMAGE_IMPLEMENTATION
#include <GL/glut.h>
#include <stb_image.h>
#include <iostream>
#include "point.h"
#include "camera.h"

int wnd_width=1300;
int wnd_height=900;
GLdouble aspect = wnd_width/wnd_height;
Camera cam;
unsigned int texture;
float text_coords[] = {0,0, 1,0, 1,1, 0,1};

void DrawFloor();
void DrawWall(float x, float width, float height);
void KeyPressed(int key, int x, int y);
void TextureInit();
void display();
void Idle();

void TextureInit(){
    int width, height, cnt;
    unsigned char* data = stbi_load("whitemarble.jpg", &width, &height, &cnt, 0);
    if(data==nullptr) std::cout<< "NO\n";
    else std::cout<<width<<'\t'<<height<<'\n';
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    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_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
                 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
    glBindTexture(GL_TEXTURE_2D, 0);
    stbi_image_free(data);
}

void display(){
    glClearColor(0.6, 0.8, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90, aspect, 0.1, 3);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
              cam.view.x, cam.view.y, cam.view.z,
              0, 0.5, 0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glBegin(GL_QUADS);
    DrawFloor();
    DrawWall(-0.5, 2, 0.7);
    DrawWall(0.5, 2, 0.7);
    glEnd();
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glutSwapBuffers();
}

void DrawFloor(){
    glTexCoord2d(0, 0);
    glVertex3d(1, 0, 2.5);
    glTexCoord2d(1, 0);
    glVertex3d(1, 0, 0);
    glTexCoord2d(1, 1);
    glVertex3d(-1, 0, 0);
    glTexCoord2d(0, 1);
    glVertex3d(-1, 0, 2.5);
}

void DrawWall(float x, float width, float height){
    glVertex3f(x, height, 0);
    glVertex3f(x, height, width);
    glVertex3f(x, 0, width);
    glVertex3f(x, 0, 0);
}

void KeyPressed(int key, int x, int y){
    switch (key) {
    case GLUT_KEY_UP: { cam.MoveForward(); break; }
    case GLUT_KEY_DOWN: { cam.MoveBack(); break; }
    case GLUT_KEY_LEFT: {cam.TurnLeft(); break; }
    case GLUT_KEY_RIGHT: {cam.TurnRight(); break; }
    }
    cam.PrintPosition();
    glutPostRedisplay();
}



void Idle(){

}```

【问题讨论】:

  • 你最初是怎么想出这段代码的?
  • 来自 YouTube 视频)
  • 下载 Renderdoc,运行你的 gl 程序并捕获一个帧,然后查看一个帧是如何构造的以及使用了哪些资源。 Bam,就这样,你现在也是一个 opengl 调试器了。

标签: c++ opengl glut


【解决方案1】:

您的代码导致在glBeginglEnd 之间只能使用几个GL 命令的子集。您必须在指定顶点之前立即调用glBegin

void display(){
    glClearColor(0.6, 0.8, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(90, aspect, 0.1, 3);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(cam.pos.x, cam.pos.y, cam.pos.z,
              cam.view.x, cam.view.y, cam.view.z,
              0, 0.5, 0);

    
    // glBegin(GL_QUADS);                             // <--- DELETE
    
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, texture);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, 0, text_coords);
    
    glBegin(GL_QUADS);                                // <--- INSERT
    //glColor3f(0, 0, 0.7);
    DrawFloor();
    //glColor3f(0, 0.8, 0.1);
    DrawWall(-0.5, 2, 0.7);
    DrawWall(0.5, 2, 0.7);
    glEnd();
    
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glutSwapBuffers();
}

您不能混合使用修复函数属性和glBegin/glEnd 序列。请改用glTexCoord

glTexCoord2d(0, 0);
glVertex3d(1, 0, 2.5);
glTexCoord2d(1, 0);
glVertex3d(1, 0, 0);
glTexCoord2d(1, 1);
glVertex3d(-1, 0, 0);
glTexCoord2d(0, 1);
glVertex3d(-1, 0, 2.5);

【讨论】:

  • 现在地板和墙壁都是灰色的。我是否正确设置了坐标 text_coords?图片大小为 800 * 533 像素。
  • @Denis 纹理坐标似乎是正确的。
  • @Denis 纹理坐标数组可能是正确的,但从不使用该数组,因为使用 glBegin/glEnd 绘制时,glTexCoordPointer 完全不相关。
  • 现在可以了。谢谢。但是画面很拉长。
  • @Denis 这是一个新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多