سؤال

أواجه مشكلة في الحصول على نسيج للخريطة على الهندسة بشكل صحيح مع OpenGL. في الواقع، يبدو أنني قد كسر الاستيفاء اللون الذي كان يعمل بشكل جيد. لقد قمت بإنشاء حالة اختبار في C99 التي تستخدم SDL و GLEE والتربة.

#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <SDL/SDL.h>
#include <GL/GLee.h>
#include <SOIL/SOIL.h>

static const char *vertex_source = " \
uniform mat4 projection; \
uniform mat4 view_model; \
 \
attribute vec2 vertex; \
attribute vec2 texcoord; \
attribute vec4 colour; \
 \
varying vec2 _texcoord; \
 \
void main() \
{ \
    gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex, 0, 1); \
    _texcoord = texcoord; \
    gl_FrontColor = colour; \
} ";

static const char *fragment_source = " \
uniform sampler2D sampler0; \
 \
varying vec2 _texcoord; \
 \
void main() \
{ \
    gl_FragColor = texture2D(sampler0, _texcoord) * 0.01 + gl_Color; \
} ";

typedef struct
{
    GLfloat position[2];
    GLfloat texcoord[2];
    GLubyte colour[4];
} Vertex;

static Vertex verts[] = {
        {
            .position = { 1, 1 },
            .texcoord = { 1, 1 },
            .colour = { 255, 0, 0, 255 },
        },
        {
            .position = { -1, 1 },
            .texcoord = { 0, 1 },
            .colour = { 0, 255, 0, 255 },
        },
        {
            .position = { -1, -1 },
            .texcoord = { 0, 0 },
            .colour = { 0, 0, 255, 255 },
        },
        {
            .position = { 1, -1 },
            .texcoord = { 1, 0 },
            .colour = { 255, 255, 0, 255 },
        },
    };

static GLuint vertex, fragment, program, vbo, texture;
static GLint sampler_loc, vertex_loc, texcoord_loc, colour_loc;

static void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_SetVideoMode(800, 800, 0, SDL_OPENGL);

    glClearColor(1, 0, 0, 0);

    glMatrixMode(GL_PROJECTION);
    glOrtho(-1, 1, -1, 1, -1, 1);

    /* Shaders */
    vertex = glCreateShader(GL_VERTEX_SHADER);
    assert(vertex != 0);
    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    assert(fragment != 0);

    GLint length = strlen(vertex_source);
    glShaderSource(vertex, 1, &vertex_source, &length);
    length = strlen(fragment_source);
    glShaderSource(fragment, 1, &fragment_source, &length);

    glCompileShader(vertex);
    glCompileShader(fragment);

    program = glCreateProgram();

    glAttachShader(program, vertex);
    glAttachShader(program, fragment);

    glLinkProgram(program);

    sampler_loc = glGetUniformLocation(program, "sampler0");
    vertex_loc = glGetAttribLocation(program, "vertex");
    texcoord_loc = glGetAttribLocation(program, "texcoord");
    colour_loc = glGetAttribLocation(program, "colour");

    /* VBO */
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), &verts[0], GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    /* Texture */
    texture = SOIL_load_OGL_texture("test.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
    assert(texture != 0);
}

static void draw()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(program);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);
    glUniform1i(sampler_loc, 0);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glScalef(.5, .5, .5);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    glEnableVertexAttribArray(0);

    glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, position));
    glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, texcoord));
    glVertexAttribPointer(colour_loc, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), offsetof(Vertex, colour));

    glDrawArrays(GL_QUADS, 0, 4);

    glDisableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindTexture(GL_TEXTURE_2D, 0);
    glPopMatrix();

    glUseProgram(0);
}

static void shutdown()
{
    SDL_Quit();
}

int main()
{
    init();
    atexit(shutdown);

    while(true)
    {
        static SDL_Event event;
        while(SDL_PollEvent(&event)) 
        {
            switch(event.type) 
            {
                case SDL_QUIT:
                    exit(0);
                    break;

                default:
                    break;
            }
        }

        draw();

        SDL_GL_SwapBuffers();

        if(glGetError() != GL_NO_ERROR)
        {
            printf("Error\n");
            exit(1);
        }
    }

    return 0;
}

الشيء الوحيد الذي يجعله الرصيف هو مربع أزرق عادي أعلى GlClearColor.

أي مساعدة موضع تقدير كبير.

شكرا على الإجابات، لقد أرفقت رمز ثابت للكمال.

#include <stdbool.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <SDL/SDL.h>
#include <GL/GLee.h>
#include <SOIL/SOIL.h>

static const char *vertex_source = " \
uniform mat4 projection; \
uniform mat4 view_model; \
 \
attribute vec2 vertex; \
attribute vec2 texcoord; \
attribute vec4 colour; \
 \
varying vec2 _texcoord; \
 \
void main() \
{ \
    gl_Position = gl_ModelViewProjectionMatrix * vec4(vertex, 0, 1); \
    _texcoord = texcoord; \
    gl_FrontColor = colour; \
} ";

static const char *fragment_source = " \
uniform sampler2D sampler0; \
 \
varying vec2 _texcoord; \
 \
void main() \
{ \
    gl_FragColor = texture2D(sampler0, _texcoord) + gl_Color; \
} ";

typedef struct
{
    GLfloat position[2];
    GLfloat texcoord[2];
    GLubyte colour[4];
} Vertex;

static Vertex verts[] = {
        {
            .position = { 1, 1 },
            .texcoord = { 1, 1 },
            .colour = { 255, 0, 0, 255 },
        },
        {
            .position = { -1, 1 },
            .texcoord = { 0, 1 },
            .colour = { 0, 255, 0, 255 },
        },
        {
            .position = { -1, -1 },
            .texcoord = { 0, 0 },
            .colour = { 0, 0, 255, 255 },
        },
        {
            .position = { 1, -1 },
            .texcoord = { 1, 0 },
            .colour = { 255, 255, 0, 255 },
        },
    };

static GLuint vertex, fragment, program, vbo, texture;
static GLint sampler_loc, vertex_loc, texcoord_loc, colour_loc;

static void init()
{
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_SetVideoMode(800, 800, 0, SDL_OPENGL);

    glClearColor(1, 0, 0, 0);

    glMatrixMode(GL_PROJECTION);
    glOrtho(-1, 1, -1, 1, -1, 1);

    /* Shaders */
    vertex = glCreateShader(GL_VERTEX_SHADER);
    assert(vertex != 0);
    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    assert(fragment != 0);

    GLint length = strlen(vertex_source);
    glShaderSource(vertex, 1, &vertex_source, &length);
    length = strlen(fragment_source);
    glShaderSource(fragment, 1, &fragment_source, &length);

    glCompileShader(vertex);
    glCompileShader(fragment);

    program = glCreateProgram();

    glAttachShader(program, vertex);
    glAttachShader(program, fragment);

    glLinkProgram(program);

    sampler_loc = glGetUniformLocation(program, "sampler0");
    vertex_loc = glGetAttribLocation(program, "vertex");
    texcoord_loc = glGetAttribLocation(program, "texcoord");
    colour_loc = glGetAttribLocation(program, "colour");

    glUseProgram(program);
    glUniform1i(sampler_loc, 0);
    glUseProgram(0);

    /* VBO */
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);

    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), &verts[0], GL_STATIC_DRAW);
    glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, position));
    glVertexAttribPointer(texcoord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), offsetof(Vertex, texcoord));
    glVertexAttribPointer(colour_loc, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), offsetof(Vertex, colour));

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    /* Texture */
    texture = SOIL_load_OGL_texture("test.png", SOIL_LOAD_AUTO, SOIL_CREATE_NEW_ID, SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y);
    assert(texture != 0);
}

static void draw()
{
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(program);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glScalef(.5, .5, .5);

    glEnableVertexAttribArray(vertex_loc);
    glEnableVertexAttribArray(texcoord_loc);
    glEnableVertexAttribArray(colour_loc);

    glDrawArrays(GL_QUADS, 0, 4);

    glDisableVertexAttribArray(vertex_loc);
    glDisableVertexAttribArray(texcoord_loc);
    glDisableVertexAttribArray(colour_loc);

    glBindTexture(GL_TEXTURE_2D, 0);
    glPopMatrix();

    glUseProgram(0);
}

static void shutdown()
{
    SDL_Quit();
}

int main()
{
    init();
    atexit(shutdown);

    while(true)
    {
        static SDL_Event event;
        while(SDL_PollEvent(&event)) 
        {
            switch(event.type) 
            {
                case SDL_QUIT:
                    exit(0);
                    break;

                default:
                    break;
            }
        }

        draw();

        SDL_GL_SwapBuffers();

        if(glGetError() != GL_NO_ERROR)
        {
            printf("Error\n");
            exit(1);
        }
    }

    return 0;
}
هل كانت مفيدة؟

المحلول

لا يمكنك تمكين صفيفات Vertex Attrib بشكل صحيح.

  • يمكنك تمكين 0، والتي قد لا تكون شيئا تستخدمها (حسنا، في الممارسة العملية، ربما vertex_loc, ، ولكن يجب أن لا تعتمد عليه)
  • أنت تتجاهل المصفوفات الأخرى 2

حاول القيام بما يلي:

glEnableVertexAttribArray(vertex_loc);
glEnableVertexAttribArray(texcoord_loc);
glEnableVertexAttribArray(colour_loc);

تحرير لإضافة: قد أشر إلى تفاصيل أخرى:

  • قمت بتعيين موقع Sampler مرة واحدة فقط. إعداده يميل إلى فرض عمل إضافي في برنامج التشغيل، وبما أنك ستحددها فقط إلى نفس وحدة الملمس في كل مرة، فقد تفعل ذلك أيضا في بدء التشغيل.

  • المكان الذي تتصل به glBindBuffer(GL_ARRAY_BUFFER, 0) ليست خاطئة، لكنني أضعها بعد مكالمات VertExAttribPooter. المخزن المؤقت المرتبط حاليا هو حقا حجة إضافية لتلك المكالمات ... ولا تؤثر على Cldrawrawars Call نفسها.

نصائح أخرى

يتضمن تظليلك الفرعي

texture2D(sampler0, _texcoord) * 0.01

والتي من شأنها أن تجعل نسيجك غير مرئي بشكل أساسي في معظم الشاشات، أليس كذلك؟

AFAIK تحتاج إلى استخدام GlClientActiveTucture () قبل ربط نسيج VBO.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top