OpenGL纹理未渲染(C)

时间:2019-12-27 14:18:31

标签: c opengl shader textures

我想在一个矩形(两个三角形)之间绘制一个简单的图片,但是当我启动程序时,只有一个黑色的矩形而不是图片。 为了渲染图片,我使用的是着色器,我可以通过制服使用它。 我找不到错误,为什么它没有渲染。 你能帮我吗?

main.c

#define APIENTRY __stdcall
#include<glad/glad.h>
#include <GL/glut.h>
#include <stdio.h>
#include<math.h>

#include "VertexBuffer.h"
#include"shader2.h"
#include "index_buffer.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"


struct VertexBuffer buffer1;
struct IndexBuffer indexBuffer1;
uint32_t numVerticies = 4;
uint32_t numIndices = 6;
int colorUniformLocation;
GLuint indexBuffer;
GLuint textureId;
float time = 0.0f;
float a = 0.0f;
float b = 0.0f;
float c = 0.0f;


void display(void)
{
    glClearColor(0,1.0,1.0,1);
    glClear(GL_COLOR_BUFFER_BIT); //Löscht Bild aus Speicher

    bindVertexBuffer(&buffer1);
    bindIndexBuffer(&indexBuffer1);
    glUniform4f(colorUniformLocation, a, b, c, 1.0f);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureId);

    glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_INT, 0);

    unbindVertexBuffer();
    unbindIndexBuffer(&indexBuffer1);

    glFlush(); //Gibt dem Bildschirm das Bild
}

void keyboard(unsigned char key, int x, int y)
{
    if(key == 27) //Wenn Escape schließen
    {
        exit(0);
    }
}

void reshape(int width, int height)
{

}

void update(int t)
{

    time+=0.02f;
    a = sinf(time) * sinf(time);
    b = cosf(time) * cosf(time);
    c = tanf(time) * tanf(time);

    glutPostRedisplay();
    glutTimerFunc(1000.0/60.0, update, 0);
}

int main (int argc, char **argv)
{

    glutInit(&argc, argv);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(183,100);
    glutCreateWindow("TestApp");
    glutDisplayFunc(display); //display func initialisieren
    glutKeyboardFunc(keyboard); //keyboard func initialisieren
    glutReshapeFunc(reshape); //reshape func initialisieren
    glutTimerFunc(1000.0/60.0, update, 0);

    gladLoadGL();

    //Initialize the triangle-------------------------
    struct Vertex verticies[6];
    verticies[0].x = -0.5;
    verticies[0].y = -0.5;
    verticies[0].z = 0;
    verticies[0].u = 0;
    verticies[0].v = 0;
    verticies[0].r = 1;
    verticies[0].g = 0;
    verticies[0].b = 0;
    verticies[0].a = 1;

    verticies[1].x = -0.5;
    verticies[1].y = 0.5;
    verticies[1].z = 0;
    verticies[0].u = 0;
    verticies[0].v = 1;
    verticies[1].r = 0;
    verticies[1].g = 1;
    verticies[1].b = 0;
    verticies[1].a = 1;

    verticies[2].x = 0.5;
    verticies[2].y = -0.5;
    verticies[2].z = 0;
    verticies[0].u = 1;
    verticies[0].v = 0;
    verticies[2].r = 0;
    verticies[2].g = 0;
    verticies[2].b = 1;
    verticies[2].a = 1;

    verticies[3].x = 0.5;
    verticies[3].y = 0.5;
    verticies[3].z = 0;
    verticies[0].u = 1;
    verticies[0].v = 1;
    verticies[3].r = 1;
    verticies[3].g = 0;
    verticies[3].b = 0;
    verticies[3].a = 1;

    uint32_t indices[] = {
        0, 1, 2,
        1, 2, 3
    };
    //-------------------------------------------------


    initIndexBuffer(&indexBuffer1, indices, numIndices, sizeof(indices[0]));
    initVertexBuffer(&buffer1, verticies, numVerticies); //Buffer initialisieren

    char vs[] ="#version 330 \nlayout(location = 0) in vec3 a_position;\nlayout(location = 1) in vec2 a_texCoord;\nlayout(location = 2) in vec4 a_color;\nout vec4 v_color;\nout vec2 v_texCoord;\nvoid main()\n{\ngl_Position = vec4(a_position, 1.0f);\nv_color = a_color;\nv_texCoord = a_texCoord;\n}";
    char fs[] =  "#version 330\nlayout(location = 0) out vec4 f_color;\nin vec4 v_color;\nin vec2 v_texCoord;\nuniform sampler2D u_texture;\nuniform vec4 u_color;\nvoid main()\n{\nvec4 texColor = texture(u_texture, v_texCoord);\nf_color = texColor;\n}";

    int32_t textureWidth = 0;
    int32_t textureHeight = 0;
    int32_t bitsPerPixel = 0;
    stbi_set_flip_vertically_on_load(1);
    auto textureBuffer = stbi_load("C:\\Users\\Maciel\\Desktop\\Backup_Maciel\\c_coding\\Testing_glut\\res\\logo.png", &textureWidth, &textureHeight, &bitsPerPixel, 4);

    //TEXTURE------------------------------------

    glGenTextures(1, &textureId);
    glBindTexture(GL_TEXTURE_2D, textureId);

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, textureWidth, textureHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureBuffer);
    glBindTexture(GL_TEXTURE_2D, 0);
    if(textureBuffer)
    {
        stbi_image_free(textureBuffer);
    }

    //Shader laden------------------------------
    struct Shader shader1;
    initShader(&shader1, vs, fs);
    bindShader(&shader1);

    colorUniformLocation = glGetUniformLocation(shader1.shaderId, "u_color");
    if(!colorUniformLocation != -1)
    {
        glUniform4f(colorUniformLocation, 1.0f, 0.0f, 1.0f, 1.0f);
    }

    int textureUnifromLocation = glGetUniformLocation(shader1.shaderId, "u_texture");
    if(!textureUnifromLocation != -1)
    {
        glUniform1i(textureUnifromLocation, 0);
    }

    //LOOP starts
    glutMainLoop();

    cleanUpVertexBuffer(&buffer1);
    cleanUpIndexBuffer(&indexBuffer1);
    glDeleteTextures(1, &textureId);

    return 0;
}

VertexBuffer.h

#include<glad/glad.h>

struct Vertex
{
    float x;
    float y;
    float z;

    float u;
    float v;

    float r;
    float g;
    float b;
    float a;
};

struct VertexBuffer
{

    //Parameter
    void* data;
    uint32_t numVerticies;

    GLuint bufferID;
    GLuint vao;
};

void initVertexBuffer(struct VertexBuffer *buffer, void *d, uint32_t nV)
{
    (*buffer).data = d;
    (*buffer).numVerticies = nV;

    glGenVertexArrays(1, &(buffer->vao)); //Vao wird erzeugt, id = vao
    glBindVertexArray((*buffer).vao); //Vao wird gebindet

    glGenBuffers(1, &(buffer->bufferID)); //Buffer/Speicher wird erzeugt -> Anzahl an VBO´s
    glBindBuffer(GL_ARRAY_BUFFER, (*buffer).bufferID); //Buffer wird gebindet -> ist ein Array
    glBufferData(GL_ARRAY_BUFFER, (*buffer).numVerticies * sizeof(struct Vertex), (*buffer).data, GL_STATIC_DRAW); //Daten werden in Buffer geschrieben

    glEnableVertexAttribArray(0); //Aktiviert index 0 vom vao
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), 0); //Sagt wie OpemGL die Daten interpretieren soll

    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), 12);

    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(struct Vertex), 20);
    glBindVertexArray(0); //vao wird geunbindet
}

void bindVertexBuffer(struct VertexBuffer *buffer)
{
    glBindVertexArray((*buffer).vao);
}

void unbindVertexBuffer()
{
    glBindVertexArray(0);
}

void cleanUpVertexBuffer(struct VertexBuffer *buffer)
{
    glDeleteBuffers(1, (*buffer).bufferID);
}

shader2.h

#include<glad/glad.h>
#include<stdio.h>

struct Shader
{
    //Parameter
    const char *vertexShader;
    const char *fragmentShader;

    GLuint shaderId;
};

GLuint createShader();
GLuint compileShader();

void initShader(struct Shader *shader, const char *vS, const char *fS)
{
    (*shader).vertexShader = vS;
    (*shader).fragmentShader = fS;

    (*shader).shaderId = createShader((*shader).vertexShader, (*shader).fragmentShader);
}

void bindShader(struct Shader *shader)
{
    glUseProgram((*shader).shaderId);
}

void unBindShader()
{
    glUseProgram(0);
}

GLuint createShader(const char *vertexShader, const char *fragmentShader)
{
    GLuint program = glCreateProgram();
    GLuint vs = compileShader(vertexShader, GL_VERTEX_SHADER);
    GLuint fs = compileShader(fragmentShader, GL_FRAGMENT_SHADER);

    glAttachShader(program, vs);
    glAttachShader(program, fs);
    glLinkProgram(program);
    glValidateProgram(program);

   //glDetachShader(program, vs);
   // glDetachShader(program, fs);

    return program;
}

GLuint compileShader(char *shaderSource, GLenum type)
{
    GLuint id = glCreateShader(type);
    glShaderSource(id, 1, &shaderSource, 0);
    glCompileShader(id);

    GLint result;
    glGetShaderiv(id,GL_COMPILE_STATUS, &result);

    if(result == GL_FALSE)
    {
        int length;
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);

        GLchar *strInfoLog[length ];
        glGetShaderInfoLog(id, length, &length, strInfoLog);
        fprintf(stderr, strInfoLog);
    }

    return id;
}

vertexshader

#version 330 
layout(location = 0) in vec3 a_position;
layout(location = 1) in vec2 a_texCoord;
layout(location = 2) in vec4 a_color;
out vec4 v_color;
out vec2 v_texCoord;
void main()
{
gl_Position = vec4(a_position, 1.0f);
v_color = a_color;
v_texCoord = a_texCoord;
}

fragmentshader

#version 330
layout(location = 0) out vec4 f_color;
in vec4 v_color;
in vec2 v_texCoord;
uniform sampler2D u_texture;
uniform vec4 u_color;
void main()
{
vec4 texColor = texture(u_texture, v_texCoord);
f_color = texColor;
}

1 个答案:

答案 0 :(得分:2)

您仅设置顶点0的纹理坐标:

verticies[0].u = 1;
verticies[0].v = 1;

您还应该将它们设置为折点[1],折点[2]和折点[3]

相关问题