📄 shaderobjects.c
字号:
/* * Mesa 3-D graphics library * Version: 6.5 * * Copyright (C) 2004-2006 Brian Paul All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//** * \file shaderobjects.c * ARB_shader_objects state management functions * \author Michal Krol */#include "glheader.h"#include "context.h"#include "hash.h"#include "shaderobjects.h"#include "shaderobjects_3dlabs.h"#define I_UNKNOWN struct gl2_unknown_intf **#define I_GENERIC struct gl2_generic_intf **#define I_CONTAINER struct gl2_container_intf **#define I_PROGRAM struct gl2_program_intf **#define I_SHADER struct gl2_shader_intf **#define RELEASE_GENERIC(x)\ (**x)._unknown.Release ((I_UNKNOWN) x)#define RELEASE_CONTAINER(x)\ (**x)._generic._unknown.Release ((I_UNKNOWN) x)#define RELEASE_PROGRAM(x)\ (**x)._container._generic._unknown.Release ((I_UNKNOWN) x)#define RELEASE_SHADER(x)\ (**x)._generic._unknown.Release ((I_UNKNOWN) x);#define _LOOKUP_HANDLE(handle, function)\ I_UNKNOWN unk;\ _glthread_LOCK_MUTEX (ctx->Shared->Mutex);\ unk = (I_UNKNOWN) _mesa_HashLookup (ctx->Shared->GL2Objects, handle);\ _glthread_UNLOCK_MUTEX (ctx->Shared->Mutex);\ if (unk == NULL) {\ _mesa_error (ctx, GL_INVALID_VALUE, function);\ break;\ }#define _QUERY_INTERFACE(x, type, uuid, function)\ x = (type) (**unk).QueryInterface (unk, uuid);\ if (x == NULL) {\ _mesa_error (ctx, GL_INVALID_OPERATION, function);\ break;\ }#define GET_GENERIC(x, handle, function)\ I_GENERIC x = NULL;\ do {\ _LOOKUP_HANDLE(handle, function);\ _QUERY_INTERFACE(x, I_GENERIC, UIID_GENERIC, function);\ } while (0)#define GET_CONTAINER(x, handle, function)\ I_CONTAINER x = NULL;\ do {\ _LOOKUP_HANDLE(handle, function);\ _QUERY_INTERFACE(x, I_CONTAINER, UIID_CONTAINER, function);\ } while (0)#define GET_PROGRAM(x, handle, function)\ I_PROGRAM x = NULL;\ do {\ _LOOKUP_HANDLE(handle, function);\ _QUERY_INTERFACE(x, I_PROGRAM, UIID_PROGRAM, function);\ } while (0)#define GET_SHADER(x, handle, function)\ I_SHADER x = NULL;\ do {\ _LOOKUP_HANDLE(handle, function);\ _QUERY_INTERFACE(x, I_SHADER, UIID_SHADER, function);\ } while (0)#define _LINKED_PROGRAM(x, function)\ if ((**x).GetLinkStatus (x) == GL_FALSE) {\ RELEASE_PROGRAM(x);\ _mesa_error (ctx, GL_INVALID_OPERATION, function);\ break;\ }#define GET_LINKED_PROGRAM(x, handle, function)\ I_PROGRAM x = NULL;\ do {\ _LOOKUP_HANDLE(handle, function);\ _QUERY_INTERFACE(x, I_PROGRAM, UIID_PROGRAM, function);\ _LINKED_PROGRAM(x, function);\ } while (0)#define _CURRENT_PROGRAM(x, function)\ if (ctx->ShaderObjects.CurrentProgram == NULL) {\ _mesa_error (ctx, GL_INVALID_OPERATION, function);\ break;\ }\ x = ctx->ShaderObjects.CurrentProgram;#define GET_CURRENT_LINKED_PROGRAM(x, function)\ I_PROGRAM x = NULL;\ do {\ _CURRENT_PROGRAM(x, function);\ _LINKED_PROGRAM(x, function);\ } while (0)GLvoid GLAPIENTRY_mesa_DeleteObjectARB (GLhandleARB obj){ GET_CURRENT_CONTEXT(ctx); GET_GENERIC(gen, obj, "glDeleteObjectARB"); if (gen != NULL) { (**gen).Delete (gen); RELEASE_GENERIC(gen); }}GLhandleARB GLAPIENTRY_mesa_GetHandleARB (GLenum pname){ GET_CURRENT_CONTEXT(ctx); switch (pname) { case GL_PROGRAM_OBJECT_ARB: { I_PROGRAM pro = ctx->ShaderObjects.CurrentProgram; if (pro != NULL) return (**pro)._container._generic.GetName ((I_GENERIC) pro); } break; default: _mesa_error (ctx, GL_INVALID_ENUM, "glGetHandleARB"); } return 0;}GLvoid GLAPIENTRY_mesa_DetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj){ GET_CURRENT_CONTEXT(ctx); GET_CONTAINER(con, containerObj, "glDetachObjectARB"); if (con != NULL) { GET_GENERIC(att, attachedObj, "glDetachObjectARB"); if (att != NULL) { (**con).Detach (con, att); RELEASE_GENERIC(att); } RELEASE_CONTAINER(con); }}GLhandleARB GLAPIENTRY_mesa_CreateShaderObjectARB (GLenum shaderType){ return _mesa_3dlabs_create_shader_object (shaderType);}GLvoid GLAPIENTRY_mesa_ShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB **string, const GLint *length){ GET_CURRENT_CONTEXT(ctx); GLint *offsets; GLsizei i; GLcharARB *source; GET_SHADER(sha, shaderObj, "glShaderSourceARB"); if (sha == NULL) return;
if (string == NULL)
{
RELEASE_SHADER(sha);
_mesa_error (ctx, GL_INVALID_VALUE, "glShaderSourceARB");
return;
} /* * This array holds offsets of where the appropriate string ends, thus the last * element will be set to the total length of the source code. */ offsets = (GLint *) _mesa_malloc (count * sizeof (GLint)); if (offsets == NULL) { RELEASE_SHADER(sha); _mesa_error (ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); return; } for (i = 0; i < count; i++) {
if (string[i] == NULL)
{
_mesa_free ((GLvoid *) offsets);
RELEASE_SHADER(sha);
_mesa_error (ctx, GL_INVALID_VALUE, "glShaderSourceARB");
return;
} if (length == NULL || length[i] < 0) offsets[i] = _mesa_strlen (string[i]); else offsets[i] = length[i]; /* accumulate string lengths */ if (i > 0) offsets[i] += offsets[i - 1]; } source = (GLcharARB *) _mesa_malloc ((offsets[count - 1] + 1) * sizeof (GLcharARB)); if (source == NULL) { _mesa_free ((GLvoid *) offsets); RELEASE_SHADER(sha); _mesa_error (ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); return; } for (i = 0; i < count; i++) { GLint start = (i > 0) ? offsets[i - 1] : 0; _mesa_memcpy (source + start, string[i], (offsets[i] - start) * sizeof (GLcharARB)); } source[offsets[count - 1]] = '\0'; (**sha).SetSource (sha, source, offsets, count); RELEASE_SHADER(sha);}GLvoid GLAPIENTRY_mesa_CompileShaderARB (GLhandleARB shaderObj){ GET_CURRENT_CONTEXT(ctx); GET_SHADER(sha, shaderObj, "glCompileShaderARB"); if (sha != NULL) { (**sha).Compile (sha); RELEASE_SHADER(sha); }}GLhandleARB GLAPIENTRY_mesa_CreateProgramObjectARB (GLvoid){ return _mesa_3dlabs_create_program_object ();}GLvoid GLAPIENTRY_mesa_AttachObjectARB (GLhandleARB containerObj, GLhandleARB obj){ GET_CURRENT_CONTEXT(ctx); GET_CONTAINER(con, containerObj, "glAttachObjectARB"); if (con != NULL) { GET_GENERIC(att, obj, "glAttachObjectARB"); if (att != NULL) { (**con).Attach (con, att); RELEASE_GENERIC(att); } RELEASE_CONTAINER(con); }}GLvoid GLAPIENTRY_mesa_LinkProgramARB (GLhandleARB programObj){ GET_CURRENT_CONTEXT(ctx); GET_PROGRAM(pro, programObj, "glLinkProgramARB"); if (pro != NULL) { (**pro).Link (pro);
if (pro == ctx->ShaderObjects.CurrentProgram)
{
if ((**pro).GetLinkStatus (pro))
_mesa_UseProgramObjectARB (programObj);
else
_mesa_UseProgramObjectARB (0);
} RELEASE_PROGRAM(pro); }}GLvoid GLAPIENTRY_mesa_UseProgramObjectARB (GLhandleARB programObj){ GET_CURRENT_CONTEXT(ctx); I_PROGRAM program = NULL; FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (programObj != 0) {
GET_PROGRAM(pro, programObj, "glUseProgramObjectARB"); if (pro == NULL) return; if ((**pro).GetLinkStatus (pro) == GL_FALSE) { RELEASE_PROGRAM(pro); _mesa_error (ctx, GL_INVALID_OPERATION, "glUseProgramObjectARB"); return; } program = pro;
ctx->ShaderObjects._VertexShaderPresent = (**pro).IsShaderPresent (pro, GL_VERTEX_SHADER_ARB);
ctx->ShaderObjects._FragmentShaderPresent = (**pro).IsShaderPresent (pro,
GL_FRAGMENT_SHADER_ARB); }
else
{
ctx->ShaderObjects._VertexShaderPresent = GL_FALSE;
ctx->ShaderObjects._FragmentShaderPresent = GL_FALSE;
} if (ctx->ShaderObjects.CurrentProgram != NULL) RELEASE_PROGRAM(ctx->ShaderObjects.CurrentProgram); ctx->ShaderObjects.CurrentProgram = program;}GLvoid GLAPIENTRY_mesa_ValidateProgramARB (GLhandleARB programObj){ GET_CURRENT_CONTEXT(ctx); GET_PROGRAM(pro, programObj, "glValidateProgramARB"); if (pro != NULL) { (**pro).Validate (pro); RELEASE_PROGRAM(pro); }}GLvoid GLAPIENTRY_mesa_Uniform1fARB (GLint location, GLfloat v0){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { if (!_slang_write_uniform (pro, location, 1, &v0, GL_FLOAT)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fARB"); }}GLvoid GLAPIENTRY_mesa_Uniform2fARB (GLint location, GLfloat v0, GLfloat v1){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { GLfloat v[2] = { v0, v1 }; if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC2)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fARB"); }}GLvoid GLAPIENTRY_mesa_Uniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { GLfloat v[3] = { v0, v1, v2 }; if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC3)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fARB"); }}GLvoid GLAPIENTRY_mesa_Uniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4fARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { GLfloat v[4] = { v0, v1, v2, v3 }; if (!_slang_write_uniform (pro, location, 1, v, GL_FLOAT_VEC4)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4fARB"); }}GLvoid GLAPIENTRY_mesa_Uniform1iARB (GLint location, GLint v0){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1iARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { if (!_slang_write_uniform (pro, location, 1, &v0, GL_INT)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1iARB"); }}GLvoid GLAPIENTRY_mesa_Uniform2iARB (GLint location, GLint v0, GLint v1){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2iARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { GLint v[2] = { v0, v1 }; if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC2)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2iARB"); }}GLvoid GLAPIENTRY_mesa_Uniform3iARB (GLint location, GLint v0, GLint v1, GLint v2){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3iARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { GLint v[3] = { v0, v1, v2 }; if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC3)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3iARB"); }}GLvoid GLAPIENTRY_mesa_Uniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform4iARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { GLint v[4] = { v0, v1, v2, v3 }; if (!_slang_write_uniform (pro, location, 1, v, GL_INT_VEC4)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform4iARB"); }}GLvoid GLAPIENTRY_mesa_Uniform1fvARB (GLint location, GLsizei count, const GLfloat *value){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform1fvARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform1fvARB"); }}GLvoid GLAPIENTRY_mesa_Uniform2fvARB (GLint location, GLsizei count, const GLfloat *value){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform2fvARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC2)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform2fvARB"); }}GLvoid GLAPIENTRY_mesa_Uniform3fvARB (GLint location, GLsizei count, const GLfloat *value){ GET_CURRENT_CONTEXT(ctx); GET_CURRENT_LINKED_PROGRAM(pro, "glUniform3fvARB");
FLUSH_VERTICES(ctx, _NEW_PROGRAM); if (pro != NULL) { if (!_slang_write_uniform (pro, location, count, value, GL_FLOAT_VEC3)) _mesa_error (ctx, GL_INVALID_OPERATION, "glUniform3fvARB"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -