首页 > 解决方案 > 为什么在 OpenGL 中使用纹理会破坏我的其他对象?

问题描述

我正在使用 C++、OpenGL 和 Freeglut 在 Windows 中编写一个程序,以学习如何使用它。我编写的代码工作如下:

#define GLEW_STATIC
#include <iostream>
#include <GL/glew.h>;
#include <freeglut.h>
#include <Windows.h>
#include <stdio.h>
#include <string>
#include <vector>
#include "fstream"
#include <algorithm>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>;
#include <chrono>

GLint partColorUniformLocation;
GLint bufferColorUniformLocation;
GLint vpMatrixUniformLocation;
GLint shows;

float radi = 5.0f;
float angx = 0.30;
float angy = 4.60;
float camX = -cos(angx) * sin(angy) * radi;
float camY = -cos(angx) * cos(angy) * radi;
float camZ = sin(angx) * radi;
float zoom = 5.0f;
float ww0;
float ww1;
float wh0;
float wh1;
float menubar;
float menur = 400;

using namespace std;
using glm::vec3;
using glm::vec4;
using glm::mat3;
using glm::mat4;

mat4 PV;
vector <mat3> Model;
mat3 World = mat3(1.0f);
vec3 UP(0.0f, 0.0f, 1.0f);
HWND hWnd;
HINSTANCE hInst;

float ww;
float wh;
int ln0 = 1280;
int shaderProgram;

unsigned int VBO;
GLuint boxID;
unsigned int VCOx;
unsigned int VCOy;
unsigned int VCOz;
GLuint coordxID;
GLuint coordyID;
GLuint coordzID;
unsigned int VTO;
GLuint ptexID;
GLuint texID;
unsigned int VTO2;
GLuint rptexID;
GLuint rtexID;
vector <char> b;
vector <unsigned char> bu;
GLuint texture0;
GLint mW;

void GetDesktopResolution(int& ww, int& wh);
void getDesktop();
void box();
void coord();
void reshape(int ww, int wh);
void display(void);
void texturemenu();
void bmpsread();
void maketexture0(int tw, int th);
void mouseButton(int button, int state, int x, int y);
void mouseMove(int x, int y);
void installShader();

const char* vertexShaderSource =
"#version 330 core\n"
"layout (location = 0) in vec3 position;\n"
"layout (location = 1) in vec3 inNormal;\n"
"layout (location = 2) in vec3 inColor;\n"
"layout (location = 3) in vec2 tex;\n"
"uniform mat4 VP;\n"
"out vec3 outColor;\n"
"out vec3 Normal;\n"
"out vec2 outTex;\n"
"void main()\n"
"{\n"
"   vec4 v = vec4(position, 1.0);\n"
"   gl_Position = VP * v;\n"
"   outColor = inColor;\n"
"   Normal = inNormal;\n"
"   outTex = tex;\n"
"}\0";

const char* fragmentShaderSource =
"#version 330 core\n"
"out vec4 color;\n"
"in vec3 outColor;\n"
"in vec3 Normal;\n"
"in vec2 outTex;\n"
"uniform int shows;\n"
"uniform sampler2D texture0;\n"
"uniform vec3 partColor;"
"uniform vec3 bufferColor;"
"void main()\n"
"{\n"
"   if (shows == 0) \n"
"   {\n"
"       color = vec4(bufferColor/255.0, 1.0);\n"
"   }\n"
"   else if (shows == 1)\n"
"   {\n"
"       color = vec4(1.0, 1.0, 1.0, 1.0);\n"
"   }\n"
"   else if (shows == 2)\n"
"   {\n"
"       color = vec4(partColor, 1.0);\n"
"   }\n"
"   else if (shows == 3)\n"
"   {\n"
"       color = texture(texture0, outTex);\n"
"   }\n"
"}\n\0";

void GetDesktopResolution(float& ww, float& wh) {
    RECT desktop;
    const HWND hDesktop = GetDesktopWindow();
    GetWindowRect(hDesktop, &desktop);
    ww = desktop.right;
    wh = desktop.bottom;
}

void getDesktop() {
    wh = glutGet(GLUT_WINDOW_HEIGHT);
    ww = glutGet(GLUT_WINDOW_WIDTH);
    menubar = 35;
    ww0 = -(ww - menur) / 10.0f;
    ww1 = (ww - menur) / 10.0f;
    wh0 = -(wh - menubar) / 10.0f + 30;
    wh1 = (wh - menubar) / 10.0f + 30;
    zoom = 0.2f;
}

void box() {
    vector <float> box;
    box.resize(72);
    box = {
        -10.0f, -10.0f, 20.0f,
        10.0f, -10.0f, 20.0f,
        10.0f, -10.0f, 20.0f,
        10.0f, 10.0f, 20.0f,
        10.0f, 10.0f, 20.0f,
        -10.0f, 10.0f, 20.0f,
        -10.0f, 10.0f, 20.0f,
        -10.0f, -10.0f, 20.0f,

        -10.0f, -10.0f, 0.0f,
        10.0f, -10.0f, 0.0f,
        10.0f, -10.0f, 0.0f,
        10.0f, 10.0f, 0.0f,
        10.0f, 10.0f, 0.0f,
        -10.0f, 10.0f, 0.0f,
        -10.0f, 10.0f, 0.0f,
        -10.0f, -10.0f, 0.0f,

        -10.0f, -10.0f, 20.0f,
        -10.0f, -10.0f, 0.0f,
        10.0f, -10.0f, 20.0f,
        10.0f, -10.0f, 0.0f,
        10.0f, 10.0f, 20.0f,
        10.0f, 10.0f, 0.0f,
        -10.0f, 10.0f, 20.0f,
        -10.0f, 10.0f, 0.0f
    };

    glGenBuffers(1, &boxID);
    glBindBuffer(GL_ARRAY_BUFFER, boxID);
    glBufferData(GL_ARRAY_BUFFER, box.size() * sizeof(float), box.data(), GL_STATIC_DRAW);
    box.clear();

    glGenVertexArrays(1, &VBO);
    glBindVertexArray(VBO);
    glBindBuffer(GL_ARRAY_BUFFER, boxID);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glBindVertexArray(0);
}

void coord() {
    vector <float> coordx(6);
    coordx = {
        0.0f, 0.0f, 0.0f,
        10.0f, 0.0f, 0.0f
    };

    vector <float> coordy(6);
    coordy = {
        0.0f, 0.0f, 0.0f,
        0.0f, 10.0f, 0.0f
    };

    vector <float> coordz(6);
    coordz = {
        0.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 10.0f
    };

    glGenBuffers(1, &coordxID);
    glBindBuffer(GL_ARRAY_BUFFER, coordxID);
    glBufferData(GL_ARRAY_BUFFER, coordx.size() * sizeof(float), coordx.data(), GL_STATIC_DRAW);
    coordx.clear();

    glGenBuffers(1, &coordyID);
    glBindBuffer(GL_ARRAY_BUFFER, coordyID);
    glBufferData(GL_ARRAY_BUFFER, coordy.size() * sizeof(float), coordy.data(), GL_STATIC_DRAW);
    coordy.clear();

    glGenBuffers(1, &coordzID);
    glBindBuffer(GL_ARRAY_BUFFER, coordzID);
    glBufferData(GL_ARRAY_BUFFER, coordz.size() * sizeof(float), coordz.data(), GL_STATIC_DRAW);
    coordz.clear();

    glGenVertexArrays(1, &VCOx);
    glBindVertexArray(VCOx);
    glBindBuffer(GL_ARRAY_BUFFER, coordxID);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glGenVertexArrays(1, &VCOy);
    glBindVertexArray(VCOy);
    glBindBuffer(GL_ARRAY_BUFFER, coordyID);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glGenVertexArrays(1, &VCOz);
    glBindVertexArray(VCOz);
    glBindBuffer(GL_ARRAY_BUFFER, coordzID);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glBindVertexArray(0);
}

void reshape(int ww, int wh) {
    getDesktop();
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glUseProgram(shaderProgram);
    partColorUniformLocation = glGetUniformLocation(shaderProgram, "partColor");
    bufferColorUniformLocation = glGetUniformLocation(shaderProgram, "bufferColor");
    vpMatrixUniformLocation = glGetUniformLocation(shaderProgram, "VP");
    shows = glGetUniformLocation(shaderProgram, "shows");
}

void display(void) {
    glClearColor(0.7f, 0.7f, 0.7f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glViewport(0, 0, ww - menur, wh - menubar);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_FRONT);
    glFrontFace(GL_CW);
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);
    mat4 Projection = glm::ortho(ww0, ww1, wh0, wh1, -1000.0f, 1000.0f); //left, right, bottom, top, zNear, zFar
    mat4 View = glm::lookAt(glm::vec3(camX, camY, camZ), glm::vec3(0.0f, 0.0f, 0.0f), UP);
    mat4 VP = Projection * View;
    vec3 partColor;
    glUniformMatrix4fv(vpMatrixUniformLocation, 1, GL_FALSE, &VP[0][0]);

    glUniform1i(shows, 2);
    glLineWidth(2);
    glBindVertexArray(VCOx); // Coordx
    partColor = vec3(1.0f, 0.0f, 0.0f);
    glUniform3fv(partColorUniformLocation, 1, &partColor[0]);
    glDrawArrays(GL_LINES, 0, 2);
    glBindVertexArray(VCOy); // Coordy
    partColor = vec3(0.0f, 1.0f, 0.0f);
    glUniform3fv(partColorUniformLocation, 1, &partColor[0]);
    glDrawArrays(GL_LINES, 0, 2);
    glBindVertexArray(VCOz); // Coordz
    partColor = vec3(0.0f, 0.0f, 1.0f);
    glUniform3fv(partColorUniformLocation, 1, &partColor[0]);
    glDrawArrays(GL_LINES, 0, 2);

    glBindVertexArray(VBO); // Box
    partColor = vec3(1.0f, 1.0f, 1.0f);
    glUniform3fv(partColorUniformLocation, 1, &partColor[0]);
    glDrawArrays(GL_LINES, 0, 24);

    glUniform1i(shows, 1);
    glDisable(GL_DEPTH_TEST);
    glViewport(0, wh - 35, ww, wh);
    VP = glm::ortho(0.0f, ww, 0.0f, 35.0f) * glm::mat4(1.0f); //left, right, bottom, top
    glUniformMatrix4fv(vpMatrixUniformLocation, 1, GL_FALSE, &VP[0][0]);
    glBindVertexArray(VTO2);
    glDrawArrays(GL_TRIANGLES, 0, 6);

    glEnable(GL_TEXTURE0);
    glUniform1i(shows, 3);
    glViewport(0, wh - menubar, ln0, 35);
    VP = glm::ortho(0.0f, float(ln0), 0.0f, 35.0f) * glm::mat4(1.0f); //left, right, bottom, top
    glUniformMatrix4fv(vpMatrixUniformLocation, 1, GL_FALSE, &VP[0][0]);
    glBindVertexArray(VTO);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    glDisable(GL_TEXTURE0);

    glutSwapBuffers();
}

void texturemenu() {
    vector <float> ptex(18);
    float top = 35;
    float bottom = 0;
    float left = 0;
    float right = 1280;
    ptex = {
        right, top, 0.0f,
        left, top, 0.0f,
        left, bottom, 0.0f,

        left, bottom, 0.0f,
        right, bottom, 0.0f,
        right, top, 0.0f
    };

    vector <float> tex(12);
    tex = {
        1.0f, 1.0f,
        0.0f, 1.0f,
        0.0f, 0.0f,

        0.0f, 0.0f,
        1.0f, 0.0f,
        1.0f, 1.0f
    };

    glGenBuffers(1, &ptexID);
    glBindBuffer(GL_ARRAY_BUFFER, ptexID);
    glBufferData(GL_ARRAY_BUFFER, ptex.size() * sizeof(float), ptex.data(), GL_STATIC_DRAW);
    ptex.clear();

    glGenTextures(1, &texID);
    glBindBuffer(GL_ARRAY_BUFFER, texID);
    glBufferData(GL_ARRAY_BUFFER, tex.size() * sizeof(float), tex.data(), GL_STATIC_DRAW);
    tex.clear();

    glGenVertexArrays(1, &VTO);
    glBindVertexArray(VTO);
    glBindBuffer(GL_ARRAY_BUFFER, ptexID);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
    glBindBuffer(GL_ARRAY_BUFFER, texID);
    glEnableVertexAttribArray(3);
    glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glBindVertexArray(0);
}

void bmpsread() {
    bu.clear();
    bu.resize(3 * 35 * ln0, 255);
    int bmpn = 0;
    string sbmp;
    sbmp = "C:/C++/icons/dll/new.bmp";
    if (sbmp.size() > 0) {
        ifstream fo;
        unsigned int fn = 0;
        fo.open(sbmp, std::ios::binary | std::ios::in);
        if (fo.is_open()) {
            std::ifstream in_file(sbmp, std::ios::binary | std::ios::ate);
            fo.seekg(0, std::ios::beg);
            int file_size = in_file.tellg();
            fn = file_size;
            b.resize(fn);
            fo.seekg(0, std::ios::beg);
            fo.read(b.data(), fn);
        }
        fo.close();
        fo.clear();
        int dataPos = *(int*)&(b[0x0A]);
        int www = *(int*)&(b[0x12]);
        int ka = 0;
        int kx = ceil((((float)www * 3) + 1) / 4) * 4 - www * 3;
        if (kx == 4) { kx = 0; }
        for (int i = 0; i < 35; i++) {
            for (int j = 0; j < www; j++) {
                bu[i * ln0 * 3 + (bmpn + j) * 3] = (unsigned char)b[i * www * 3 + j * 3 + ka + dataPos];
                bu[i * ln0 * 3 + (bmpn + j) * 3 + 1] = (unsigned char)b[i * www * 3 + j * 3 + ka + 1 + dataPos];
                bu[i * ln0 * 3 + (bmpn + j) * 3 + 2] = (unsigned char)b[i * www * 3 + j * 3 + ka + 2 + dataPos];
            }
            ka += kx;
        }
        b.clear();
    }
    bmpn += 37;
}

void maketexture0(int tw, int th) {
    glGenTextures(1, &texture0);
    auto textureUniformLocation = glGetUniformLocation(shaderProgram, "texture0");
    glUniform1i(texture0, 0);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture0);
    glEnable(GL_TEXTURE0);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tw, th, 0, GL_BGR, GL_UNSIGNED_BYTE, bu.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    bu.clear();
}

void installShader() {
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    glCompileShader(vertexShader);
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    glDetachShader(shaderProgram, vertexShader);
    glDetachShader(shaderProgram, fragmentShader);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitWindowSize(800, 600);
    mW = glutCreateWindow(" Texture Test");
    glewInit();
    HWND win_handle = FindWindow(0, L" Texture Test");
    WNDCLASS wc = { 0 };

    if (!win_handle) {
        return -1;
    }
    SetWindowLong(win_handle, GWL_STYLE, (GetWindowLong(win_handle, GWL_STYLE) | WS_MAXIMIZE));
    ShowWindowAsync(win_handle, SW_SHOWDEFAULT);
    ShowWindowAsync(win_handle, SW_SHOWMAXIMIZED);

    box();
    coord();

    installShader();
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);

    glutMainLoop();
    return 0;
}

没有纹理:

图像

但是在我添加纹理以创建菜单栏(在此示例中为“new.bmp”图片)并在“coord();”之后添加以下代码之后 在“int main(int argc, char** argv)”中:

bmpsread();
texturemenu();
maketexture0(ln0, 35);

然后我的盒子消失了,我的坐标是错误的。

带纹理:

图像

我究竟做错了什么?

标签: c++winapiopenglglutglm-math

解决方案


推荐阅读