在OpenGL立方体上显示多个纹理,c++GLFW

Displaying multiple textures on an OpenGL cube, c++ GLFW

本文关键字:纹理 c++GLFW 显示 OpenGL 立方体      更新时间:2023-10-16

所以,我使用GLFW进行窗口管理,并且我有GLEW用于扩展管理。我正试着写一个跨平台的游戏,是我哥哥想出的。这是一场纸牌游戏。但是,为了获得3D表面上纹理映射和渲染的基础知识,我正在尝试在立方体的侧面显示一些卡片纹理。我的第一个问题是glfw的TGA加载程序,尽管我使用了glGenTextures的GLuint指针数组,但只有第一个要加载的纹理是可显示的(尽管它会在我尝试纹理的每个表面上正确显示)。然后,我发现http://home.comcast.net/~mlyn7576/OpenGL TGA/,它似乎也能工作,但现在只显示最后加载的纹理,它在所有面上显示一个纹理,尽管我只引用了它的GL名称一次。那么我做错了什么?我不明白为什么只显示一个加载的纹理。

这是我的主要标题:

#ifndef _RPSEVOLVED_H_
#define _RPSEVOLVED_H_
#endif
#include <iostream>
#include <math.h>
#include <glglew.h>
#include <glglfw.h>
#include <stdint.h>
using namespace std;
class RPSEvolved
{
private:
    bool Running;
public:
    static RPSEvolved* instance;
    RPSEvolved();
    int OnExecute();
    GLuint cardBackId;
    GLuint bgId;
    GLuint airCardId;
    GLuint earthCardId;
    GLuint fireCardId;
    GLuint lightningCardId;
    GLuint waterCardId;
public:
    bool OnInit();
    void OnEvent(/*SDL_Event* ev*/);
    void OnLoop();
    void OnRender();
    void OnCleanup();
    //callbacks
    static void GLFWCALL OnKeyCB(int key, int action);
    static void OnWindowCloseCB();
    static RPSEvolved* GetInstance();
    void GLFWCALL OnCharCB(int key, int action);
    void GLFWCALL OnMouseWheelCB(int pos);
    void GLFWCALL OnMouseMoveCB(int x, int y);
    void GLFWCALL OnMouseButtonCB(int button, int action);
};

这是我的初始化代码:

#include "RPSEvolved.h"
#include "RPSE_TGA.h"
bool RPSEvolved::OnInit()
{
    if(glfwInit() == GL_FALSE)
    {
        cout << "Error initializing GLFW";
        return false;
    }
    if(glfwOpenWindow(1024, 768, 8, 8, 8, 8, 32, 32, GLFW_WINDOW) == GL_FALSE)
    {
        cout << "Error initializing GLFW";
        return false;
    }
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_TEXTURE_2D);
    glEnable(GL_NORMALIZE); //Automatically normalize normals
    glShadeModel(GL_SMOOTH);
    glMatrixMode(GL_PROJECTION);
    gluPerspective(45, 1024/768, 1, 100);
    glMatrixMode(GL_MODELVIEW);
    glfwDisable(GLFW_AUTO_POLL_EVENTS);
    glClearColor(0, 0, 0, 255);
    glfwSetWindowCloseCallback((GLFWwindowclosefun)OnWindowCloseCB);
    glfwSetKeyCallback(OnKeyCB);
    cardBackId = load_texture_TGA("images\cardBack.tga", NULL, NULL, GL_CLAMP, GL_CLAMP);
    bgId = load_texture_TGA("images\bg.tga", NULL, NULL, GL_CLAMP, GL_CLAMP);
    airCardId = load_texture_TGA("images\airCard.tga", NULL, NULL, GL_CLAMP, GL_CLAMP);
    earthCardId = load_texture_TGA("images\earthCard.tga", NULL, NULL, GL_CLAMP, GL_CLAMP);
    fireCardId = load_texture_TGA("images\fireCard.tga", NULL, NULL, GL_CLAMP, GL_CLAMP);
    lightningCardId = load_texture_TGA("images\lightningCard.tga", NULL, NULL, GL_CLAMP, GL_CLAMP);
    waterCardId = load_texture_TGA("images\waterCard.tga", NULL, NULL, GL_CLAMP, GL_CLAMP);
    return true;
}

我的显示代码:

#include "RPSEvolved.h"
void RPSEvolved::OnRender()
{
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    gluLookAt(0.0f, 5.0f, 30.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
    static float _angle = 0.0f; _angle -= 0.3f;
    glEnable(GL_TEXTURE_2D);
    glRotatef(_angle, 0.0f, 1.0f, 0.0f);
    glColor4f(1.0f, 1.0f, 1.0f, 0.0f);
    glBegin(GL_QUADS);
    glBindTexture(GL_TEXTURE_2D, cardBackId);
    glNormal3f(0.0f, 0.0f, 1.0f); // front
    glTexCoord2f(0.0f, 0.0f);   glVertex3f(-3.0f, -5.0f, 3.0f);
    glTexCoord2f(1.0f, 0.0f);   glVertex3f(3.0f, -5.0f, 3.0f);
    glTexCoord2f(1.0f, 1.0f);   glVertex3f(3.0f, 5.0f, 3.0f);
    glTexCoord2f(0.0f, 1.0f);   glVertex3f(-3.0f, 5.0f, 3.0f);
    glBindTexture(GL_TEXTURE_2D, airCardId);
    glNormal3f(1.0f, 0.0f, 0.0f); // right
    glTexCoord2f(0.0f, 0.0f);   glVertex3f(3.0f, -4.0f, 3.0f);
    glTexCoord2f(1.0f, 0.0f);   glVertex3f(3.0f, -4.0f, -3.0f);
    glTexCoord2f(1.0f, 1.0f);   glVertex3f(3.0f, 4.0f, -3.0f);
    glTexCoord2f(0.0f, 1.0f);   glVertex3f(3.0f, 4.0f, 3.0f);
    glBindTexture(GL_TEXTURE_2D, earthCardId);
    glNormal3f(0.0f, 0.0f, -1.0f); // back
    glTexCoord2f(0.0f, 0.0f);   glVertex3f(3.0f, 4.0f, -3.0f);
    glTexCoord2f(1.0f, 0.0f);   glVertex3f(-3.0f, 4.0f, -3.0f);
    glTexCoord2f(1.0f, 1.0f);   glVertex3f(-3.0f, -4.0f, -3.0f);
    glTexCoord2f(0.0f, 1.0f);   glVertex3f(3.0f, -4.0f, -3.0f);
    glBindTexture(GL_TEXTURE_2D, fireCardId);
    glNormal3f(-1.0f, 0.0f, 0.0f); // left
    glTexCoord2f(0.0f, 0.0f);   glVertex3f(-3.0f, 4.0f, -3.0f);
    glTexCoord2f(1.0f, 0.0f);   glVertex3f(-3.0f, 4.0f, 3.0f);
    glTexCoord2f(1.0f, 1.0f);   glVertex3f(-3.0f, -4.0f, 3.0f);
    glTexCoord2f(0.0f, 1.0f);   glVertex3f(-3.0f, -4.0f, -3.0f);
    glBindTexture(GL_TEXTURE_2D, lightningCardId);
    glNormal3f(0.0f, 1.0f, 0.0f); // top
    glTexCoord2f(0.0f, 0.0f);   glVertex3f(3.0f, 4.0f, 3.0f);
    glTexCoord2f(1.0f, 0.0f);   glVertex3f(-3.0f, 4.0f, 3.0f);
    glTexCoord2f(1.0f, 1.0f);   glVertex3f(-3.0f, 4.0f, -3.0f);
    glTexCoord2f(0.0f, 1.0f);   glVertex3f(3.0f, 4.0f, -3.0f);
    glBindTexture(GL_TEXTURE_2D, waterCardId);
    glNormal3f(0.0f, -1.0f, 0.0f); // top
    glTexCoord2f(0.0f, 0.0f);   glVertex3f(-3.0f, -4.0f, 3.0f);
    glTexCoord2f(1.0f, 0.0f);   glVertex3f(3.0f, -4.0f, 3.0f);
    glTexCoord2f(1.0f, 1.0f);   glVertex3f(3.0f, -4.0f, -3.0f);
    glTexCoord2f(0.0f, 1.0f);   glVertex3f(-3.0f, -4.0f, -3.0f);
    glEnd();
    glfwSwapBuffers();
}

请注意,如果我将OnInit()中对load_texture_TGA的调用替换为对glfwLoadTexture2D()的调用,那么就会出现只显示第一个纹理的问题。是怎么回事,纹理并没有像预期的那样全部显示出来?

附言:很抱歉,如果这真的很长,我有一个习惯,在寻求编码帮助时,我会提供所有我认为相关的信息。

我认为您需要在单独的批次中完成每个人脸:

glBindTexture(GL_TEXTURE_2D, cardBackId);
glBegin(GL_QUADS);
// front vertices..
glEnd();
glBindTexture(GL_TEXTURE_2D, airCardId);
glBegin(GL_QUADS);
// Right vertices..
glEnd();
// Other faces...

有几个替代方案可以让你在一个批次中渲染立方体:

  • 生成一个包含立方体所有面的纹理。然后为立方体的顶点提供适当的纹理坐标。你可以使用二维纹理或三维纹理
  • 绑定不同纹理单元寄存器中的所有纹理,并编写像素着色器